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;