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); + } }