Author: kevans
Date: Thu Mar 28 03:31:51 2019
New Revision: 345627
URL: https://svnweb.freebsd.org/changeset/base/345627

Log:
  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

Modified:
  head/sys/net/if_bridge.c

Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c    Thu Mar 28 03:30:04 2019        (r345626)
+++ head/sys/net/if_bridge.c    Thu Mar 28 03:31:51 2019        (r345627)
@@ -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);                                             \
        }                                                               \


_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to