Allocate the M_VLANTAG m_pkthdr flag, and use it to indicate that

a packet has VLAN mbuf tag attached.  This is faster to check than
m_tag_locate(), and allows us to use the tags in non-vlan(4) VLAN
producers.

The first argument to VLAN_OUTPUT_TAG() is now unused but retained
for backward compatibility.

While here, embellish a fix in rev. 1.174 of if_ethersubr.c -- it
now checks for packets with VLAN (mbuf) tags, and it should now
be possible to bridge(4) on vlan(4)'s whose parent interfaces
support VLAN decapsulation in hardware.

Reviewed by:	sam
This commit is contained in:
Ruslan Ermilov 2005-02-18 22:31:19 +00:00
parent b7820945ac
commit 6ee20ab521
4 changed files with 12 additions and 8 deletions

View File

@ -604,7 +604,8 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
#endif
if (!(BDG_ACTIVE(ifp)) &&
!(ether_type == ETHERTYPE_VLAN && ifp->if_nvlans > 0)) {
!((ether_type == ETHERTYPE_VLAN || m->m_flags & M_VLANTAG) &&
ifp->if_nvlans > 0)) {
/*
* Discard packet if upper layers shouldn't see it because it
* was unicast to a different Ethernet address. If the driver
@ -618,7 +619,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m)
* it's undesired.
*/
if ((ifp->if_flags & IFF_PROMISC) != 0
&& (eh->ether_dhost[0] & 1) == 0
&& !ETHER_IS_MULTICAST(eh->ether_dhost)
&& bcmp(eh->ether_dhost,
IFP2AC(ifp)->ac_enaddr, ETHER_ADDR_LEN) != 0
&& (ifp->if_flags & IFF_PPROMISC) == 0) {
@ -657,8 +658,7 @@ post_stats:
* Check to see if the device performed the VLAN decapsulation and
* provided us with the tag.
*/
if (m_tag_first(m) != NULL &&
m_tag_locate(m, MTAG_VLAN, MTAG_VLAN_TAG, NULL) != NULL) {
if (m->m_flags & M_VLANTAG) {
/*
* If no VLANs are configured, drop.
*/

View File

@ -563,6 +563,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
*/
tag = EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag));
m_tag_delete(m, mtag);
m->m_flags &= ~M_VLANTAG;
} else {
switch (ifp->if_type) {
case IFT_ETHER:

View File

@ -80,8 +80,8 @@ struct vlanreq {
*
* 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 ifnet to see if any VLANs are
* in use and only then check for a packet tag; this is done with:
* 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:
*
* struct m_tag *mtag;
* mtag = VLAN_OUTPUT_TAG(ifp, m);
@ -107,10 +107,11 @@ struct vlanreq {
} \
*(u_int *)(mtag+1) = (_t); \
m_tag_prepend((_m), mtag); \
(_m)->m_flags |= M_VLANTAG; \
} while (0)
#define VLAN_OUTPUT_TAG(_ifp, _m) \
((_ifp)->if_nvlans != 0 ? \
((_m)->m_flags & M_VLANTAG ? \
m_tag_locate((_m), MTAG_VLAN, MTAG_VLAN_TAG, NULL) : NULL)
#define VLAN_TAG_VALUE(_mt) (*(u_int *)((_mt)+1))
#endif /* _KERNEL */

View File

@ -178,6 +178,7 @@ struct mbuf {
#define M_FRAG 0x0800 /* packet is a fragment of a larger packet */
#define M_FIRSTFRAG 0x1000 /* packet is first fragment */
#define M_LASTFRAG 0x2000 /* packet is last fragment */
#define M_VLANTAG 0x10000 /* packet has VLAN tag attached */
/*
* External buffer types: identify ext_buf type.
@ -195,7 +196,8 @@ struct mbuf {
*/
#define M_COPYFLAGS (M_PKTHDR|M_EOR|M_RDONLY|M_PROTO1|M_PROTO1|M_PROTO2|\
M_PROTO3|M_PROTO4|M_PROTO5|M_SKIP_FIREWALL|\
M_BCAST|M_MCAST|M_FRAG|M_FIRSTFRAG|M_LASTFRAG)
M_BCAST|M_MCAST|M_FRAG|M_FIRSTFRAG|M_LASTFRAG|\
M_VLANTAG)
/*
* Flags indicating hw checksum support and sw checksum requirements.