[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openbsd-tech
Subject:    Hardware VLAN tag stripping
From:       Christian Weisgerber <naddy () mips ! inka ! de>
Date:       2008-09-30 19:09:04
Message-ID: 20080930190904.GA35068 () lorvorc ! mips ! inka ! de
[Download RAW message or body]

This patch finally makes use of the new mbuf VLAN tag infrastructure.
 
* Allow ether_input() and vlan_input() to handle a packet where
  the tag is stored in the header.
* Switch the existing TX VLAN hardware support over to having the
  tag in the header.
* Make bridge(4) handle interfaces with and without hardware tag
  support and forward packets inbetween.
* bnx, ix, re, txp: convert RX tag stripping to the new way.
* bge, bnx, ix, nfe, nge, re, ti, txp, xge: convert TX tagging.
 
This could use serious eyeballing (especially for corner cases in
if_bridge.c) and testing in setups that involve VLANs in some way.


Note that bpf(4) listeners such as tcpdump(8) don't see out-of-band
tags.  This already applied to the old TX tagging support and will
be addressed in future work.

Index: sys/net/if_bridge.c
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.c,v
retrieving revision 1.172
diff -u -p -r1.172 if_bridge.c
--- sys/net/if_bridge.c	10 Sep 2008 14:01:23 -0000	1.172
+++ sys/net/if_bridge.c	16 Sep 2008 18:30:31 -0000
@@ -35,6 +35,7 @@
 #include "gif.h"
 #include "pf.h"
 #include "carp.h"
+#include "vlan.h"
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -95,6 +96,10 @@
 #include <netinet/ip_carp.h>
 #endif
 
+#if NVLAN > 0
+#include <net/if_vlan_var.h>
+#endif
+
 #include <net/if_bridge.h>
 
 /*
@@ -1354,6 +1359,11 @@ bridgeintr_frame(struct bridge_softc *sc
 #endif
 
 	len = m->m_pkthdr.len;
+#if NVLAN > 0
+	if ((m->m_flags & M_VLANTAG) &&
+	    (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0)
+		len += ETHER_VLAN_ENCAP_LEN;
+#endif
 	if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
 		bridge_fragment(sc, dst_if, &eh, m);
 	else {
@@ -1609,6 +1619,11 @@ bridge_broadcast(struct bridge_softc *sc
 			continue;
 #endif
 
+#if NVLAN > 0
+		if ((mc->m_flags & M_VLANTAG) &&
+		    (dst_if->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0)
+			len += ETHER_VLAN_ENCAP_LEN;
+#endif
 		if ((len - ETHER_HDR_LEN) > dst_if->if_mtu)
 			bridge_fragment(sc, dst_if, eh, mc);
 		else {
@@ -2076,6 +2091,11 @@ bridge_blocknonip(struct ether_header *e
 	if (m->m_pkthdr.len < ETHER_HDR_LEN)
 		return (1);
 
+#if NVLAN > 0
+	if (m->m_flags & M_VLANTAG)
+		return (1);
+#endif
+
 	etype = ntohs(eh->ether_type);
 	switch (etype) {
 	case ETHERTYPE_ARP:
@@ -2412,6 +2432,11 @@ bridge_filter(struct bridge_softc *sc, i
 	int hlen;
 	u_int16_t etype;
 
+#if NVLAN > 0
+	if (m->m_flags & M_VLANTAG)
+		return (m);
+#endif
+
 	etype = ntohs(eh->ether_type);
 
 	if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6) {
@@ -2600,15 +2625,22 @@ bridge_fragment(struct bridge_softc *sc,
 	goto dropit;
 #else
 	etype = ntohs(eh->ether_type);
-	if (etype == ETHERTYPE_VLAN &&
-	    (ifp->if_capabilities & IFCAP_VLAN_MTU) &&
-	    ((m->m_pkthdr.len - sizeof(struct ether_vlan_header)) <=
-	    ifp->if_mtu)) {
-		s = splnet();
-		bridge_ifenqueue(sc, ifp, m);
-		splx(s);
-		return;
+#if NVLAN > 0
+	if ((m->m_flags & M_VLANTAG) || etype == ETHERTYPE_VLAN) {
+		int len = m->m_pkthdr.len;
+
+		if (m->m_flags & M_VLANTAG)
+			len += ETHER_VLAN_ENCAP_LEN;
+		if ((ifp->if_capabilities & IFCAP_VLAN_MTU) &&
+		    (len - sizeof(struct ether_vlan_header) <= ifp->if_mtu)) {
+			s = splnet();
+			bridge_ifenqueue(sc, ifp, m);
+			splx(s);
+			return;
+		}
+		goto dropit;
 	}
+#endif
 	if (etype != ETHERTYPE_IP) {
 		if (etype > ETHERMTU ||
 		    m->m_pkthdr.len < (LLC_SNAPFRAMELEN +
@@ -2702,6 +2734,29 @@ bridge_ifenqueue(struct bridge_softc *sc
 	/* Packet needs etherip encapsulation. */
 	if (ifp->if_type == IFT_GIF)
 		m->m_flags |= M_PROTO1;
+#endif
+#if NVLAN > 0
+	/*
+	 * If the underlying interface cannot do VLAN tag insertion itself,
+	 * create an encapsulation header.
+	 */
+	if ((m->m_flags & M_VLANTAG) &&
+	    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0) {
+		struct ether_vlan_header evh;
+
+		m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&evh);
+		evh.evl_proto = evh.evl_encap_proto;
+		evh.evl_encap_proto = htons(ETHERTYPE_VLAN);
+		evh.evl_tag = htons(m->m_pkthdr.ether_vtag);
+		m_adj(m, ETHER_HDR_LEN);
+		M_PREPEND(m, sizeof(evh), M_DONTWAIT);
+		if (m == NULL) {
+			sc->sc_if.if_oerrors++;
+			return (ENOBUFS);
+		}
+		m_copyback(m, 0, sizeof(evh), &evh);
+		m->m_flags &= ~M_VLANTAG;
+	}
 #endif
 	len = m->m_pkthdr.len;
 	mflags = m->m_flags;
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.124
diff -u -p -r1.124 if_ethersubr.c
--- sys/net/if_ethersubr.c	28 Aug 2008 13:10:54 -0000	1.124
+++ sys/net/if_ethersubr.c	16 Sep 2008 15:46:53 -0000
@@ -573,7 +573,8 @@ ether_input(ifp0, eh, m)
 	}
 
 #if NVLAN > 0
