git: 7e51bc6cdd5c - main - pf: Introduce unhandled_af()

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Tue, 04 Mar 2025 08:05:51 UTC
The branch main has been updated by kp:

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

commit 7e51bc6cdd5c317109e25b0b64230d00d68dceb3
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-03-03 16:26:39 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-03-04 08:05:37 +0000

    pf: Introduce unhandled_af()
    
    For cases where code conditionally does something based on an address family
    and later assumes one of the paths was taken.  This was initially just calls
    to panic until guenther suggested a function to reduce the amount of strings
    needed.
    
    This reduces the amount of noise with static analysers and acts as a sanity
    check.
    
    ok guenther@ bluhm@
    
    Obtained from:  OpenBSD, jsg <jsg@openbsd.org>, ba4138390b
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pfvar.h           |  1 +
 sys/netpfil/pf/pf.c       | 38 +++++++++++++++++++++++++++++++++++++-
 sys/netpfil/pf/pf_ioctl.c |  6 ++++++
 sys/netpfil/pf/pf_table.c | 37 +++++++++++++++++++++++++++++--------
 sys/netpfil/pf/pflow.c    |  4 ++--
 5 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index b9b7f71c07d1..2aaef12e3431 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2280,6 +2280,7 @@ VNET_DECLARE(struct pf_krule *, pf_rulemarker);
 #define V_pf_rulemarker     VNET(pf_rulemarker)
 #endif
 
+void				 unhandled_af(int) __dead2;
 int				 pf_start(void);
 int				 pf_stop(void);
 void				 pf_initialize(void);
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 72e648b84b2f..ad6be0c67c2a 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -601,6 +601,8 @@ pf_addr_cmp(struct pf_addr *a, struct pf_addr *b, sa_family_t af)
 			return (-1);
 		break;
 #endif /* INET6 */
+	default:
+		unhandled_af(af);
 	}
 	return (0);
 }
@@ -616,7 +618,7 @@ pf_is_loopback(sa_family_t af, struct pf_addr *addr)
 	case AF_INET6:
 		return IN6_IS_ADDR_LOOPBACK(&addr->v6);
 	default:
-		panic("Unknown af %d", af);
+		unhandled_af(af);
 	}
 }
 
@@ -696,6 +698,8 @@ pf_packet_rework_nat(struct mbuf *m, struct pf_pdesc *pd, int off,
 			case AF_INET6:
 				PF_ACPY(pd->src, &nk->addr[pd->sidx], pd->af);
 				break;
+			default:
+				unhandled_af(pd->af);
 			}
 		}
 		if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af)) {
@@ -708,6 +712,8 @@ pf_packet_rework_nat(struct mbuf *m, struct pf_pdesc *pd, int off,
 			case AF_INET6:
 				PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af);
 				break;
+			default:
+				unhandled_af(pd->af);
 			}
 		}
 		break;
@@ -740,6 +746,8 @@ pf_hashsrc(struct pf_addr *addr, sa_family_t af)
 		h = murmur3_32_hash32((uint32_t *)&addr->v6,
 		    sizeof(addr->v6)/sizeof(uint32_t), V_pf_hashseed);
 		break;
+	default:
+		unhandled_af(af);
 	}
 
 	return (h & V_pf_srchashmask);
@@ -803,6 +811,8 @@ pf_addrcpy(struct pf_addr *dst, const struct pf_addr *src, sa_family_t af)
 	case AF_INET6:
 		memcpy(&dst->v6, &src->v6, sizeof(dst->v6));
 		break;
+	default:
+		unhandled_af(af);
 	}
 }
 #endif /* INET6 */
@@ -931,6 +941,8 @@ pf_overload_task(void *v, int pending)
 			p.pfra_ip6addr = pfoe->addr.v6;
 			break;
 #endif
+		default:
+			unhandled_af(pfoe->af);
 		}
 
 		PF_RULES_WLOCK();
@@ -2174,6 +2186,8 @@ pf_isforlocal(struct mbuf *m, int af)
 		return (! (ia->ia6_flags & IN6_IFF_NOTREADY));
 	}
 #endif
+	default:
+		unhandled_af(af);
 	}
 
 	return (false);
@@ -2335,6 +2349,8 @@ pf_icmp_mapping(struct pf_pdesc *pd, u_int8_t type,
 		}
 		break;
 #endif /* INET6 */
+	default:
+		unhandled_af(pd->af);
 	}
 	HTONS(*virtual_type);
 	return (0);  /* These types match to their own state */
@@ -2960,6 +2976,8 @@ pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
 		break;
 	}
 #endif /* INET6 */
+	default:
+		unhandled_af(af);
 	}
 }
 
@@ -3333,6 +3351,8 @@ pf_change_ap(struct mbuf *m, struct pf_addr *a, u_int16_t *p, u_int16_t *ic,
 		}
 		break;
 #endif /* INET6 */
+	default:
+		unhandled_af(af);
 	}
 
 	if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | 
@@ -3639,6 +3659,8 @@ pf_change_icmp_af(struct mbuf *m, int off, struct pf_pdesc *pd,
 		ip6->ip6_src = src->v6;
 		ip6->ip6_dst = dst->v6;
 		break;
+	default:
+		unhandled_af(naf);
 	}
 
 	/* adjust payload offset and total packet length */
@@ -3877,6 +3899,8 @@ pf_translate_icmp_af(int af, void *arg)
 			icmp4->icmp_void = htonl(ptr);
 		}
 		break;
+	default:
+		unhandled_af(af);
 	}
 #endif /* INET && INET6 */
 
@@ -3983,6 +4007,8 @@ pf_build_tcp(const struct pf_krule *r, sa_family_t af,
 		len = sizeof(struct ip6_hdr) + tlen;
 		break;
 #endif /* INET6 */
+	default:
+		unhandled_af(af);
 	}
 
 	m = m_gethdr(M_NOWAIT, MT_DATA);
@@ -4148,6 +4174,8 @@ pf_send_sctp_abort(sa_family_t af, struct pf_pdesc *pd,
 		off += sizeof(struct ip6_hdr);
 		break;
 #endif /* INET6 */
+	default:
+		unhandled_af(af);
 	}
 
 	/* SCTP header */
@@ -4231,6 +4259,8 @@ pf_send_tcp(const struct pf_krule *r, sa_family_t af,
 		pfse->pfse_type = PFSE_IP6;
 		break;
 #endif /* INET6 */
+	default:
+		unhandled_af(af);
 	}
 
 	pfse->pfse_m = m;
@@ -7648,6 +7678,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
 		icmpsum = &pd->hdr.icmp6.icmp6_cksum;
 		break;
 #endif /* INET6 */
+	default:
+		panic("unhandled proto %d", pd->proto);
 	}
 
 	if (pf_icmp_mapping(pd, icmptype, &icmp_dir, &virtual_id,
@@ -7849,6 +7881,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
 			pd2.ip_sum = NULL;
 			break;
 #endif /* INET6 */
+		default:
+			unhandled_af(pd->af);
 		}
 
 		if (PF_ANEQ(pd->dst, pd2.src, pd->af)) {
@@ -8052,6 +8086,8 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
 					    (caddr_t )&h2_6);
 					break;
 #endif /* INET6 */
+				default:
+					unhandled_af(pd->af);
 				}
 				m_copyback(pd->m, pd2.off, 8, (caddr_t)&th);
 			}
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index e622186f671f..787715412fc2 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2406,6 +2406,12 @@ relock_DIOCKILLSTATES:
 	return (killed);
 }
 
