git: abda72f3a1f6 - main - pf: INET/INET6 address family check should be unified in PF
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 09 Apr 2025 09:51:41 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=abda72f3a1f60121dbe1341f3aadfb714cdee1fb
commit abda72f3a1f60121dbe1341f3aadfb714cdee1fb
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-04-08 15:36:58 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-04-09 08:18:20 +0000
pf: INET/INET6 address family check should be unified in PF
It also adds af_unhandled(), where it is currently missing.
ok mcbride@
Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 9b00340fee
Obtained from: OpenBSD, sashan <sashan@openbsd.org>, 3f22add75d
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/netpfil/pf/pf.c | 76 +++++++++++++++++++++++------------------------
sys/netpfil/pf/pf_lb.c | 10 +++++--
sys/netpfil/pf/pf_norm.c | 16 ++++++----
sys/netpfil/pf/pf_table.c | 54 ++++++++++++++++++++++++++-------
4 files changed, 99 insertions(+), 57 deletions(-)
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index c343512b20dd..5f5f2403e448 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -614,7 +614,7 @@ pf_is_loopback(sa_family_t af, struct pf_addr *addr)
#ifdef INET
case AF_INET:
return IN_LOOPBACK(ntohl(addr->v4.s_addr));
-#endif
+#endif /* INET */
case AF_INET6:
return IN6_IS_ADDR_LOOPBACK(&addr->v6);
default:
@@ -776,7 +776,7 @@ pf_state_hash(struct pf_kstate *s)
hv = 1;
return (hv);
}
-#endif
+#endif /* ALTQ */
static __inline void
pf_set_protostate(struct pf_kstate *s, int which, u_int8_t newstate)
@@ -915,13 +915,13 @@ pf_overload_task(void *v, int pending)
p.pfra_net = 32;
p.pfra_ip4addr = pfoe->addr.v4;
break;
-#endif
+#endif /* INET */
#ifdef INET6
case AF_INET6:
p.pfra_net = 128;
p.pfra_ip6addr = pfoe->addr.v6;
break;
-#endif
+#endif /* INET6 */
default:
unhandled_af(pfoe->af);
}
@@ -1631,7 +1631,7 @@ pf_state_key_detach(struct pf_kstate *s, int idx)
struct pf_keyhash *kh = &V_pf_keyhash[pf_hashkey(sk)];
PF_HASHROW_ASSERT(kh);
-#endif
+#endif /* INVARIANTS */
TAILQ_REMOVE(&sk->states[idx], s, key_list[idx]);
s->key[idx] = NULL;
@@ -1701,7 +1701,7 @@ pf_state_key_addr_setup(struct pf_pdesc *pd,
}
}
copy:
-#endif
+#endif /* INET6 */
if (saddr)
PF_ACPY(&key->addr[pd->sidx], saddr, pd->af);
if (daddr)
@@ -2169,7 +2169,7 @@ pf_isforlocal(struct mbuf *m, int af)
return (in_localip(ip->ip_dst));
}
-#endif
+#endif /* INET */
#ifdef INET6
case AF_INET6: {
struct ip6_hdr *ip6;
@@ -2180,7 +2180,7 @@ pf_isforlocal(struct mbuf *m, int af)
return (false);
return (! (ia->ia6_flags & IN6_IFF_NOTREADY));
}
-#endif
+#endif /* INET6 */
default:
unhandled_af(af);
}
@@ -4367,13 +4367,13 @@ pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
if (icmp6_ratelimit(NULL, type, code))
return;
break;
-#endif
+#endif /* INET6 */
#ifdef INET
case AF_INET:
if (badport_bandlim(pf_icmp_to_bandlim(type)) != 0)
return;
break;
-#endif
+#endif /* INET */
}
/* Allocate outgoing queue entry, mbuf and mbuf tag. */
@@ -5183,10 +5183,10 @@ pf_test_eth_rule(int dir, struct pfi_kkif *kif, struct mbuf **m0)
{
#ifdef INET
struct ip ip;
-#endif
+#endif /* INET */
#ifdef INET6
struct ip6_hdr ip6;
-#endif
+#endif /* INET6 */
struct mbuf *m = *m0;
struct ether_header *e;
struct pf_keth_rule *r, *rm, *a = NULL;
@@ -5734,7 +5734,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm,
PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af);
}
break;
-#endif /* INET */
+#endif /* INET6 */
}
break;
}
@@ -6169,7 +6169,7 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a,
case IPPROTO_ICMP:
#ifdef INET6
case IPPROTO_ICMPV6:
-#endif
+#endif /* INET6 */
s->timeout = PFTM_ICMP_FIRST_PACKET;
break;
default:
@@ -7522,7 +7522,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
TAILQ_INSERT_TAIL(&pd->sctp_multihome_jobs, job, next);
break;
}
-#endif
+#endif /* INET6 */
case SCTP_ADD_IP_ADDRESS: {
int ret;
struct sctp_asconf_paramhdr ah;
@@ -7640,7 +7640,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
struct pf_state_key_cmp key;
#ifdef INET
u_int16_t icmpid;
-#endif
+#endif /* INET*/
MPASS(*state == NULL);
@@ -7660,7 +7660,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
icmpcode = pd->hdr.icmp6.icmp6_code;
#ifdef INET
icmpid = pd->hdr.icmp6.icmp6_id;
-#endif
+#endif /* INET */
icmpsum = &pd->hdr.icmp6.icmp6_cksum;
break;
#endif /* INET6 */
@@ -7722,7 +7722,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
return (PF_DROP);
pd->proto = IPPROTO_ICMPV6;
}
-#endif
+#endif /* INET6 */
if (!afto &&
PF_ANEQ(pd->src, &nk->addr[sidx], AF_INET))
pf_change_a(&saddr->v4.s_addr,
@@ -7759,7 +7759,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
return (PF_DROP);
pd->proto = IPPROTO_ICMP;
}
-#endif
+#endif /* INET */
if (!afto &&
PF_ANEQ(pd->src, &nk->addr[sidx], AF_INET6))
pf_change_a6(saddr,
@@ -8042,7 +8042,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
pd->naf = nk->af;
return (PF_AFRT);
}
-#endif
+#endif /* INET && INET6 */
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
@@ -8176,7 +8176,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
pd->naf = nk->af;
return (PF_AFRT);
}
-#endif
+#endif /* INET && INET6 */
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
@@ -8321,7 +8321,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
pd->naf = nk->af;
return (PF_AFRT);
}
-#endif
+#endif /* INET && INET6 */
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
@@ -8457,7 +8457,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
pd->naf = nk->af;
return (PF_AFRT);
}
-#endif
+#endif /* INET && INET6 */
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
@@ -8576,7 +8576,7 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
pd->naf = nk->af;
return (PF_AFRT);
}
-#endif
+#endif /* INET && INET6 */
if (PF_ANEQ(pd2.src,
&nk->addr[pd2.sidx], pd2.af) ||
@@ -8744,12 +8744,12 @@ pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kkif *kif,
case AF_INET6:
return (fib6_check_urpf(rtableid, &addr->v6, 0, NHR_NONE,
ifp));
-#endif
+#endif /* INET6 */
#ifdef INET
case AF_INET:
return (fib4_check_urpf(rtableid, addr->v4, 0, NHR_NONE,
ifp));
-#endif
+#endif /* INET */
}
return (0);
@@ -9592,7 +9592,7 @@ pf_dummynet_route(struct pf_pdesc *pd, struct pf_kstate *s,
(
#ifdef INET
(pd->af == AF_INET && IN_LOOPBACK(ntohl(pd->dst->v4.s_addr))) ||
-#endif
+#endif /* INET */
(pd->af == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&pd->dst->v6)))) {
/*
* If we're redirecting to loopback mark this packet
@@ -9799,7 +9799,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
}
}
}
-#endif
+#endif /* INET6 */
static void
pf_init_pdesc(struct pf_pdesc *pd, struct mbuf *m)
@@ -9879,7 +9879,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
break;
}
-#endif
+#endif /* INET */
#ifdef INET6
case AF_INET6: {
struct ip6_hdr *h;
@@ -9965,7 +9965,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
break;
}
-#endif
+#endif /* INET6 */
default:
panic("pf_setup_pdesc called with illegal af %u", af);
}
@@ -10081,7 +10081,7 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
pd->pcksum = &pd->hdr.icmp.icmp_cksum;
break;
}
-#endif
+#endif /* INET6 */
}
if (pd->sport)
@@ -10306,7 +10306,7 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
*m0 = NULL;
return (PF_DROP);
}
-#endif
+#endif /* INET */
#ifdef INET6
/*
* If we end up changing IP addresses (e.g. binat) the stack may get
@@ -10320,7 +10320,7 @@ pf_test(sa_family_t af, int dir, int pflags, struct ifnet *ifp, struct mbuf **m0
*m0 = NULL;
return (PF_DROP);
}
-#endif
+#endif /* INET6 */
if (__predict_false(ip_divert_ptr != NULL) &&
((mtag = m_tag_locate(pd.m, MTAG_PF_DIVERT, 0, NULL)) != NULL)) {
@@ -10642,11 +10642,11 @@ done:
#ifdef INET
if (pd.naf == AF_INET)
pf_route(m0, r, kif->pfik_ifp, s, &pd, inp);
-#endif
+#endif /* INET */
#ifdef INET6
if (pd.naf == AF_INET6)
pf_route6(m0, r, kif->pfik_ifp, s, &pd, inp);
-#endif
+#endif /* INET6 */
*m0 = NULL;
action = PF_PASS;
goto out;
@@ -10659,13 +10659,13 @@ done:
/* pf_route() returns unlocked. */
pf_route(m0, r, kif->pfik_ifp, s, &pd, inp);
break;
-#endif
+#endif /* INET */
#ifdef INET6
case AF_INET6:
/* pf_route6() returns unlocked. */
pf_route6(m0, r, kif->pfik_ifp, s, &pd, inp);
break;
-#endif
+#endif /* INET6 */
}
goto out;
}
@@ -10696,7 +10696,7 @@ out:
(! (pflags & PF_PFIL_NOREFRAGMENT)) &&
(mtag = m_tag_find(pd.m, PACKET_TAG_PF_REASSEMBLED, NULL)) != NULL)
action = pf_refragment6(ifp, m0, mtag, NULL, pflags & PFIL_FWD);
-#endif
+#endif /* INET6 */
pf_sctp_multihome_delayed(&pd, kif, s, action);
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index f0cad4bb43c2..54a9463e34ef 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -57,11 +57,11 @@
#ifdef INET
#include <netinet/in_var.h>
-#endif
+#endif /* INET */
#ifdef INET6
#include <netinet6/in6_var.h>
-#endif
+#endif /* INET6 */
/*
@@ -94,7 +94,7 @@ pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
uint64_t hash64;
uint32_t hash32[2];
} h;
-#endif
+#endif /* INET6 */
uint64_t res = 0;
_Static_assert(sizeof(*key) >= SIPHASH_KEY_LENGTH, "");
@@ -122,6 +122,8 @@ pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
hash->addr32[3] = ~h.hash32[0];
break;
#endif /* INET6 */
+ default:
+ unhandled_af(af);
}
return (res);
}
@@ -497,6 +499,8 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
break;
#endif /* INET6 */
+ default:
+ unhandled_af(af);
}
} else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
if (!PF_POOL_DYNTYPE(rpool->opts)) {
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index fd72fec62a3b..be8ba939e5d9 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -434,7 +434,7 @@ pf_frent_remove(struct pf_fragment *frag, struct pf_frent *frent)
{
#ifdef INVARIANTS
struct pf_frent *prev = TAILQ_PREV(frent, pf_fragq, fr_next);
-#endif
+#endif /* INVARIANTS */
struct pf_frent *next = TAILQ_NEXT(frent, fr_next);
int index;
@@ -1457,6 +1457,8 @@ pf_normalize_tcp_init(struct pf_pdesc *pd, struct tcphdr *th,
break;
}
#endif /* INET6 */
+ default:
+ unhandled_af(pd->af);
}
/*
@@ -1581,6 +1583,8 @@ pf_normalize_tcp_stateful(struct pf_pdesc *pd,
break;
}
#endif /* INET6 */
+ default:
+ unhandled_af(pd->af);
}
if (th->th_off > (sizeof(struct tcphdr) >> 2) &&
@@ -2200,7 +2204,7 @@ pf_scrub(struct pf_pdesc *pd)
struct ip *h = mtod(pd->m, struct ip *);
#ifdef INET6
struct ip6_hdr *h6 = mtod(pd->m, struct ip6_hdr *);
-#endif
+#endif /* INET6 */
/* Clear IP_DF if no-df was requested */
if (pd->af == AF_INET && pd->act.flags & PFSTATE_NODF &&
@@ -2225,7 +2229,7 @@ pf_scrub(struct pf_pdesc *pd)
if (pd->af == AF_INET6 && pd->act.min_ttl &&
h6->ip6_hlim < pd->act.min_ttl)
h6->ip6_hlim = pd->act.min_ttl;
-#endif
+#endif /* INET6 */
/* Enforce tos */
if (pd->act.flags & PFSTATE_SETTOS) {
switch (pd->af) {
@@ -2244,7 +2248,7 @@ pf_scrub(struct pf_pdesc *pd)
h6->ip6_flow &= IPV6_FLOWLABEL_MASK | IPV6_VERSION_MASK;
h6->ip6_flow |= htonl((pd->act.set_tos | IPV6_ECN(h6)) << 20);
break;
-#endif
+#endif /* INET6 */
}
}
@@ -2257,6 +2261,6 @@ pf_scrub(struct pf_pdesc *pd)
ip_fillid(h, V_ip_random_id);
h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
}
-#endif
+#endif /* INET */
}
-#endif
+#endif /* INET || INET6 */
diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index 462b8c3aa782..d5874df3df66 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -791,10 +791,16 @@ pfr_create_kentry(struct pfr_addr *ad, bool counters)
if (ke == NULL)
return (NULL);
- if (ad->pfra_af == AF_INET)
+ switch (ad->pfra_af) {
+ case AF_INET:
FILLIN_SIN(ke->pfrke_sa.sin, ad->pfra_ip4addr);
- else if (ad->pfra_af == AF_INET6)
+ break;
+ case AF_INET6:
FILLIN_SIN6(ke->pfrke_sa.sin6, ad->pfra_ip6addr);
+ break;
+ default:
+ unhandled_af(ad->pfra_af);
+ }
ke->pfrke_af = ad->pfra_af;
ke->pfrke_net = ad->pfra_net;
ke->pfrke_not = ad->pfra_not;
@@ -933,11 +939,13 @@ pfr_prepare_network(union sockaddr_union *sa, int af, int net)
int i;
bzero(sa, sizeof(*sa));
- if (af == AF_INET) {
+ switch (af) {
+ case AF_INET:
sa->sin.sin_len = sizeof(sa->sin);
sa->sin.sin_family = AF_INET;
sa->sin.sin_addr.s_addr = net ? htonl(-1 << (32-net)) : 0;
- } else if (af == AF_INET6) {
+ break;
+ case AF_INET6:
sa->sin6.sin6_len = sizeof(sa->sin6);
sa->sin6.sin6_family = AF_INET6;
for (i = 0; i < 4; i++) {
@@ -949,6 +957,9 @@ pfr_prepare_network(union sockaddr_union *sa, int af, int net)
sa->sin6.sin6_addr.s6_addr32[i] = 0xFFFFFFFF;
net -= 32;
}
+ break;
+ default:
+ unhandled_af(af);
}
}
@@ -1022,10 +1033,16 @@ pfr_copyout_addr(struct pfr_addr *ad, const struct pfr_kentry *ke)
ad->pfra_af = ke->pfrke_af;
ad->pfra_net = ke->pfrke_net;
ad->pfra_not = ke->pfrke_not;
- if (ad->pfra_af == AF_INET)
+ switch (ad->pfra_af) {
+ case AF_INET:
ad->pfra_ip4addr = ke->pfrke_sa.sin.sin_addr;
- else if (ad->pfra_af == AF_INET6)
+ break;
+ case AF_INET6:
ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr;
+ break;
+ default:
+ unhandled_af(ad->pfra_af);
+ }
}
static void
@@ -1118,18 +1135,23 @@ pfr_walktree(struct radix_node *rn, void *arg)
{
union sockaddr_union pfr_mask;
- if (ke->pfrke_af == AF_INET) {
+ switch (ke->pfrke_af) {
+ case AF_INET:
if (w->pfrw_dyn->pfid_acnt4++ > 0)
break;
pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
pfr_sockaddr_to_pf_addr(&ke->pfrke_sa, &w->pfrw_dyn->pfid_addr4);
pfr_sockaddr_to_pf_addr(&pfr_mask, &w->pfrw_dyn->pfid_mask4);
- } else if (ke->pfrke_af == AF_INET6){
+ break;
+ case AF_INET6:
if (w->pfrw_dyn->pfid_acnt6++ > 0)
break;
pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
pfr_sockaddr_to_pf_addr(&ke->pfrke_sa, &w->pfrw_dyn->pfid_addr6);
pfr_sockaddr_to_pf_addr(&pfr_mask, &w->pfrw_dyn->pfid_mask6);
+ break;
+ default:
+ unhandled_af(ke->pfrke_af);
}
break;
}
@@ -2352,6 +2374,8 @@ _next_block:
ke2 = (struct pfr_kentry *)rn_match(&uaddr,
&kt->pfrkt_ip6->rh);
break;
+ default:
+ unhandled_af(af);
}
/* no need to check KENTRY_RNF_ROOT() here */
if (ke2 == ke) {
@@ -2416,8 +2440,18 @@ pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
dyn->pfid_acnt4 = 0;
dyn->pfid_acnt6 = 0;
- if (!dyn->pfid_af || dyn->pfid_af == AF_INET)
+ switch (dyn->pfid_af) {
+ case AF_UNSPEC: /* look up all both addresses IPv4 + IPv6 */
kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh, pfr_walktree, &w);
- if (!dyn->pfid_af || dyn->pfid_af == AF_INET6)
kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh, pfr_walktree, &w);
+ break;
+ case AF_INET:
+ kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh, pfr_walktree, &w);
+ break;
+ case AF_INET6:
+ kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh, pfr_walktree, &w);
+ break;
+ default:
+ unhandled_af(dyn->pfid_af);
+ }
}