Move ethernet VLAN tags from mtags to its own mbuf packet header field

m_pkthdr.ether_vlan.  The presence of the M_VLANTAG flag on the mbuf
signifies the presence and validity of its content.

Drivers that support hardware VLAN tag stripping fill in the received
VLAN tag (containing both vlan and priority information) into the
ether_vtag mbuf packet header field:

	m->m_pkthdr.ether_vtag = vlan_id;	/* ntohs()? */
	m->m_flags |= M_VLANTAG;

to mark the packet m with the specified VLAN tag.

On output the driver should check the mbuf for the M_VLANTAG flag to
see if a VLAN tag is present and valid:

	if (m->m_flags & M_VLANTAG) {
		... = m->m_pkthdr.ether_vtag;	/* htons()? */
		... pass tag to hardware ...
	}

VLAN tags are stored in host byte order.  Byte swapping may be necessary.

(Note: This driver conversion was mechanic and did not add or remove any
byte swapping in the drivers.)

Remove zone_mtag_vlan UMA zone and MTAG_VLAN definition.  No more tag
memory allocation have to be done.

Reviewed by:	thompsa, yar
Sponsored by:	TCP/IP Optimization Fundraise 2005
This commit is contained in:
andre 2006-09-17 13:33:30 +00:00
parent 9f40438221
commit 2d9e7e4a32
17 changed files with 97 additions and 171 deletions

View File

@ -4251,9 +4251,8 @@ bce_rx_intr(struct bce_softc *sc)
#if __FreeBSD_version < 700000
VLAN_INPUT_TAG(ifp, m, l2fhdr->l2_fhdr_vlan_tag, continue);
#else
VLAN_INPUT_TAG(ifp, m, l2fhdr->l2_fhdr_vlan_tag);
if (m == NULL)
continue;
m->m_pkthdr.ether_vtag = l2fhdr->l2_fhdr_vlan_tag;
m->m_flags |= M_VLANTAG;
#endif
}
@ -4600,7 +4599,6 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf *m_head, u16 *prod,
u16 *chain_prod, u32 *prod_bseq)
{
u32 vlan_tag_flags = 0;
struct m_tag *mtag;
struct bce_dmamap_arg map_arg;
bus_dmamap_t map;
int i, error, rc = 0;
@ -4614,10 +4612,9 @@ bce_tx_encap(struct bce_softc *sc, struct mbuf *m_head, u16 *prod,
}
/* Transfer any VLAN tags to the bd. */
mtag = VLAN_OUTPUT_TAG(sc->bce_ifp, m_head);
if (mtag != NULL)
if (m_head->m_flags & M_VLANTAG)
vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG |
(VLAN_TAG_VALUE(mtag) << 16));
(m_head->m_pkthdr.ether_vtag << 16));
/* Map the mbuf into DMAable memory. */
map = sc->tx_mbuf_map[*chain_prod];

View File

