Page MenuHomeFreeBSD

pf: Fix interface binding for af-to with route-to
ClosedPublic

Authored by vegeta_tuxpowered.net on Sep 9 2025, 1:19 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Oct 12, 9:49 AM
Unknown Object (File)
Sun, Oct 12, 9:49 AM
Unknown Object (File)
Sun, Oct 12, 9:49 AM
Unknown Object (File)
Sun, Oct 12, 9:49 AM
Unknown Object (File)
Sat, Oct 11, 10:57 PM
Unknown Object (File)
Thu, Oct 9, 8:31 PM
Unknown Object (File)
Fri, Oct 3, 7:17 PM
Unknown Object (File)
Fri, Oct 3, 1:28 PM

Details

Summary

States created by inbound af-to rules bypass outbound filtering and span
both the inbound and outbound interfaces. When the first packet for such
rule creates a state, this state has st->orig_kif set the original inbound
interface and kif set to V_pfi_all. When the outbound interface is
eventually known st->kif is updated to that interface. When not using
route-to, the outbound route and its interface are determined for the new
address family and st->kif is set to that interface. However when using
route-to, ifp is explicitely given and the code for updating st->kif is not
run for the first packet. When the returning packet matches the state, the
code is run but updates st->kif to the original inbound interface, which is
now the outbound interface. The state ends up with st->kif == st->orig_kif
and won't forward any more returning packets.

There is another block of code performing such update, but only for
reply-to.

Perform the update of st->kif in a single place no matter if ifp was
explicitely given or found by routing lookup. For checks using pings check
if really all pings have been replied to, because a single reply is enough
to have ping exit with a successful exit code.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

sys/netpfil/pf/pf.c
9514

I'm not sure this assertion is correct. I believe we can route-to on plain IPv6 traffic.

sys/netpfil/pf/pf.c
9514

Those MPASSes are to verify that we have arrived here from:

static struct pfi_kkif *
BOUND_IFACE(struct pf_kstate *st, struct pf_pdesc *pd)
{
…
	/*
	 * Initially set to all, because we don't know what interface we'll be
	 * sending this out when we create the state.
	 */
	if (st->rule->rt == PF_REPLYTO || (pd->af != pd->naf && st->direction == PF_IN))
		return (V_pfi_all);
…
}

So an inbound af-to. I am unsure about reply-to, though. Let me double-check that.

vegeta_tuxpowered.net added inline comments.
sys/netpfil/pf/pf.c
9514

I've updated the MPASS to reflect what the conditions in BOUND_IFACE().

This revision is now accepted and ready to land.Thu, Sep 18, 7:32 AM