-	if (etype == ETHERTYPE_VLAN && (vlan_input(eh, m) == 0))
+	if (((m->m_flags & M_VLANTAG) || etype == ETHERTYPE_VLAN)
+	    && (vlan_input(eh, m) == 0))
 		return;
 #endif
 
@@ -598,7 +599,7 @@ ether_input(ifp0, eh, m)
 #endif
 
 #if NVLAN > 0
-	if (etype == ETHERTYPE_VLAN) {
+	if ((m->m_flags & M_VLANTAG) || etype == ETHERTYPE_VLAN) {
 		/* The bridge did not want the vlan frame either, drop it. */
 		ifp->if_noproto++;
 		m_freem(m);
Index: sys/net/if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.74
diff -u -p -r1.74 if_vlan.c
--- sys/net/if_vlan.c	2 Sep 2008 17:35:16 -0000	1.74
+++ sys/net/if_vlan.c	16 Sep 2008 15:46:54 -0000
@@ -206,23 +206,12 @@ vlan_start(struct ifnet *ifp)
 		 * If the IFCAP_VLAN_HWTAGGING capability is set on the parent,
 		 * it can do VLAN tag insertion itself and doesn't require us
 	 	 * to create a special header for it. In this case, we just pass
-		 * the packet along. However, we need some way to tell the
-		 * interface where the packet came from so that it knows how
-		 * to find the VLAN tag to use, so we set the rcvif in the
-		 * mbuf header to our ifnet.
-		 *
-		 * Note: we also set the M_PROTO1 flag in the mbuf to let
-		 * the parent driver know that the rcvif pointer is really
-		 * valid. We need to do this because sometimes mbufs will
-		 * be allocated by other parts of the system that contain
-		 * garbage in the rcvif pointer. Using the M_PROTO1 flag
-		 * lets the driver perform a proper sanity check and avoid
-		 * following potentially bogus rcvif pointers off into
-		 * never-never land.
+		 * the packet along.
 		 */
 		if (p->if_capabilities & IFCAP_VLAN_HWTAGGING) {
-			m->m_pkthdr.rcvif = ifp;
-			m->m_flags |= M_PROTO1;
+			m->m_pkthdr.ether_vtag = ifv->ifv_tag +
+			    (ifv->ifv_prio << EVL_PRIO_BITS);
+			m->m_flags |= M_VLANTAG;
 		} else {
 			struct ether_vlan_header evh;
 
@@ -276,13 +265,17 @@ vlan_input(eh, m)
 	u_int tag;
 	struct ifnet *ifp = m->m_pkthdr.rcvif;
 
-	if (m->m_len < EVL_ENCAPLEN &&
-	    (m = m_pullup(m, EVL_ENCAPLEN)) == NULL) {
-		ifp->if_ierrors++;
-		return (0);
-	}
+	if (m->m_flags & M_VLANTAG) {
+		tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
+	} else {
+		if (m->m_len < EVL_ENCAPLEN &&
+		    (m = m_pullup(m, EVL_ENCAPLEN)) == NULL) {
+			ifp->if_ierrors++;
+			return (0);
+		}
 
-	tag = EVL_VLANOFTAG(ntohs(*mtod(m, u_int16_t *)));
+		tag = EVL_VLANOFTAG(ntohs(*mtod(m, u_int16_t *)));
+	}
 
 	LIST_FOREACH(ifv, &vlan_tagh[TAG_HASH(tag)], ifv_list) {
 		if (m->m_pkthdr.rcvif == ifv->ifv_p && tag == ifv->ifv_tag)
@@ -305,10 +298,14 @@ vlan_input(eh, m)
 	 * reentrant!).
 	 */
 	m->m_pkthdr.rcvif = &ifv->ifv_if;
-	eh->ether_type = mtod(m, u_int16_t *)[1];
-	m->m_len -= EVL_ENCAPLEN;
-	m->m_data += EVL_ENCAPLEN;
-	m->m_pkthdr.len -= EVL_ENCAPLEN;
+	if (m->m_flags & M_VLANTAG) {
+		m->m_flags &= ~M_VLANTAG;
+	} else {
+		eh->ether_type = mtod(m, u_int16_t *)[1];
+		m->m_len -= EVL_ENCAPLEN;
+		m->m_data += EVL_ENCAPLEN;
+		m->m_pkthdr.len -= EVL_ENCAPLEN;
+	}
 
 #if NBPFILTER > 0
 	if (ifv->ifv_if.if_bpf)
Index: sys/dev/ic/re.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/re.c,v
retrieving revision 1.90
diff -u -p -r1.90 re.c
--- sys/dev/ic/re.c	10 Sep 2008 14:01:22 -0000	1.90
+++ sys/dev/ic/re.c	16 Sep 2008 15:46:27 -0000
@@ -1416,6 +1416,13 @@ re_rxeof(struct rl_softc *sc)
 				m->m_pkthdr.csum_flags |= M_TCP_CSUM_IN_OK |
 				    M_UDP_CSUM_IN_OK;
 		}
+#if NVLAN > 0
+		if (rxvlan & RL_RDESC_VLANCTL_TAG) {
+			m->m_pkthdr.ether_vtag =
+			    ntohs((rxvlan & RL_RDESC_VLANCTL_DATA));
+			m->m_flags |= M_VLANTAG;
+		}
+#endif
 
 #if NBPFILTER > 0
 		if (ifp->if_bpf)
@@ -1590,13 +1597,6 @@ re_encap(struct rl_softc *sc, struct mbu
 	struct rl_desc	*d;
 	u_int32_t	cmdstat, vlanctl = 0, csum_flags = 0;
 	struct rl_txq	*txq;
-#if NVLAN > 0
-	struct ifvlan	*ifv = NULL;
-
-	if ((m->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    m->m_pkthdr.rcvif != NULL)
-		ifv = m->m_pkthdr.rcvif->if_softc;
-#endif
 
 	if (sc->rl_ldata.rl_tx_free <= RL_NTXDESC_RSVD)
 		return (EFBIG);
@@ -1669,8 +1669,9 @@ re_encap(struct rl_softc *sc, struct mbu
 	 * transmission attempt.
 	 */
 #if NVLAN > 0
-	if (ifv != NULL)
-		vlanctl |= swap16(ifv->ifv_tag) | RL_TDESC_VLANCTL_TAG;
+	if (m->m_flags & M_VLANTAG)
+		vlanctl |= swap16(m->m_pkthdr.ether_vtag) |
+		    RL_TDESC_VLANCTL_TAG;
 #endif
 
 	/*
@@ -1878,6 +1879,8 @@ re_init(struct ifnet *ifp)
 	cfg = RL_CPLUSCMD_PCI_MRW;
 	if (ifp->if_capabilities & IFCAP_CSUM_IPv4)
 		cfg |= RL_CPLUSCMD_RXCSUM_ENB;
+	if (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)
+		cfg |= RL_CPLUSCMD_VLANSTRIP;
 	if (sc->rl_flags & RL_FLAG_MACSTAT) {
 		cfg |= RL_CPLUSCMD_MACSTAT_DIS;
 		/* XXX magic. */
Index: sys/dev/pci/if_bge.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.243
diff -u -p -r1.243 if_bge.c
--- sys/dev/pci/if_bge.c	10 Sep 2008 14:01:22 -0000	1.243
+++ sys/dev/pci/if_bge.c	16 Sep 2008 15:46:35 -0000
@@ -2874,13 +2874,6 @@ bge_encap(struct bge_softc *sc, struct m
 	struct txdmamap_pool_entry *dma;
 	bus_dmamap_t dmamap;
 	int			i = 0;
-#if NVLAN > 0
-	struct ifvlan		*ifv = NULL;
-
-	if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    m_head->m_pkthdr.rcvif != NULL)
-		ifv = m_head->m_pkthdr.rcvif->if_softc;
-#endif
 
 	cur = frag = *txidx;
 
@@ -2940,9 +2933,9 @@ doit:
 		f->bge_len = dmamap->dm_segs[i].ds_len;
 		f->bge_flags = csum_flags;
 #if NVLAN > 0
-		if (ifv != NULL) {
+		if (m_head->m_flags & M_VLANTAG) {
 			f->bge_flags |= BGE_TXBDFLAG_VLAN_TAG;
-			f->bge_vlan_tag = ifv->ifv_tag;
+			f->bge_vlan_tag = m_head->m_pkthdr.ether_vtag;
 		} else {
 			f->bge_vlan_tag = 0;
 		}
Index: sys/dev/pci/if_bnx.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bnx.c,v
retrieving revision 1.65
diff -u -p -r1.65 if_bnx.c
--- sys/dev/pci/if_bnx.c	10 Sep 2008 14:01:22 -0000	1.65
+++ sys/dev/pci/if_bnx.c	16 Sep 2008 15:46:35 -0000
@@ -4014,26 +4014,14 @@ bnx_rx_intr(struct bnx_softc *sc)
 			if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
 			    !(sc->rx_mode & BNX_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
 #if NVLAN > 0
-				struct ether_vlan_header vh;
-
 				DBPRINT(sc, BNX_VERBOSE_SEND,
 				    "%s(): VLAN tag = 0x%04X\n",
 				    __FUNCTION__,
 				    l2fhdr->l2_fhdr_vlan_tag);
 
-				if (m->m_pkthdr.len < ETHER_HDR_LEN) {
-					m_freem(m);
-					goto bnx_rx_int_next_rx;
-				}
-				m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&vh);
-				vh.evl_proto = vh.evl_encap_proto;
-				vh.evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
-				vh.evl_encap_proto = htons(ETHERTYPE_VLAN);
-				m_adj(m, ETHER_HDR_LEN);
-				M_PREPEND(m, sizeof(vh), M_DONTWAIT);
-				if (m == NULL)
-					goto bnx_rx_int_next_rx;
-				m_copyback(m, 0, sizeof(vh), &vh);
+				m->m_pkthdr.ether_vtag =
+				    l2fhdr->l2_fhdr_vlan_tag;
+				m->m_flags |= M_VLANTAG;
 #else
 				m_freem(m);
 				goto bnx_rx_int_next_rx;
@@ -4400,11 +4388,9 @@ bnx_tx_encap(struct bnx_softc *sc, struc
 
 #if NVLAN > 0
 	/* Transfer any VLAN tags to the bd. */
-	if ((m0->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    m0->m_pkthdr.rcvif != NULL) {
-		struct ifvlan *ifv = m0->m_pkthdr.rcvif->if_softc;
+	if (m0->m_flags & M_VLANTAG) {
 		flags |= TX_BD_FLAGS_VLAN_TAG;
-		vlan_tag = ifv->ifv_tag;
+		vlan_tag = m0->m_pkthdr.ether_vtag;
 	}
 #endif
 
Index: sys/dev/pci/if_ix.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ix.c,v
retrieving revision 1.8
diff -u -p -r1.8 if_ix.c
--- sys/dev/pci/if_ix.c	10 Sep 2008 14:01:22 -0000	1.8
+++ sys/dev/pci/if_ix.c	16 Sep 2008 15:46:36 -0000
@@ -848,9 +848,7 @@ ixgbe_encap(struct tx_ring *txr, struct 
         cmd_type_len |= IXGBE_ADVTXD_DCMD_IFCS | IXGBE_ADVTXD_DCMD_DEXT;
 
 #if NVLAN > 0
-	/* VLAN tagging? */
-	if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    m_head->m_pkthdr.rcvif != NULL)
+	if (m_head->m_flags & M_VLANTAG)
         	cmd_type_len |= IXGBE_ADVTXD_DCMD_VLE;
 #endif
 
@@ -1895,11 +1893,6 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, 
 	int ctxd = txr->next_avail_tx_desc;
 #if NVLAN > 0
 	struct ether_vlan_header *eh;
-	struct ifvlan		*ifv = NULL;
-
-	if ((mp->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    mp->m_pkthdr.rcvif != NULL)
-		ifv = mp->m_pkthdr.rcvif->if_softc;
 #else
 	struct ether_header *eh;
 #endif
@@ -1915,9 +1908,9 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, 
 	 * be placed into the descriptor itself.
 	 */
 #if NVLAN > 0
-	if (ifv != NULL) {
+	if (mp->m_flags & M_VLANTAG) {
 		vlan_macip_lens |=
-		    htole16(ifv->ifv_tag) << IXGBE_ADVTXD_VLAN_SHIFT;
+		    htole16(mp->m_pkthdr.ether_vtag) << IXGBE_ADVTXD_VLAN_SHIFT;
 	} else
 #endif
 	if (offload == FALSE)
@@ -2028,12 +2021,6 @@ ixgbe_tso_setup(struct tx_ring *txr, str
 #if NVLAN > 0
 	uint16_t vtag = 0;
 	struct ether_vlan_header *eh;
-
-	struct ifvlan		*ifv = NULL;
-
-	if ((mp->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    mp->m_pkthdr.rcvif != NULL)
-		ifv = mp->m_pkthdr.rcvif->if_softc;
 #else
 	struct ether_header *eh;
 #endif
@@ -2083,9 +2070,9 @@ ixgbe_tso_setup(struct tx_ring *txr, str
 
 #if NVLAN > 0
 	/* VLAN MACLEN IPLEN */
-	if (ifv != NULL) {
+	if (mp->m_flags & M_VLANTAG) {
 		vtag = htole16(mp->m_pkthdr.ether_vtag);
-                vlan_macip_lens |= (ifv->ifv_tag << IXGBE_ADVTXD_VLAN_SHIFT);
+		vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT);
 	}
 #endif
 
@@ -2798,22 +2785,9 @@ ixgbe_rxeof(struct rx_ring *rxr, int cou
 
 #if NVLAN > 0 && defined(IX_CSUM_OFFLOAD)
 				if (staterr & IXGBE_RXD_STAT_VP) {
-					struct ether_vlan_header vh;
-
-					if (m->m_pkthdr.len < ETHER_HDR_LEN)
-						goto discard;
-					m_copydata(m, 0,
-					    ETHER_HDR_LEN, (caddr_t)&vh);
-					vh.evl_proto = vh.evl_encap_proto;
-					vh.evl_tag =
+					m->m_pkthdr.ether_vtag =
 					    letoh16(cur->wb.upper.vlan);
-					vh.evl_encap_proto =
-					    htons(ETHERTYPE_VLAN);
-					m_adj(m, ETHER_HDR_LEN);
-					M_PREPEND(m, sizeof(vh), M_DONTWAIT);
-					if (m == NULL)
-						goto discard;
-					m_copyback(m, 0, sizeof(vh), &vh);
+					m->m_flags |= M_VLANTAG;
 				}
 #endif
 				rxr->fmp = NULL;
Index: sys/dev/pci/if_nfe.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_nfe.c,v
retrieving revision 1.81
diff -u -p -r1.81 if_nfe.c
--- sys/dev/pci/if_nfe.c	10 Sep 2008 14:01:22 -0000	1.81
+++ sys/dev/pci/if_nfe.c	16 Sep 2008 15:46:36 -0000
@@ -939,11 +939,8 @@ nfe_encap(struct nfe_softc *sc, struct m
 
 #if NVLAN > 0
 	/* setup h/w VLAN tagging */
-	if ((m0->m_flags & (M_PROTO1 | M_PKTHDR)) == (M_PROTO1 | M_PKTHDR) &&
-	    m0->m_pkthdr.rcvif != NULL) {
-		struct ifvlan *ifv = m0->m_pkthdr.rcvif->if_softc;
-		vtag = NFE_TX_VTAG | htons(ifv->ifv_tag);
-	}
+	if (m0->m_flags & M_VLANTAG)
+		vtag = NFE_TX_VTAG | htons(m0->m_pkthdr.ether_vtag);
 #endif
 	if (m0->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
 		flags |= NFE_TX_IP_CSUM;
Index: sys/dev/pci/if_nge.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_nge.c,v
retrieving revision 1.58
diff -u -p -r1.58 if_nge.c
--- sys/dev/pci/if_nge.c	23 May 2008 08:49:27 -0000	1.58
+++ sys/dev/pci/if_nge.c	26 Aug 2008 16:37:05 -0000
@@ -1593,13 +1593,6 @@ nge_encap(sc, m_head, txidx)
 	struct nge_desc		*f = NULL;
 	struct mbuf		*m;
 	int			frag, cur, cnt = 0;
-#if NVLAN > 0
-	struct ifvlan		*ifv = NULL;
-
-	if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    m_head->m_pkthdr.rcvif != NULL)
-		ifv = m_head->m_pkthdr.rcvif->if_softc;
-#endif
 
 	/*
 	 * Start packing the mbufs in this chain into
@@ -1633,9 +1626,9 @@ nge_encap(sc, m_head, txidx)
 	sc->nge_ldata->nge_tx_list[*txidx].nge_extsts = 0;
 
 #if NVLAN > 0
-	if (ifv != NULL) {
+	if (m_head->m_flags & M_VLANTAG) {
 		sc->nge_ldata->nge_tx_list[cur].nge_extsts |=
-			(NGE_TXEXTSTS_VLANPKT|ifv->ifv_tag);
+		    (NGE_TXEXTSTS_VLANPKT|htons(m_head->m_pkthdr.ether_vtag));
 	}
 #endif
 
Index: sys/dev/pci/if_ti.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_ti.c,v
retrieving revision 1.85
diff -u -p -r1.85 if_ti.c
--- sys/dev/pci/if_ti.c	7 Jun 2008 19:03:13 -0000	1.85
+++ sys/dev/pci/if_ti.c	29 Aug 2008 15:11:38 -0000
@@ -2029,13 +2029,6 @@ ti_encap_tigon1(struct ti_softc *sc, str
 	bus_dmamap_t		txmap;
 	struct ti_tx_desc	txdesc;
 	int			i = 0;
-#if NVLAN > 0
-	struct ifvlan		*ifv = NULL;
-
-	if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    m_head->m_pkthdr.rcvif != NULL)
-		ifv = m_head->m_pkthdr.rcvif->if_softc;
-#endif
 
 	entry = SLIST_FIRST(&sc->ti_tx_map_listhead);
 	if (entry == NULL)
@@ -2064,9 +2057,9 @@ ti_encap_tigon1(struct ti_softc *sc, str
 
 		txdesc.ti_flags = 0;
 #if NVLAN > 0
-		if (ifv != NULL) {
+		if (m_head->m_flags & M_VLANTAG) {
 			txdesc.ti_flags |= TI_BDFLAG_VLAN_TAG;
-			txdesc.ti_vlan_tag = ifv->ifv_tag;
+			txdesc.ti_vlan_tag = m_head->m_pkthdr.ether_vtag;
 		}
 #endif
 
@@ -2116,13 +2109,6 @@ ti_encap_tigon2(struct ti_softc *sc, str
 	struct ti_txmap_entry	*entry;
 	bus_dmamap_t		txmap;
 	int			i = 0;
-#if NVLAN > 0
-	struct ifvlan		*ifv = NULL;
-
-	if ((m_head->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-	    m_head->m_pkthdr.rcvif != NULL)
-		ifv = m_head->m_pkthdr.rcvif->if_softc;
-#endif
 
 	entry = SLIST_FIRST(&sc->ti_tx_map_listhead);
 	if (entry == NULL)
@@ -2150,9 +2136,9 @@ ti_encap_tigon2(struct ti_softc *sc, str
 		f->ti_len = txmap->dm_segs[i].ds_len & 0xffff;
 		f->ti_flags = 0;
 #if NVLAN > 0
-		if (ifv != NULL) {
+		if (m_head->m_flags & M_VLANTAG) {
 			f->ti_flags |= TI_BDFLAG_VLAN_TAG;
-			f->ti_vlan_tag = ifv->ifv_tag;
+			f->ti_vlan_tag = m_head->m_pkthdr.ether_vtag;
 		} else {
 			f->ti_vlan_tag = 0;
 		}
Index: sys/dev/pci/if_txp.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_txp.c,v
retrieving revision 1.93
diff -u -p -r1.93 if_txp.c
--- sys/dev/pci/if_txp.c	10 Sep 2008 14:01:23 -0000	1.93
+++ sys/dev/pci/if_txp.c	16 Sep 2008 15:46:37 -0000
@@ -640,31 +641,6 @@ txp_rx_reclaim(struct txp_softc *sc, str
 		free(sd, M_DEVBUF);
 		m->m_pkthdr.len = m->m_len = letoh16(rxd->rx_len);
 
-#if NVLAN > 0
-		/*
-		 * XXX Another firmware bug: the vlan encapsulation
-		 * is always removed, even when we tell the card not
-		 * to do that.  Restore the vlan encapsulation below.
-		 */
-		if (rxd->rx_stat & htole32(RX_STAT_VLAN)) {
-			struct ether_vlan_header vh;
-
-			if (m->m_pkthdr.len < ETHER_HDR_LEN) {
-				m_freem(m);
-				goto next;
-			}
-			m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&vh);
-			vh.evl_proto = vh.evl_encap_proto;
-			vh.evl_tag = rxd->rx_vlan >> 16;
-			vh.evl_encap_proto = htons(ETHERTYPE_VLAN);
-			m_adj(m, ETHER_HDR_LEN);
-			M_PREPEND(m, sizeof(vh), M_DONTWAIT);
-			if (m == NULL)
-				goto next;
-			m_copyback(m, 0, sizeof(vh), &vh);
-		}
-#endif
-
 #ifdef __STRICT_ALIGNMENT
 		{
 			/*
@@ -697,6 +673,18 @@ txp_rx_reclaim(struct txp_softc *sc, str
 		}
 #endif
 
+#if NVLAN > 0
+		/*
+		 * XXX Another firmware bug: the vlan encapsulation
+		 * is always removed, even when we tell the card not
+		 * to do that.  Restore the vlan encapsulation below.
+		 */
+		if (rxd->rx_stat & htole32(RX_STAT_VLAN)) {
+			m->m_pkthdr.ether_vtag = ntohs(rxd->rx_vlan >> 16);
+			m->m_flags |= M_VLANTAG;
+		}
+#endif
+
 #if NBPFILTER > 0
 		/*
 		 * Handle BPF listeners. Let the BPF user see the packet.
@@ -774,10 +762,8 @@ txp_rxbuf_reclaim(struct txp_softc *sc)
 		MCLGET(sd->sd_mbuf, M_DONTWAIT);
 		if ((sd->sd_mbuf->m_flags & M_EXT) == 0)
 			goto err_mbuf;
-		/* reserve some space for a possible VLAN header */
-		sd->sd_mbuf->m_data += 8;
-		sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES - 8;
 		sd->sd_mbuf->m_pkthdr.rcvif = ifp;
+		sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES;
 		if (bus_dmamap_create(sc->sc_dmat, TXP_MAX_PKTLEN, 1,
 		    TXP_MAX_PKTLEN, 0, BUS_DMA_NOWAIT, &sd->sd_map))
 			goto err_mbuf;
@@ -1058,9 +1044,7 @@ txp_alloc_rings(struct txp_softc *sc)
 		if ((sd->sd_mbuf->m_flags & M_EXT) == 0) {
 			goto bail_rxbufring;
 		}
-		/* reserve some space for a possible VLAN header */
-		sd->sd_mbuf->m_data += 8;
-		sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES - 8;
+		sd->sd_mbuf->m_pkthdr.len = sd->sd_mbuf->m_len = MCLBYTES;
 		sd->sd_mbuf->m_pkthdr.rcvif = ifp;
 		if (bus_dmamap_create(sc->sc_dmat, TXP_MAX_PKTLEN, 1,
 		    TXP_MAX_PKTLEN, 0, BUS_DMA_NOWAIT, &sd->sd_map)) {
@@ -1351,9 +1335,6 @@ txp_start(struct ifnet *ifp)
 	struct mbuf *m, *mnew;
 	struct txp_swdesc *sd;
 	u_int32_t firstprod, firstcnt, prod, cnt, i;
-#if NVLAN > 0
-	struct ifvlan		*ifv;
-#endif
 
 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
 		return;
@@ -1415,11 +1396,9 @@ txp_start(struct ifnet *ifp)
 			goto oactive;
 
 #if NVLAN > 0
-		if ((m->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-		    m->m_pkthdr.rcvif != NULL) {
-			ifv = m->m_pkthdr.rcvif->if_softc;
+		if (m->m_flags & M_VLANTAG) {
 			txd->tx_pflags = TX_PFLAGS_VLAN |
-			    (htons(ifv->ifv_tag) << TX_PFLAGS_VLANTAG_S);
+			    (htons(m->m_pkthdr.ether_vtag) << TX_PFLAGS_VLANTAG_S);
 		}
 #endif
 
Index: sys/dev/pci/if_xge.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_xge.c,v
retrieving revision 1.43
diff -u -p -r1.43 if_xge.c
--- sys/dev/pci/if_xge.c	19 Sep 2007 03:50:25 -0000	1.43
+++ sys/dev/pci/if_xge.c	26 Aug 2008 16:58:07 -0000
@@ -1105,9 +1105,6 @@ xge_start(struct ifnet *ifp)
 	struct	mbuf *m;
 	uint64_t par, lcr;
 	int nexttx = 0, ntxd, error, i;
-#if NVLAN > 0
-	struct ifvlan *ifv = NULL;
-#endif
 
 	if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
 		return;
@@ -1151,12 +1148,10 @@ xge_start(struct ifnet *ifp)
 		txd->txd_control2 = TXD_CTL2_UTIL;
 
 #if NVLAN > 0
-		if ((m->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
-		    m->m_pkthdr.rcvif != NULL) {
-			ifv = m->m_pkthdr.rcvif->if_softc;
-
+		if (m->m_flags & M_VLANTAG) {
 			txd->txd_control2 |= TXD_CTL2_VLANE;
-			txd->txd_control2 |= TXD_CTL2_VLANT(ifv->ifv_tag);
+			txd->txd_control2 |=
+			    TXD_CTL2_VLANT(m->m_pkthdr.ether_vtag);
 		}
 #endif
 
-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic