Right now vlan_input() is called *after* ether_input(). More precisely it is called after the mbuf has been m_adj(9)'usted to skip the Ethernet header. This is not a problem in se but...
To make sure vlan(4) keeps working during the if_input() transition, it has to stop calling ether_input() and use if_input() instead. Since this new API will run input handler *before* ether_input(), the packet *must* contain the original Ethernet header. Hence the small hack below. This is just temporary this code will be deleted as soon as vlan(4) is converted to if_input(). Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.114 diff -u -p -r1.114 if_vlan.c --- net/if_vlan.c 7 Apr 2015 10:46:20 -0000 1.114 +++ net/if_vlan.c 9 Apr 2015 12:12:35 -0000 @@ -277,6 +277,7 @@ vlan_input(struct ether_header *eh, stru struct vlan_taghash *tagh; u_int tag; u_int16_t etype; + struct ether_header *eh1; if (m->m_flags & M_VLANTAG) { etype = ETHERTYPE_VLAN; @@ -351,8 +352,14 @@ vlan_input(struct ether_header *eh, stru } } + M_PREPEND(m, sizeof(*eh1), M_DONTWAIT); + if (m == NULL) + return (-1); + eh1 = mtod(m, struct ether_header *); + memmove(eh1, eh, sizeof(*eh1)); + ifv->ifv_if.if_ipackets++; - ether_input(m, eh); + ether_input_mbuf(&ifv->ifv_if, m); return (0); }