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
This commit is contained in:
parent
610a21fd82
commit
d8b985430c
@ -2000,7 +2000,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
|
||||
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, struct sockaddr *sa,
|
||||
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, struct sockaddr *sa,
|
||||
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, struct sockaddr *sa,
|
||||
} 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); \
|
||||
} \
|
||||
|
Loading…
x
Reference in New Issue
Block a user