git: 950cc1f44fbd - main - bpf: Add "_if" tap APIs

From: Justin Hibbits <jhibbits_at_FreeBSD.org>
Date: Tue, 31 Jan 2023 20:03:12 UTC
The branch main has been updated by jhibbits:

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

commit 950cc1f44fbd5965db7b679c0aaf1bd9b432ec25
Author:     Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2023-01-12 20:17:33 +0000
Commit:     Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2023-01-31 20:02:14 +0000

    bpf: Add "_if" tap APIs
    
    Summary:
    Hide more netstack by making the BPF_TAP macros real functions in the
    netstack.  "struct ifnet" is used in the header instead of "if_t" to
    keep header pollution down.
    
    Sponsored by:   Juniper Networks, Inc.
    Differential Revision: https://reviews.freebsd.org/D38103
---
 sys/net/bpf.c          | 25 +++++++++++++++++++++++++
 sys/net/bpf.h          | 27 ++++++++++-----------------
 sys/net/ethernet.h     | 15 +++++----------
 sys/net/if_ethersubr.c | 12 ++++++++++++
 4 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index ab733f1d68ec..ffac63ef95d9 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -2349,6 +2349,13 @@ bpf_tap(struct bpf_if *bp, u_char *pkt, u_int pktlen)
 	NET_EPOCH_EXIT(et);
 }
 
+void
+bpf_tap_if(if_t ifp, u_char *pkt, u_int pktlen)
+{
+	if (bpf_peers_present(ifp->if_bpf))
+		bpf_tap(ifp->if_bpf, pkt, pktlen);
+}
+
 #define	BPF_CHECK_DIRECTION(d, r, i)				\
 	    (((d)->bd_direction == BPF_D_IN && (r) != (i)) ||	\
 	    ((d)->bd_direction == BPF_D_OUT && (r) == (i)))
@@ -2409,6 +2416,15 @@ bpf_mtap(struct bpf_if *bp, struct mbuf *m)
 	NET_EPOCH_EXIT(et);
 }
 
+void
+bpf_mtap_if(if_t ifp, struct mbuf *m)
+{
+	if (bpf_peers_present(ifp->if_bpf)) {
+		M_ASSERTVALID(m);
+		bpf_mtap(ifp->if_bpf, m);
+	}
+}
+
 /*
  * Incoming linkage from device drivers, when packet is in
  * an mbuf chain and to be prepended by a contiguous header.
@@ -2466,6 +2482,15 @@ bpf_mtap2(struct bpf_if *bp, void *data, u_int dlen, struct mbuf *m)
 	NET_EPOCH_EXIT(et);
 }
 
+void
+bpf_mtap2_if(if_t ifp, void *data, u_int dlen, struct mbuf *m)
+{
+	if (bpf_peers_present(ifp->if_bpf)) {
+		M_ASSERTVALID(m);
+		bpf_mtap2(ifp->if_bpf, data, dlen, m);
+	}
+}
+
 #undef	BPF_CHECK_DIRECTION
 #undef	BPF_TSTAMP_NONE
 #undef	BPF_TSTAMP_FAST
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index e5b8898188f1..279d2f65e7fc 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -53,6 +53,7 @@ typedef	int32_t	  bpf_int32;
 typedef	u_int32_t bpf_u_int32;
 typedef	int64_t	  bpf_int64;
 typedef	u_int64_t bpf_u_int64;
+struct ifnet;
 
 /*
  * Alignment macros.  BPF_WORDALIGN rounds up to the next multiple of
@@ -421,8 +422,11 @@ struct bpf_if_ext {
 void	 bpf_bufheld(struct bpf_d *d);
 int	 bpf_validate(const struct bpf_insn *, int);
 void	 bpf_tap(struct bpf_if *, u_char *, u_int);
+void	 bpf_tap_if(struct ifnet *, u_char *, u_int);
 void	 bpf_mtap(struct bpf_if *, struct mbuf *);
+void	 bpf_mtap_if(struct ifnet *, struct mbuf *);
 void	 bpf_mtap2(struct bpf_if *, void *, u_int, struct mbuf *);
+void	 bpf_mtap2_if(struct ifnet *, void *, u_int, struct mbuf *);
 void	 bpfattach(struct ifnet *, u_int, u_int);
 void	 bpfattach2(struct ifnet *, u_int, u_int, struct bpf_if **);
 void	 bpfdetach(struct ifnet *);
@@ -444,22 +448,12 @@ bpf_peers_present(struct bpf_if *bpf)
 	return (0);
 }
 
-#define	BPF_TAP(_ifp,_pkt,_pktlen) do {				\
-	if (bpf_peers_present((_ifp)->if_bpf))			\
-		bpf_tap((_ifp)->if_bpf, (_pkt), (_pktlen));	\
-} while (0)
-#define	BPF_MTAP(_ifp,_m) do {					\
-	if (bpf_peers_present((_ifp)->if_bpf)) {		\
-		M_ASSERTVALID(_m);				\
-		bpf_mtap((_ifp)->if_bpf, (_m));			\
-	}							\
-} while (0)
-#define	BPF_MTAP2(_ifp,_data,_dlen,_m) do {			\
-	if (bpf_peers_present((_ifp)->if_bpf)) {		\
-		M_ASSERTVALID(_m);				\
-		bpf_mtap2((_ifp)->if_bpf,(_data),(_dlen),(_m));	\
-	}							\
-} while (0)
+#define	BPF_TAP(_ifp,_pkt,_pktlen)				\
+		bpf_tap_if((_ifp), (_pkt), (_pktlen))
+#define	BPF_MTAP(_ifp,_m) 					\
+	bpf_mtap_if((_ifp), (_m))
+#define	BPF_MTAP2(_ifp,_data,_dlen,_m) 				\
+	bpf_mtap2_if((_ifp), (_data), (_dlen), (_m))
 #endif
 
 /*
@@ -468,7 +462,6 @@ bpf_peers_present(struct bpf_if *bpf)
 #define BPF_MEMWORDS 16
 
 /* BPF attach/detach events */
