The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=abda72f3a1f60121dbe1341f3aadfb714cdee1fb

commit abda72f3a1f60121dbe1341f3aadfb714cdee1fb
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-04-08 15:36:58 +0000
Commit:     Kristof Provost <k...@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 <sas...@openbsd.org>, 9b00340fee
    Obtained from:  OpenBSD, sashan <sas...@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);
+       }
 }

Reply via email to