--- /sys/net/if_gif.c.orig 2008-10-03 14:18:50.000000000 +0400 +++ /sys/net/if_gif.c 2008-10-03 11:43:48.000000000 +0400 @@ -81,6 +81,7 @@ #include #include +#include #include #include @@ -560,6 +561,31 @@ m->m_flags |= M_MCAST; ifp->if_imcasts++; } + /* Check vlan tagging on received frame. */ + /* Probably should be moved somewhere up. */ + if (ntohs(eh->ether_type) == ETHERTYPE_VLAN) { + /* Copy from if_ethersubr.c */ + struct ether_vlan_header *evl; + if (m->m_len < sizeof(*evl) && + (m = m_pullup(m, sizeof(*evl))) == NULL) { +#ifdef DIAGNOSTIC + if_printf(ifp, "cannot pullup VLAN header\n"); +#endif + ifp->if_ierrors++; + m_freem(m); + return; + } + + evl = mtod(m, struct ether_vlan_header *); + m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag); + m->m_flags |= M_VLANTAG; + + bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN, + ETHER_HDR_LEN - ETHER_TYPE_LEN); + m_adj(m, ETHER_VLAN_ENCAP_LEN); + /* End of copy */ + } + BRIDGE_INPUT(ifp, m); if (m != NULL && ifp != oldifp) {