Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 May 2019 01:08:30 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r348346 - head/sys/net
Message-ID:  <201905290108.x4T18Ub3014929@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Wed May 29 01:08:30 2019
New Revision: 348346
URL: https://svnweb.freebsd.org/changeset/base/348346

Log:
  if_bridge(4): Complete bpf auditing of local traffic over the bridge
  
  There were two remaining "gaps" in auditing local bridge traffic with
  bpf(4):
  
  Locally originated outbound traffic from a member interface is invisible to
  the bridge's bpf(4) interface. Inbound traffic locally destined to a member
  interface is invisible to the member's bpf(4) interface -- this traffic has
  no chance after bridge_input to otherwise pass it over, and it wasn't
  originally received on this interface.
  
  I call these "gaps" because they don't affect conventional bridge setups.
  Alas, being able to establish an audit trail of all locally destined traffic
  for setups that can function like this is useful in some scenarios.
  
  Reviewed by:	kp
  MFC after:	1 week
  Differential Revision:	https://reviews.freebsd.org/D19757

Modified:
  head/sys/net/if_bridge.c

Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c	Wed May 29 00:54:49 2019	(r348345)
+++ head/sys/net/if_bridge.c	Wed May 29 01:08:30 2019	(r348346)
@@ -2000,7 +2000,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struc
     struct rtentry *rt)
 {
 	struct ether_header *eh;
-	struct ifnet *dst_if;
+	struct ifnet *bifp, *dst_if;
 	struct bridge_softc *sc;
 	uint16_t vlan;
 
@@ -2015,13 +2015,14 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struc
 	vlan = VLANTAGOF(m);
 
 	BRIDGE_LOCK(sc);
+	bifp = sc->sc_ifp;
 
 	/*
 	 * If bridge is down, but the original output interface is up,
 	 * go ahead and send out that interface.  Otherwise, the packet
 	 * is dropped below.
 	 */
-	if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+	if ((bifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		dst_if = ifp;
 		goto sendunicast;
 	}
@@ -2034,6 +2035,9 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struc
 		dst_if = NULL;
 	else
 		dst_if = bridge_rtlookup(sc, eh->ether_dhost, vlan);
+	/* Tap any traffic not passing back out the originating interface */
+	if (dst_if != ifp)
+		ETHER_BPF_MTAP(bifp, m);
 	if (dst_if == NULL) {
 		struct bridge_iflist *bif;
 		struct mbuf *mc;
@@ -2071,7 +2075,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struc
 			} else {
 				mc = m_copypacket(m, M_NOWAIT);
 				if (mc == NULL) {
-					if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1);
+					if_inc_counter(bifp, IFCOUNTER_OERRORS, 1);
 					continue;
 				}
 			}
@@ -2450,6 +2454,8 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
 				return (NULL);				\
 			}						\
 		}							\
+		if ((iface) != bifp)					\
+			ETHER_BPF_MTAP(iface, m);			\
 		BRIDGE_UNLOCK(sc);					\
 		return (m);						\
 	}								\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905290108.x4T18Ub3014929>