HW-vlan breaks our if_input() design because vlan packets are
decapsulated before calling if_input().

So it doesn't matter in which order you configured your pseudo-driver,
they all have to deal with this layer violation.

Here's a jumbo diff for carp(4) and bridge(4).

Index: net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.278
diff -u -p -r1.278 if_bridge.c
--- net/if_bridge.c     12 Apr 2016 06:20:30 -0000      1.278
+++ net/if_bridge.c     23 May 2016 13:17:08 -0000
@@ -1063,6 +1063,18 @@ bridge_process(struct ifnet *ifp, struct
        if ((sc->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
                goto reenqueue;
 
+#if NVLAN > 0
+       /*
+        * If the underlying interface removed the VLAN header itself,
+        * add it back.
+        */
+       if (ISSET(m->m_flags, M_VLANTAG)) {
+               m = vlan_inject(m, ETHERTYPE_VLAN, m->m_pkthdr.ether_vtag);
+               if (m == NULL)
+                       return;
+       }
+#endif
+
 #if NBPFILTER > 0
        if (sc->sc_if.if_bpf)
                bpf_mtap_ether(sc->sc_if.if_bpf, m, BPF_DIRECTION_IN);
Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.289
diff -u -p -r1.289 ip_carp.c
--- netinet/ip_carp.c   18 May 2016 03:46:03 -0000      1.289
+++ netinet/ip_carp.c   23 May 2016 13:14:48 -0000
@@ -80,6 +80,10 @@
 #include <net/bpf.h>
 #endif
 
+#if NVLAN > 0
+#include <net/if_vlan_var.h>
+#endif
+
 #include <netinet/ip_carp.h>
 
 struct carp_mc_entry {
@@ -1398,6 +1402,15 @@ carp_input(struct ifnet *ifp0, struct mb
        struct carp_if *cif;
        struct carp_softc *sc;
        struct srp_ref sr;
+
+#if NVLAN > 0
+       /*
+        * If the underlying interface removed the VLAN header itself,
+        * it's not for us.
+        */
+       if (ISSET(m->m_flags, M_VLANTAG))
+               return (0);
+#endif
 
        eh = mtod(m, struct ether_header *);
        cif = (struct carp_if *)cookie;

Reply via email to