if_bridge(4): ensure all traffic passing over the bridge is accounted for

Consider a bridge0 with em0 and em1 members. Traffic rx'd by em0 and
transmitted by bridge0 through em1 gets accounted for in IPACKETS/IBYTES
and bridge0 bpf -- assuming it's not unicast traffic destined for em1.
Unicast traffic destined for em1 traffic is not accounted for by any
mechanism, and isn't pushed through bridge0's bpf machinery as any other
packets that pass over the bridge do.

Fix this and simplify GRAB_OUR_PACKETS by bailing out early if it was rx'd
by the interface that it was addressed for. Everything else there is
relevant for any traffic that came in from one member that's being directed
at another member of the bridge.

Reviewed by:	kp
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D19614
This commit is contained in:
Kyle Evans 2019-03-28 03:31:51 +00:00
parent 09b47fc1c2
commit 93c9d31918
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345627

View File

@ -2422,22 +2422,6 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
if (memcmp(IF_LLADDR((iface)), eh->ether_dhost, ETHER_ADDR_LEN) == 0 \
OR_CARP_CHECK_WE_ARE_DST((iface)) \
) { \
if ((iface)->if_type == IFT_BRIDGE) { \
ETHER_BPF_MTAP(iface, m); \
if_inc_counter(iface, IFCOUNTER_IPACKETS, 1); \
if_inc_counter(iface, IFCOUNTER_IBYTES, m->m_pkthdr.len); \
/* Filter on the physical interface. */ \
if (V_pfil_local_phys && \
(PFIL_HOOKED_IN(V_inet_pfil_head) \
OR_PFIL_HOOKED_INET6)) { \
if (bridge_pfil(&m, NULL, ifp, \
PFIL_IN) != 0 || m == NULL) { \
BRIDGE_UNLOCK(sc); \
return (NULL); \
} \
eh = mtod(m, struct ether_header *); \
} \
} \
if (bif->bif_flags & IFBIF_LEARNING) { \
error = bridge_rtupdate(sc, eh->ether_shost, \
vlan, bif, 0, IFBAF_DYNAMIC); \
@ -2448,6 +2432,24 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
} \
} \
m->m_pkthdr.rcvif = iface; \
if ((iface) == ifp) { \
/* Skip bridge processing... src == dest */ \
BRIDGE_UNLOCK(sc); \
return (m); \
} \
/* It's passing over or to the bridge, locally. */ \
ETHER_BPF_MTAP(bifp, m); \
if_inc_counter(bifp, IFCOUNTER_IPACKETS, 1); \
if_inc_counter(bifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); \
/* Filter on the physical interface. */ \
if (V_pfil_local_phys && (PFIL_HOOKED_IN(V_inet_pfil_head) \
OR_PFIL_HOOKED_INET6)) { \
if (bridge_pfil(&m, NULL, ifp, \
PFIL_IN) != 0 || m == NULL) { \
BRIDGE_UNLOCK(sc); \
return (NULL); \
} \
} \
BRIDGE_UNLOCK(sc); \
return (m); \
} \