Index: if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.274 diff -u -p -r1.274 if_ethersubr.c --- if_ethersubr.c 7 Mar 2021 06:02:32 -0000 1.274 +++ if_ethersubr.c 5 Jul 2021 07:11:17 -0000 @@ -404,12 +404,12 @@ ether_input(struct ifnet *ifp, struct mb if (ISSET(m->m_flags, M_VLANTAG) || etype == ETHERTYPE_VLAN || etype == ETHERTYPE_QINQ) { #if NVLAN > 0 - m = vlan_input(ifp, m); + m = vlan_input(ifp, m, &sdelim); if (m == NULL) return; -#endif /* NVLAN > 0 */ - +#else sdelim = 1; +#endif } /* Index: if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.207 diff -u -p -r1.207 if_vlan.c --- if_vlan.c 9 Jun 2021 03:24:54 -0000 1.207 +++ if_vlan.c 5 Jul 2021 07:11:17 -0000 @@ -336,6 +336,23 @@ leave: } struct mbuf * +vlan_strip(struct mbuf *m) +{ + if (ISSET(m->m_flags, M_VLANTAG)) { + CLR(m->m_flags, M_VLANTAG); + } else { + struct ether_vlan_header *evl; + + evl = mtod(m, struct ether_vlan_header *); + memmove((caddr_t)evl + EVL_ENCAPLEN, evl, + offsetof(struct ether_vlan_header, evl_encap_proto)); + m_adj(m, EVL_ENCAPLEN); + } + + return (m); +} + +struct mbuf * vlan_inject(struct mbuf *m, uint16_t type, uint16_t tag) { struct ether_vlan_header evh; @@ -358,7 +375,7 @@ vlan_inject(struct mbuf *m, uint16_t typ } struct mbuf * -vlan_input(struct ifnet *ifp0, struct mbuf *m) +vlan_input(struct ifnet *ifp0, struct mbuf *m, unsigned int *sdelim) { struct vlan_softc *sc; struct ifnet *ifp; @@ -407,8 +424,16 @@ vlan_input(struct ifnet *ifp0, struct mb } smr_read_leave(); - if (sc == NULL) - return (m); /* decline, let bridge have a go */ + if (sc == NULL) { + /* VLAN 0 Priority Tagging */ + if (tag == 0 && etype == ETHERTYPE_VLAN) { + /* XXX we should actually use the prio value? */ + m = vlan_strip(m); + } else + *sdelim = 1; + + return (m); /* decline */ + } ifp = &sc->sc_if; if (!ISSET(ifp->if_flags, IFF_RUNNING)) { @@ -421,13 +446,7 @@ vlan_input(struct ifnet *ifp0, struct mb * the given source interface and vlan tag, remove the * encapsulation. */ - if (ISSET(m->m_flags, M_VLANTAG)) { - CLR(m->m_flags, M_VLANTAG); - } else { - memmove((caddr_t)evl + EVL_ENCAPLEN, evl, - offsetof(struct ether_vlan_header, evl_encap_proto)); - m_adj(m, EVL_ENCAPLEN); - } + m = vlan_strip(m); rxprio = sc->sc_rxprio; switch (rxprio) { Index: if_vlan_var.h =================================================================== RCS file: /cvs/src/sys/net/if_vlan_var.h,v retrieving revision 1.42 diff -u -p -r1.42 if_vlan_var.h --- if_vlan_var.h 22 Jul 2020 01:30:54 -0000 1.42 +++ if_vlan_var.h 5 Jul 2021 07:11:17 -0000 @@ -47,7 +47,7 @@ struct vlanreq { }; #ifdef _KERNEL -struct mbuf *vlan_input(struct ifnet *, struct mbuf *); +struct mbuf *vlan_input(struct ifnet *, struct mbuf *, unsigned int *); struct mbuf *vlan_inject(struct mbuf *, uint16_t, uint16_t); #endif /* _KERNEL */