-struct ifnet;
 typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */,
     int /* 1 =>'s attach */);
 EVENTHANDLER_DECLARE(bpf_track, bpf_track_fn);
diff --git a/sys/net/ethernet.h b/sys/net/ethernet.h
index 807420957aef..98b02d71da50 100644
--- a/sys/net/ethernet.h
+++ b/sys/net/ethernet.h
@@ -35,7 +35,7 @@
  * encapsulation) and whether or not an FCS is present.
  */
 #define	ETHER_MAX_FRAME(ifp, etype, hasfcs)				\
-	((ifp)->if_mtu + ETHER_HDR_LEN +				\
+	(if_getmtu(ifp) + ETHER_HDR_LEN +				\
 	 ((hasfcs) ? ETHER_CRC_LEN : 0) +				\
 	 (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))
 
@@ -399,15 +399,10 @@ struct ether_vlan_header {
  * ether_vlan_mtap.  This function will re-insert VLAN tags for the duration
  * of the tap, so they show up properly for network analyzers.
  */
-#define	ETHER_BPF_MTAP(_ifp, _m) do {					\
-	if (bpf_peers_present((_ifp)->if_bpf)) {			\
-		M_ASSERTVALID(_m);					\
-		if (((_m)->m_flags & M_VLANTAG) != 0)			\
-			ether_vlan_mtap((_ifp)->if_bpf, (_m), NULL, 0);	\
-		else							\
-			bpf_mtap((_ifp)->if_bpf, (_m));			\
-	}								\
-} while (0)
+struct ifnet;
+struct mbuf;
+void ether_bpf_mtap_if(struct ifnet *ifp, struct mbuf *m);
+#define	ETHER_BPF_MTAP(_ifp, _m)	ether_bpf_mtap_if((_ifp), (_m))
 
 /*
  * Names for 802.1q priorities ("802.1p").  Notice that in this scheme,
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index b3fc71006a35..8bc66497e161 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1337,6 +1337,18 @@ ether_vlanencap_proto(struct mbuf *m, uint16_t tag, uint16_t proto)
 	return (m);
 }
 
+void
+ether_bpf_mtap_if(struct ifnet *ifp, struct mbuf *m)
+{
+	if (bpf_peers_present(ifp->if_bpf)) {
+		M_ASSERTVALID(m);
+		if ((m->m_flags & M_VLANTAG) != 0)
+			ether_vlan_mtap(ifp->if_bpf, m, NULL, 0);
+		else
+			bpf_mtap(ifp->if_bpf, m);
+	}
+}
+
 static SYSCTL_NODE(_net_link, IFT_L2VLAN, vlan, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
     "IEEE 802.1Q VLAN");
 static SYSCTL_NODE(_net_link_vlan, PF_LINK, link,