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))