+void
+unhandled_af(int af)
+{
+	panic("unhandled af %d", af);
+}
+
 int
 pf_start(void)
 {
diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index 666ec18ec377..462b8c3aa782 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -754,12 +754,17 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
 	PF_RULES_ASSERT();
 
 	bzero(&sa, sizeof(sa));
-	if (ad->pfra_af == AF_INET) {
+	switch (ad->pfra_af) {
+	case AF_INET:
 		FILLIN_SIN(sa.sin, ad->pfra_ip4addr);
 		head = &kt->pfrkt_ip4->rh;
-	} else if ( ad->pfra_af == AF_INET6 ) {
+		break;
+	case AF_INET6:
 		FILLIN_SIN6(sa.sin6, ad->pfra_ip6addr);
 		head = &kt->pfrkt_ip6->rh;
+		break;
+	default:
+		unhandled_af(ad->pfra_af);
 	}
 	if (ADDR_NETWORK(ad)) {
 		pfr_prepare_network(&mask, ad->pfra_af, ad->pfra_net);
@@ -957,10 +962,16 @@ pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
 	PF_RULES_WASSERT();
 
 	bzero(ke->pfrke_node, sizeof(ke->pfrke_node));
-	if (ke->pfrke_af == AF_INET)
+	switch (ke->pfrke_af) {
+	case AF_INET:
 		head = &kt->pfrkt_ip4->rh;
-	else if (ke->pfrke_af == AF_INET6)
+		break;
+	case AF_INET6:
 		head = &kt->pfrkt_ip6->rh;
+		break;
+	default:
+		unhandled_af(ke->pfrke_af);
+	}
 
 	if (KENTRY_NETWORK(ke)) {
 		pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
@@ -978,10 +989,16 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
 	struct radix_node	*rn;
 	struct radix_head	*head = NULL;
 
-	if (ke->pfrke_af == AF_INET)
+	switch (ke->pfrke_af) {
+	case AF_INET:
 		head = &kt->pfrkt_ip4->rh;
-	else if (ke->pfrke_af == AF_INET6)
+		break;
+	case AF_INET6:
 		head = &kt->pfrkt_ip6->rh;
+		break;
+	default:
+		unhandled_af(ke->pfrke_af);
+	}
 
 	if (KENTRY_NETWORK(ke)) {
 		pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
@@ -1051,7 +1068,7 @@ pfr_sockaddr_to_pf_addr(const union sockaddr_union *sa, struct pf_addr *a)
 		memcpy(&a->v6, &sa->sin6.sin6_addr, sizeof(a->v6));
 		break;
 	default:
-		panic("Unknown AF");
+		unhandled_af(sa->sa.sa_family);
 	}
 }
 
@@ -2079,6 +2096,8 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
 		break;
 	    }
 #endif /* INET6 */
+	default:
+		unhandled_af(af);
 	}
 	match = (ke && !ke->pfrke_not);
 	if (match)
@@ -2131,7 +2150,7 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
 	    }
 #endif /* INET6 */
 	default:
-		panic("%s: unknown address family %u", __func__, af);
+		unhandled_af(af);
 	}
 	if ((ke == NULL || ke->pfrke_not) != notrule) {
 		if (op_pass != PFR_OP_PASS)
@@ -2261,6 +2280,8 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
 		uaddr.sin6.sin6_family = AF_INET6;
 		addr = (struct pf_addr *)&uaddr.sin6.sin6_addr;
 		break;
+	default:
+		unhandled_af(af);
 	}
 
 	if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
diff --git a/sys/netpfil/pf/pflow.c b/sys/netpfil/pf/pflow.c
index ae9d162bb6bf..00890589814d 100644
--- a/sys/netpfil/pf/pflow.c
+++ b/sys/netpfil/pf/pflow.c
@@ -1216,7 +1216,7 @@ pflow_sendout_ipfix(struct pflow_softc *sc, enum pflow_family_t af)
 		    + sc->sc_count_nat4 * sizeof(struct pflow_ipfix_nat4);
 		break;
 	default:
-		panic("Unsupported AF %d", af);
+		unhandled_af(af);
 	}
 
 	pflowstat_inc(pflow_packets);
@@ -1444,7 +1444,7 @@ nlattr_add_sockaddr(struct nl_writer *nw, int attr, const struct sockaddr *s)
 		break;
 	}
 	default:
-		panic("Unknown address family %d", s->sa_family);
+		unhandled_af(s->sa_family);
 	}
 
 	nlattr_set_len(nw, off);