[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