svn commit: r348346 - head/sys/net
Kyle Evans
kevans at FreeBSD.org
Wed May 29 01:08:31 UTC 2019
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); \
} \
More information about the svn-src-all
mailing list