git: c6210cfd58f6 - main - pf: fix if-bound with nat64
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 17 Dec 2024 10:08:02 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=c6210cfd58f6a570786106f35ebbe1c49f48287c commit c6210cfd58f6a570786106f35ebbe1c49f48287c Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2024-11-15 15:29:54 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2024-12-17 10:07:16 +0000 pf: fix if-bound with nat64 Just as with reply-to rules we don't know what interface we will send this out of until we create the state. Create new nat64 rules as floating, but bind them to the appropriate interface on the first pf_route(), when we do know. Set state policy if-bound for the nat64 tests to validate this. See also: 6460322a0 Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D47801 --- sys/netpfil/pf/pf.c | 28 +++++++++++++++++++++++++--- tests/sys/netpfil/pf/nat64.sh | 1 + 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 445aef881fe8..08486d5d1467 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -438,8 +438,10 @@ enum { PF_ICMP_MULTI_NONE, PF_ICMP_MULTI_LINK }; } while (0) static struct pfi_kkif * -BOUND_IFACE(struct pf_kstate *st, struct pfi_kkif *k) +BOUND_IFACE(struct pf_kstate *st, struct pf_pdesc *pd) { + struct pfi_kkif *k = pd->kif; + SDT_PROBE2(pf, ip, , bound_iface, st, k); /* Floating unless otherwise specified. */ @@ -450,7 +452,7 @@ BOUND_IFACE(struct pf_kstate *st, struct pfi_kkif *k) * 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) + if (st->rule->rt == PF_REPLYTO || (pd->af != pd->naf)) return (V_pfi_all); /* Don't overrule the interface for states created on incoming packets. */ @@ -6125,7 +6127,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a, __func__, nr, sk, nk)); /* Swap sk/nk for PF_OUT. */ - if (pf_state_insert(BOUND_IFACE(s, pd->kif), pd->kif, + if (pf_state_insert(BOUND_IFACE(s, pd), pd->kif, (pd->dir == PF_IN) ? sk : nk, (pd->dir == PF_IN) ? nk : sk, s)) { REASON_SET(&reason, PFRES_STATEINS); @@ -8800,6 +8802,16 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, dst.sin_addr = nh->gw4_sa.sin_addr; else dst.sin_addr = ip->ip_dst; + + /* + * Bind to the correct interface if we're + * if-bound. We don't know which interface + * that will be until here, so we've inserted + * the state on V_pf_all. Fix that now. + */ + if (s->kif == V_pfi_all && ifp != NULL && + r->rule_flag & PFRULE_IFBOUND) + s->kif = ifp->if_pf_kif; } } @@ -9050,6 +9062,16 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp, sizeof(dst.sin6_addr)); else dst.sin6_addr = ip6->ip6_dst; + + /* + * Bind to the correct interface if we're + * if-bound. We don't know which interface + * that will be until here, so we've inserted + * the state on V_pf_all. Fix that now. + */ + if (s->kif == V_pfi_all && ifp != NULL && + r->rule_flag & PFRULE_IFBOUND) + s->kif = ifp->if_pf_kif; } } diff --git a/tests/sys/netpfil/pf/nat64.sh b/tests/sys/netpfil/pf/nat64.sh index 3e04dc6e7bc0..0ae2c0399daf 100644 --- a/tests/sys/netpfil/pf/nat64.sh +++ b/tests/sys/netpfil/pf/nat64.sh @@ -52,6 +52,7 @@ nat64_setup() jexec rtr pfctl -e pft_set_rules rtr \ + "set state-policy if-bound" \ "pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" }