mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 17:22:46 -04:00
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:
parent
09b47fc1c2
commit
93c9d31918
1 changed files with 18 additions and 16 deletions
|
|
@ -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); \
|
||||
} \
|
||||
|
|
|
|||
Loading…
Reference in a new issue