I'm progressively changing how pseudo-drivers are "plugged" into our
network stack with the goal to turning them MP-safe.

The diff below is a simple refactoring and should not introduce any
behavior change.  It moves a bridge-specific vlan-related chunk of
code into the bridge(4) driver.

I'd like to hear from people with a simple, complicated or even weird
bridge+vlan setup :)

I also appreciate comments and oks!

Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.232
diff -u -p -r1.232 if_bridge.c
--- net/if_bridge.c     6 Feb 2015 22:10:43 -0000       1.232
+++ net/if_bridge.c     11 Mar 2015 14:32:05 -0000
@@ -117,6 +117,8 @@ void        bridge_localbroadcast(struct bridge
     struct ether_header *, struct mbuf *);
 void   bridge_span(struct bridge_softc *, struct ether_header *,
     struct mbuf *);
+struct mbuf *bridge_dispatch(struct bridge_iflist *, struct ifnet *,
+    struct ether_header *, struct mbuf *);
 void   bridge_stop(struct bridge_softc *);
 void   bridge_init(struct bridge_softc *);
 int    bridge_bifconf(struct bridge_softc *, struct ifbifconf *);
@@ -1299,10 +1301,10 @@ struct mbuf *
 bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m)
 {
        struct bridge_softc *sc;
-       int s;
-       struct bridge_iflist *ifl, *srcifl;
-       struct arpcom *ac;
-       struct mbuf *mc;
+       struct bridge_iflist *ifl;
+#if NVLAN > 0
+       uint16_t etype = ntohs(eh->ether_type);
+#endif /* NVLAN > 0 */
 
        /*
         * Make sure this interface is a bridge member.
@@ -1328,6 +1330,31 @@ bridge_input(struct ifnet *ifp, struct e
 
        bridge_span(sc, eh, m);
 
+       m = bridge_dispatch(ifl, ifp, eh, m);
+
+#if NVLAN > 0
+       if ((m != NULL) && ((m->m_flags & M_VLANTAG) ||
+           etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ)) {
+               /* The bridge did not want the vlan frame either, drop it. */
+               ifp->if_noproto++;
+               m_freem(m);
+               m = NULL;
+       }
+#endif /* NVLAN > 0 */
+
+       return (m);
+}
+
+struct mbuf *
+bridge_dispatch(struct bridge_iflist *ifl, struct ifnet *ifp,
+    struct ether_header *eh, struct mbuf *m)
+{
+       struct bridge_softc *sc = ifl->bridge_sc;
+       struct bridge_iflist *srcifl;
+       struct arpcom *ac;
+       struct mbuf *mc;
+       int s;
+
        if (m->m_flags & (M_BCAST | M_MCAST)) {
                /*
                 * Reserved destination MAC addresses (01:80:C2:00:00:0x)
@@ -1377,6 +1404,7 @@ bridge_input(struct ifnet *ifp, struct e
                IF_ENQUEUE(&sc->sc_if.if_snd, mc);
                splx(s);
                schednetisr(NETISR_BRIDGE);
+#if NGIF > 0
                if (ifp->if_type == IFT_GIF) {
                        TAILQ_FOREACH(ifl, &sc->sc_iflist, next) {
                                if (ifl->ifp->if_type == IFT_ETHER)
@@ -1396,6 +1424,7 @@ bridge_input(struct ifnet *ifp, struct e
                                m = NULL;
                        }
                }
+#endif /* NGIF */
                return (m);
        }
 
@@ -1446,11 +1475,13 @@ bridge_input(struct ifnet *ifp, struct e
 
                        m->m_pkthdr.rcvif = ifl->ifp;
                        m->m_pkthdr.ph_rtableid = ifl->ifp->if_rdomain;
+#if NGIF > 0
                        if (ifp->if_type == IFT_GIF) {
                                m->m_flags |= M_PROTO1;
                                ether_input(ifl->ifp, eh, m);
                                m = NULL;
                        }
+#endif /* NGIF */
                        return (m);
                }
                if (bcmp(ac->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN) == 0
Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.189
diff -u -p -r1.189 if_ethersubr.c
--- net/if_ethersubr.c  16 Feb 2015 18:24:02 -0000      1.189
+++ net/if_ethersubr.c  11 Mar 2015 11:06:54 -0000
@@ -563,16 +563,6 @@ ether_input(struct ifnet *ifp0, void *hd
        }
 #endif
 
-#if NVLAN > 0
-       if ((m->m_flags & M_VLANTAG) || etype == ETHERTYPE_VLAN ||
-           etype == ETHERTYPE_QINQ) {
-               /* The bridge did not want the vlan frame either, drop it. */
-               ifp->if_noproto++;
-               m_freem(m);
-               return (1);
-       }
-#endif /* NVLAN > 0 */
-
 #if NCARP > 0
        if (ifp->if_carp) {
                if (ifp->if_type != IFT_CARP && (carp_input(ifp, eh, m) == 0))

Reply via email to