Gary, and anyone else who can test VLAN support, please try this
    patch and tell me if it works.

                                                -Matt

Index: net/vlan/if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/vlan/if_vlan.c,v
retrieving revision 1.18
diff -u -r1.18 if_vlan.c
--- net/vlan/if_vlan.c  28 Nov 2005 17:13:46 -0000      1.18
+++ net/vlan/if_vlan.c  27 Dec 2005 22:42:05 -0000
@@ -379,10 +379,8 @@
 {
        struct bpf_if *bif;
        struct ifvlan *ifv;
-       struct ether_header *eh = mtod(m, struct ether_header *);
        struct ifnet *rcvif;
 
-       m_adj(m, ETHER_HDR_LEN);
        rcvif = m->m_pkthdr.rcvif;
 
        ASSERT_SERIALIZED(rcvif->if_serializer);
@@ -392,14 +390,18 @@
         * bpf tap if active.
         */
        if ((bif = rcvif->if_bpf) != NULL) {
+               struct ether_header *eh;
                struct ether_vlan_header evh;
 
+               eh = mtod(m, struct ether_header *);
+               m_adj(m, ETHER_HDR_LEN);
                bcopy(eh, &evh, 2*ETHER_ADDR_LEN);
                evh.evl_encap_proto = htons(ETHERTYPE_VLAN);
                evh.evl_tag = htons(t);
                evh.evl_proto = eh->ether_type;
-
                bpf_ptap(bif, m, &evh, ETHER_HDR_LEN + EVL_ENCAPLEN);
+               /* XXX assumes data was left intact */
+               M_PREPEND(m, ETHER_HDR_LEN, MB_WAIT); 
        }
 
        for (ifv = LIST_FIRST(&ifv_list); ifv != NULL;
@@ -423,7 +425,7 @@
        ifv->ifv_if.if_ipackets++;
        lwkt_serialize_exit(rcvif->if_serializer);
        lwkt_serialize_enter(ifv->ifv_if.if_serializer);
-       ether_input(&ifv->ifv_if, eh, m);
+       ether_input(&ifv->ifv_if, NULL, m);
        lwkt_serialize_exit(ifv->ifv_if.if_serializer);
        lwkt_serialize_enter(rcvif->if_serializer);
        return 0;
@@ -434,6 +436,7 @@
 {
        struct ifvlan *ifv;
        struct ifnet *rcvif;
+       struct ether_header eh_copy;
 
        rcvif = m->m_pkthdr.rcvif;
        ASSERT_SERIALIZED(rcvif->if_serializer);
@@ -455,20 +458,22 @@
        /*
         * Having found a valid vlan interface corresponding to
         * the given source interface and vlan tag, remove the
-        * encapsulation, and run the real packet through
-        * ether_input() a second time (it had better be
+        * remaining encapsulation (ether_vlan_header minus the ether_header
+        * that had already been removed) and run the real packet
+        * through ether_input() a second time (it had better be
         * reentrant!).
         */
+       eh_copy = *eh;
+       eh_copy.ether_type = mtod(m, u_int16_t *)[1];   /* evl_proto */
        m->m_pkthdr.rcvif = &ifv->ifv_if;
-       eh->ether_type = mtod(m, u_int16_t *)[1];
-       m->m_data += EVL_ENCAPLEN;
-       m->m_len -= EVL_ENCAPLEN;
-       m->m_pkthdr.len -= EVL_ENCAPLEN;
+       m_adj(m, EVL_ENCAPLEN);
+       M_PREPEND(m, ETHER_HDR_LEN, MB_WAIT); 
+       *(struct ether_header *)mtod(m, void *) = eh_copy;
 
        ifv->ifv_if.if_ipackets++;
        lwkt_serialize_exit(rcvif->if_serializer);
        lwkt_serialize_enter(ifv->ifv_if.if_serializer);
-       ether_input(&ifv->ifv_if, eh, m);
+       ether_input(&ifv->ifv_if, NULL, m);
        lwkt_serialize_exit(ifv->ifv_if.if_serializer);
        lwkt_serialize_enter(rcvif->if_serializer);
        return 0;

Reply via email to