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