@ -2716,9 +2716,8 @@ bge_rxeof(struct bge_softc *sc)
* attach that information to the packet.
*/
if (have_tag) {
VLAN_INPUT_TAG(ifp, m, vlan_tag);
if (m == NULL)
continue;
m->m_pkthdr.ether_vtag = vlan_tag;
m->m_flags |= M_VLANTAG;
}
BGE_UNLOCK(sc);
@ -3078,7 +3077,6 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
bus_dmamap_t map;
struct bge_tx_bd *d;
struct mbuf *m = *m_head;
struct m_tag *mtag;
uint32_t idx = *txidx;
uint16_t csum_flags;
int nsegs, i, error;
@ -3150,9 +3148,9 @@ bge_encap(struct bge_softc *sc, struct mbuf **m_head, uint32_t *txidx)
/* ... and put VLAN tag into first segment. */
d = &sc->bge_ldata.bge_tx_ring[*txidx];
if ((mtag = VLAN_OUTPUT_TAG(sc->bge_ifp, m)) != NULL) {
if (m->m_flags & M_VLANTAG) {
d->bge_flags |= BGE_TXBDFLAG_VLAN_TAG;
d->bge_vlan_tag = VLAN_TAG_VALUE(mtag);
d->bge_vlan_tag = m->m_pkthdr.ether_vtag;
} else
d->bge_vlan_tag = 0;

View File

@ -1447,7 +1447,6 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp)
struct em_buffer *tx_buffer, *tx_buffer_last;
struct em_tx_desc *current_tx_desc;
struct mbuf *m_head;
struct m_tag *mtag;
uint32_t txd_upper, txd_lower, txd_used, txd_saved;
int nsegs, i, j;
int error, do_tso, tso_desc = 0;
@ -1470,16 +1469,13 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp)
}
}
/* Find out if we are in vlan mode. */
mtag = VLAN_OUTPUT_TAG(ifp, m_head);
/*
* When operating in promiscuous mode, hardware encapsulation for
* packets is disabled. This means we have to add the vlan
* encapsulation in the driver, since it will have come down from the
* VLAN layer with a tag instead of a VLAN header.
*/
if (mtag != NULL && adapter->em_insert_vlan_header) {
if ((m_head->m_flags & M_VLANTAG) && adapter->em_insert_vlan_header) {
struct ether_vlan_header *evl;
struct ether_header eh;
@ -1503,9 +1499,7 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp)
bcopy(&eh, evl, sizeof(*evl));
evl->evl_proto = evl->evl_encap_proto;
evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
evl->evl_tag = htons(VLAN_TAG_VALUE(mtag));
m_tag_delete(m_head, mtag);
mtag = NULL;
evl->evl_tag = htons(m_head->m_pkthdr.ether_vtag);
*m_headp = m_head;
}
@ -1681,10 +1675,10 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp)
adapter->num_tx_desc_avail -= txd_used;
}
if (mtag != NULL) {
if (m_head->m_flags & M_VLANTAG) {
/* Set the vlan id. */
current_tx_desc->upper.fields.special =
htole16(VLAN_TAG_VALUE(mtag));
htole16(m_head->m_pkthdr.ether_vtag);
/* Tell hardware to add tag. */
current_tx_desc->lower.data |= htole32(E1000_TXD_CMD_VLE);
@ -3400,9 +3394,10 @@ em_rxeof(struct adapter *adapter, int count)
goto skip;
#endif
if (status & E1000_RXD_STAT_VP)
VLAN_INPUT_TAG(ifp, adapter->fmp,
adapter->fmp->m_pkthdr.ether_vtag =
(le16toh(current_desc->special) &
E1000_RXD_SPC_VLAN_MASK));
E1000_RXD_SPC_VLAN_MASK);
adapter->fmp->m_flags |= M_VLANTAG;
#ifndef __NO_STRICT_ALIGNMENT
skip:
#endif

View File

@ -926,8 +926,6 @@ ixgb_encap(struct adapter * adapter, struct mbuf * m_head)
#if __FreeBSD_version < 500000
struct ifvlan *ifv = NULL;
#else
struct m_tag *mtag;
#endif
bus_dma_segment_t segs[IXGB_MAX_SCATTER];
bus_dmamap_t map;
@ -981,7 +979,7 @@ ixgb_encap(struct adapter * adapter, struct mbuf * m_head)
m_head->m_pkthdr.rcvif != NULL &&
m_head->m_pkthdr.rcvif->if_type == IFT_L2VLAN)
ifv = m_head->m_pkthdr.rcvif->if_softc;
#else
#elseif __FreeBSD_version < 700000
mtag = VLAN_OUTPUT_TAG(ifp, m_head);
#endif
i = adapter->next_avail_tx_desc;
@ -1005,10 +1003,13 @@ ixgb_encap(struct adapter * adapter, struct mbuf * m_head)
if (ifv != NULL) {
/* Set the vlan id */
current_tx_desc->vlan = ifv->ifv_tag;
#else
#elseif __FreeBSD_version < 700000
if (mtag != NULL) {
/* Set the vlan id */
current_tx_desc->vlan = VLAN_TAG_VALUE(mtag);
#else
if (m_head->m_flags & M_VLANTAG) {
current_tx_desc->vlan = m_head->m_pkthdr.ether_vtag;
#endif
/* Tell hardware to add tag */
@ -2151,9 +2152,17 @@ ixgb_process_receive_interrupts(struct adapter * adapter, int count)
#else
ixgb_receive_checksum(adapter, current_desc,
adapter->fmp);
#if __FreeBSD_version < 700000
if (current_desc->status & IXGB_RX_DESC_STATUS_VP)
VLAN_INPUT_TAG(ifp, adapter->fmp,
current_desc->special);
#else
if (current_desc->status & IXGB_RX_DESC_STATUS_VP) {
adapter->fmp->m_pkthdr.ether_vtag =
current_desc->special;
adapter->fmp->m_flags |= M_VLANTAG;
}
#endif
if (adapter->fmp != NULL) {
IXGB_UNLOCK(adapter);

View File

@ -1482,9 +1482,8 @@ static void nfe_rxeof(struct nfe_softc *sc)
#if NVLAN > 1
if (have_tag) {
VLAN_INPUT_TAG_NEW(ifp, m, vlan_tag);
if (m == NULL)
continue;
m->m_pkthdr.ether_vtag = vlan_tag;
m->m_flags |= M_VLANTAG;
}
#endif
@ -1604,9 +1603,6 @@ static int nfe_encap(struct nfe_softc *sc, struct mbuf *m0)
struct nfe_tx_data *data=NULL;
bus_dmamap_t map;
u_int16_t flags = NFE_TX_VALID;
#if NVLAN > 0
struct m_tag *vtag;
#endif
bus_dma_segment_t segs[NFE_MAX_SCATTER];
int nsegs;
int error, i;
@ -1628,11 +1624,6 @@ static int nfe_encap(struct nfe_softc *sc, struct mbuf *m0)
}
#if NVLAN > 0
/* setup h/w VLAN tagging */
vtag = VLAN_OUTPUT_TAG(sc->nfe_ifp, m0);
#endif
#ifdef NFE_CSUM
if (m0->m_pkthdr.csum_flags & CSUM_IP)
flags |= NFE_TX_IP_CSUM;
@ -1655,8 +1646,9 @@ static int nfe_encap(struct nfe_softc *sc, struct mbuf *m0)
desc64->length = htole16(segs[i].ds_len - 1);
desc64->flags = htole16(flags);
#if NVLAN > 0
desc64->vtag = htole32(NFE_TX_VTAG |
VLAN_TAG_VALUE(vtag));
if (m0->m_flags & M_VLANTAG)
desc64->vtag = htole32(NFE_TX_VTAG |
m0->m_pkthdr.ether_vtag);
#endif
} else {
desc32 = &sc->txq.desc32[sc->txq.cur];
@ -1669,9 +1661,6 @@ static int nfe_encap(struct nfe_softc *sc, struct mbuf *m0)
/* csum flags and vtag belong to the first fragment only */
if (nsegs > 1) {
flags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_CSUM);
#if NVLAN > 0
vtag = 0;
#endif
}
sc->txq.queued++;

View File

@ -1227,10 +1227,9 @@ nge_rxeof(sc)
* to vlan_input() instead of ether_input().
*/
if (extsts & NGE_RXEXTSTS_VLANPKT) {
VLAN_INPUT_TAG(ifp, m,
ntohs(extsts & NGE_RXEXTSTS_VTCI));
if (m == NULL)
continue;
m->m_pkthdr.ether_vtag =
ntohs(extsts & NGE_RXEXTSTS_VTCI);
m->m_flags |= M_VLANTAG;
}
NGE_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
@ -1507,7 +1506,6 @@ nge_encap(sc, m_head, txidx)
struct nge_desc *f = NULL;
struct mbuf *m;
int frag, cur, cnt = 0;
struct m_tag *mtag;
/*
* Start packing the mbufs in this chain into
@ -1549,10 +1547,9 @@ nge_encap(sc, m_head, txidx)
NGE_TXEXTSTS_UDPCSUM;
}
mtag = VLAN_OUTPUT_TAG(sc->nge_ifp, m_head);
if (mtag != NULL) {
if (m_head->m_flags & M_VLANTAG) {
sc->nge_ldata->nge_tx_list[cur].nge_extsts |=
(NGE_TXEXTSTS_VLANPKT|htons(VLAN_TAG_VALUE(mtag)));
(NGE_TXEXTSTS_VLANPKT|htons(m_head->m_pkthdr.ether_vtag));
}
sc->nge_ldata->nge_tx_list[cur].nge_mbuf = m_head;

View File

@ -1726,10 +1726,9 @@ re_rxeof(sc)
}
maxpkt--;
if (rxvlan & RL_RDESC_VLANCTL_TAG) {
VLAN_INPUT_TAG(ifp, m,
ntohs((rxvlan & RL_RDESC_VLANCTL_DATA)));
if (m == NULL)
continue;
m->m_pkthdr.ether_vtag =
ntohs((rxvlan & RL_RDESC_VLANCTL_DATA));
m->m_flags |= M_VLANTAG;
}
RL_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
@ -2007,7 +2006,6 @@ re_encap(sc, m_head, idx)
struct rl_dmaload_arg arg;
bus_dmamap_t map;
int error;
struct m_tag *mtag;
RL_LOCK_ASSERT(sc);
@ -2118,11 +2116,10 @@ re_encap(sc, m_head, idx)
* appear in the first descriptor of a multi-descriptor
* transmission attempt.
*/
mtag = VLAN_OUTPUT_TAG(sc->rl_ifp, *m_head);
if (mtag != NULL)
if ((*m_head)->m_flags & M_VLANTAG)
sc->rl_ldata.rl_tx_list[*idx].rl_vlanctl =
htole32(htons(VLAN_TAG_VALUE(mtag)) | RL_TDESC_VLANCTL_TAG);
htole32(htons((*m_head)->m_pkthdr.ether_vtag) |
RL_TDESC_VLANCTL_TAG);
/* Transfer ownership of packet to the chip. */

View File

@ -1207,7 +1207,6 @@ stge_encap(struct stge_softc *sc, struct mbuf **m_head)
struct stge_txdesc *txd;
struct stge_tfd *tfd;
struct mbuf *m;
struct m_tag *mtag;
bus_dma_segment_t txsegs[STGE_MAXTXSEGS];
int error, i, nsegs, si;
uint64_t csum_flags, tfc;
@ -1270,9 +1269,8 @@ stge_encap(struct stge_softc *sc, struct mbuf **m_head)
sc->sc_cdata.stge_tx_prod = (si + 1) % STGE_TX_RING_CNT;
/* Check if we have a VLAN tag to insert. */
mtag = VLAN_OUTPUT_TAG(sc->sc_ifp, m);
if (mtag != NULL)
tfc |= TFD_VLANTagInsert | TFD_VID(VLAN_TAG_VALUE(mtag));
if (m->m_flags & M_VLANTAG)
tfc |= (TFD_VLANTagInsert | TFD_VID(m->m_pkthdr.ether_vtag));
tfd->tfd_control = htole64(tfc);
/* Update Tx Queue. */
@ -1859,8 +1857,10 @@ stge_rxeof(struct stge_softc *sc)
#endif
/* Check for VLAN tagged packets. */
if ((status & RFD_VLANDetected) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0)
VLAN_INPUT_TAG(ifp, m, RFD_TCI(status64));
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
m->m_pkthdr.ether_vtag = RFD_TCI(status64);
m->m_flags |= M_VLANTAG;
}
STGE_UNLOCK(sc);
/* Pass it on. */

View File

@ -2813,9 +2813,8 @@ ti_rxeof(sc)
* tag it before passing the packet upward.
*/
if (have_tag) {
VLAN_INPUT_TAG(ifp, m, vlan_tag);
if (m == NULL)
continue;
m->m_pkthdr.ether_vtag = vlan_tag;
m->m_flags |= M_VLANTAG;
}
TI_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
@ -2957,7 +2956,6 @@ ti_encap(sc, m_head)
struct ti_tx_desc *f;
struct ti_tx_desc txdesc;
struct mbuf *m;
struct m_tag *mtag;
bus_dma_segment_t txsegs[TI_MAXTXSEGS];
u_int16_t csum_flags;
int error, frag, i, nseg;
@ -3013,7 +3011,6 @@ ti_encap(sc, m_head)
bus_dmamap_sync(sc->ti_rdata_dmat, sc->ti_rdata_dmamap,
BUS_DMASYNC_PREWRITE);
mtag = VLAN_OUTPUT_TAG(sc->ti_ifp, m);
frag = sc->ti_tx_saved_prodidx;
for (i = 0; i < nseg; i++) {
if (sc->ti_hwrev == TI_HWREV_TIGON) {
@ -3024,9 +3021,9 @@ ti_encap(sc, m_head)
ti_hostaddr64(&f->ti_addr, txsegs[i].ds_addr);
f->ti_len = txsegs[i].ds_len;
f->ti_flags = csum_flags;
if (mtag != NULL) {
if (m->m_flags & M_VLANTAG) {
f->ti_flags |= TI_BDFLAG_VLAN_TAG;
f->ti_vlan_tag = VLAN_TAG_VALUE(mtag) & 0xfff;
f->ti_vlan_tag = m->m_pkthdr.ether_vtag & 0xfff;
} else {
f->ti_vlan_tag = 0;
}

View File

@ -765,9 +765,8 @@ txp_rx_reclaim(sc, r)
}
if (rxd->rx_stat & RX_STAT_VLAN) {
VLAN_INPUT_TAG(ifp, m, htons(rxd->rx_vlan >> 16));
if (m == NULL)
goto next;
m->m_pkthdr.ether_vtag = htons(rxd->rx_vlan >> 16);
m->m_flags |= M_VLANTAG;
}
TXP_UNLOCK(sc);
@ -1272,7 +1271,6 @@ txp_start_locked(ifp)
struct mbuf *m, *m0;
struct txp_swdesc *sd;
u_int32_t firstprod, firstcnt, prod, cnt;
struct m_tag *mtag;
TXP_LOCK_ASSERT(sc);
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
@ -1311,10 +1309,9 @@ txp_start_locked(ifp)
if (++cnt >= (TX_ENTRIES - 4))
goto oactive;
mtag = VLAN_OUTPUT_TAG(ifp, m);
if (mtag != NULL) {
if (m->m_flags & M_VLANTAG) {
txd->tx_pflags = TX_PFLAGS_VLAN |
(htons(VLAN_TAG_VALUE(mtag)) << TX_PFLAGS_VLANTAG_S);
(htons(m->m_pkthdr.ether_vtag) << TX_PFLAGS_VLANTAG_S);
}
if (m->m_pkthdr.csum_flags & CSUM_IP)

View File

@ -1490,10 +1490,9 @@ vge_rxeof(sc)
}
if (rxstat & VGE_RDSTS_VTAG) {
VLAN_INPUT_TAG(ifp, m,
ntohs((rxctl & VGE_RDCTL_VLANID)));
if (m == NULL)
continue;
m->m_pkthdr.ether_vtag =
ntohs((rxctl & VGE_RDCTL_VLANID));
m->m_flags |= M_VLANTAG;
}
VGE_UNLOCK(sc);
@ -1757,7 +1756,6 @@ vge_encap(sc, m_head, idx)
struct vge_dmaload_arg arg;
bus_dmamap_t map;
int error;
struct m_tag *mtag;
if (sc->vge_ldata.vge_tx_free <= 2)
return (EFBIG);
@ -1816,10 +1814,9 @@ vge_encap(sc, m_head, idx)
* Set up hardware VLAN tagging.
*/
mtag = VLAN_OUTPUT_TAG(sc->vge_ifp, m_head);
if (mtag != NULL)
if (m_head->m_flags & M_VLANTAG)
sc->vge_ldata.vge_tx_list[idx].vge_ctl |=
htole32(htons(VLAN_TAG_VALUE(mtag)) | VGE_TDCTL_VTAG);
htole32(htons(m_head->m_pkthdr.ether_vtag) | VGE_TDCTL_VTAG);
sc->vge_ldata.vge_tx_list[idx].vge_sts |= htole32(VGE_TDSTS_OWN);

View File

@ -850,15 +850,7 @@ vlan_start(struct ifnet *ifp)
* packet tag that holds it.
*/
if (p->if_capenable & IFCAP_VLAN_HWTAGGING) {
struct m_tag *mtag = (struct m_tag *)
uma_zalloc(zone_mtag_vlan, M_NOWAIT);
if (mtag == NULL) {
ifp->if_oerrors++;
m_freem(m);
continue;
}
VLAN_TAG_VALUE(mtag) = ifv->ifv_tag;
m_tag_prepend(m, mtag);
m->m_pkthdr.ether_vtag = ifv->ifv_tag;
m->m_flags |= M_VLANTAG;
} else {
struct ether_vlan_header *evl;
@ -915,7 +907,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
{
struct ifvlantrunk *trunk = ifp->if_vlantrunk;
struct ifvlan *ifv;
struct m_tag *mtag;
int inenc = 0;
uint16_t tag;
KASSERT(trunk != NULL, ("%s: no trunk", __func__));
@ -925,11 +917,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
* Packet is tagged, but m contains a normal
* Ethernet frame; the tag is stored out-of-band.
*/
mtag = m_tag_locate(m, MTAG_VLAN, MTAG_VLAN_TAG, NULL);
KASSERT(mtag != NULL,
("%s: M_VLANTAG without m_tag", __func__));
tag = EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag));
m_tag_delete(m, mtag);
tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
m->m_flags &= ~M_VLANTAG;
} else {
struct ether_vlan_header *evl;
@ -937,7 +925,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
/*
* Packet is tagged in-band as specified by 802.1q.
*/
mtag = NULL;
inenc = 1;
switch (ifp->if_type) {
case IFT_ETHER:
if (m->m_len < sizeof(*evl) &&
@ -980,7 +968,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
}
TRUNK_RUNLOCK(trunk);
if (mtag == NULL) {
if (inenc) {
/*
* Packet had an in-line encapsulation header;
* remove it. The original header has already

View File

@ -70,54 +70,31 @@ struct vlanreq {
*/
/*
* Drivers that support hardware VLAN tagging pass a packet's tag
* up through the stack by appending a packet tag with this value.
* Output is handled likewise, the driver must locate the packet
* tag to extract the VLAN tag. The following macros are used to
* do this work. On input, do:
* VLAN tags are stored in host byte order. Byte swapping may be
* necessary.
*
* VLAN_INPUT_TAG(ifp, m, tag,);
* Drivers that support hardware VLAN tag stripping fill in the
* received VLAN tag (containing both vlan and priority information)
* into the ether_vtag mbuf packet header field:
*
* m->m_pkthdr.ether_vtag = vlan_id; // ntohs()?
* m->m_flags |= M_VLANTAG;
*
* to mark the packet m with the specified VLAN tag. The last
* parameter provides code to execute in case of an error. On
* output the driver should check mbuf to see if a VLAN tag is
* present and only then check for a tag; this is done with:
* to mark the packet m with the specified VLAN tag.
*
* struct m_tag *mtag;
* mtag = VLAN_OUTPUT_TAG(ifp, m);
* if (mtag != NULL) {
* ... = VLAN_TAG_VALUE(mtag);
* On output the driver should check the mbuf for the M_VLANTAG
* flag to see if a VLAN tag is present and valid:
*
* if (m->m_flags & M_VLANTAG) {
* ... = m->m_pkthdr.ether_vtag; // htons()?
* ... pass tag to hardware ...
* }
*
* Note that a driver must indicate it supports hardware VLAN
* tagging by marking IFCAP_VLAN_HWTAGGING in if_capabilities.
* stripping/insertion by marking IFCAP_VLAN_HWTAGGING in
* if_capabilities.
*/
/*
* This macro must expand to a lvalue so that it can be used
* to set a tag with a simple assignment.
*/
#define VLAN_TAG_VALUE(_mt) (*(u_int *)((_mt) + 1))
#define VLAN_INPUT_TAG(_ifp, _m, _t) do { \
struct m_tag *mtag = (struct m_tag *) \
uma_zalloc(zone_mtag_vlan, M_NOWAIT); \
if (mtag != NULL) { \
VLAN_TAG_VALUE(mtag) = (_t); \
m_tag_prepend((_m), mtag); \
(_m)->m_flags |= M_VLANTAG; \
} else { \
(_ifp)->if_ierrors++; \
m_freem(_m); \
_m = NULL; \
} \
} while (0)
#define VLAN_OUTPUT_TAG(_ifp, _m) \
((_m)->m_flags & M_VLANTAG ? \
m_tag_locate((_m), MTAG_VLAN, MTAG_VLAN_TAG, NULL) : NULL)
#define VLAN_CAPABILITIES(_ifp) do { \
if ((_ifp)->if_vlantrunk != NULL) \
(*vlan_trunk_cap_p)(_ifp); \

View File

@ -722,19 +722,11 @@ ieee80211_deliver_data(struct ieee80211com *ic,
m->m_pkthdr.rcvif = ifp;
if (ni->ni_vlan != 0) {
/* attach vlan tag */
VLAN_INPUT_TAG(ifp, m, ni->ni_vlan);
if (m == NULL)
goto out; /* XXX goto err? */
m->m_pkthdr.ether_vtag = ni->ni_vlan;
m->m_flags |= M_VLANTAG;
}
(*ifp->if_input)(ifp, m);
}
return;
out:
if (m != NULL) {
if (bpf_peers_present(ic->ic_rawbpf))
bpf_mtap(ic->ic_rawbpf, m);
m_freem(m);
}
}
static struct mbuf *

View File

@ -400,12 +400,11 @@ ieee80211_classify(struct ieee80211com *ic, struct mbuf *m, struct ieee80211_nod
*/
v_wme_ac = 0;
if (ni->ni_vlan != 0) {
struct m_tag *mtag = VLAN_OUTPUT_TAG(ic->ic_ifp, m);
if (mtag == NULL) {
if ((m->m_flags & M_VLANTAG) == 0) {
IEEE80211_NODE_STAT(ni, tx_novlantag);
return 1;
}
if (EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag)) !=
if (EVL_VLANOFTAG(m->m_pkthdr.ether_vtag) !=
EVL_VLANOFTAG(ni->ni_vlan)) {
IEEE80211_NODE_STAT(ni, tx_vlanmismatch);
return 1;

View File

@ -345,7 +345,6 @@ ng_vlan_rcvdata(hook_p hook, item_p item)
int error;
u_int16_t vlan;
struct mbuf *m;
struct m_tag *mtag;
struct filter *f;
/* Make sure we have an entire header. */
@ -361,14 +360,14 @@ ng_vlan_rcvdata(hook_p hook, item_p item)
* If from downstream, select between a match hook
* or the nomatch hook.
*/
mtag = m_tag_locate(m, MTAG_VLAN, MTAG_VLAN_TAG, NULL);
if (mtag != NULL || eh->ether_type == htons(ETHERTYPE_VLAN)) {
if (mtag != NULL) {
if (m->m_flags & M_VLANTAG ||
eh->ether_type == htons(ETHERTYPE_VLAN)) {
if (m->m_flags & M_VLANTAG) {
/*
* Packet is tagged, m contains a normal
* Ethernet frame; tag is stored out-of-band.
*/
vlan = EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag));
vlan = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
(void)&evl; /* XXX silence GCC */
} else {
if (m->m_len < sizeof(*evl) &&
@ -380,9 +379,10 @@ ng_vlan_rcvdata(hook_p hook, item_p item)
vlan = EVL_VLANOFTAG(ntohs(evl->evl_tag));
}
if ((f = ng_vlan_findentry(priv, vlan)) != NULL) {
if (mtag != NULL)
m_tag_delete(m, mtag);
else {
if (m->m_flags & M_VLANTAG) {
m->m_pkthdr.ether_vtag = 0;
m->m_flags &= ~M_VLANTAG;
} else {
evl->evl_encap_proto = evl->evl_proto;
bcopy(mtod(m, caddr_t),
mtod(m, caddr_t) +

View File

@ -111,7 +111,7 @@ struct pkthdr {
int csum_flags; /* flags regarding checksum */
int csum_data; /* data field used by csum routines */
u_int16_t tso_segsz; /* TSO segment size */
u_int16_t ether_vlan; /* Ethernet 802.1p+q vlan tag */
u_int16_t ether_vtag; /* Ethernet 802.1p+q vlan tag */
SLIST_HEAD(packet_tags, m_tag) tags; /* list of packet tags */
};
@ -329,7 +329,6 @@ extern uma_zone_t zone_jumbop;
extern uma_zone_t zone_jumbo9;
extern uma_zone_t zone_jumbo16;
extern uma_zone_t zone_ext_refcnt;
extern uma_zone_t zone_mtag_vlan;
static __inline struct mbuf *m_get(int how, short type);
static __inline struct mbuf *m_gethdr(int how, short type);
@ -755,8 +754,6 @@ struct mbuf *m_unshare(struct mbuf *, int how);
#define PACKET_TAG_CARP 28 /* CARP info */
/* Specific cookies and tags. */
#define MTAG_VLAN 1035328035
#define MTAG_VLAN_TAG 0 /* tag of VLAN interface */
/* Packet tag routines. */
struct m_tag *m_tag_alloc(u_int32_t, int, int, int);