Optionally pad outgoing frames to the minimum of 60 bytes (excl. FCS)

before tagging them.  This can help to work around brain-damage in some
switches that fail to pad a frame after untagging it if its length drops
below the minimum.  This option is blessed by IEEE Std 802.1Q (2003 Ed.),
paragraph C.4.4.3.b.  It's controlled by sysctl net.link.vlan.soft_pad.

Idea by:	az
MFC after:	1 week
This commit is contained in:
Yaroslav Tykhiy 2006-08-11 17:09:27 +00:00
parent f5e30bd1ff
commit f6e5e0ad77
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=161210
2 changed files with 57 additions and 2 deletions

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 25, 2006
.Dd August 11, 2006
.Dt VLAN 4
.Os
.Sh NAME
@ -79,6 +79,27 @@ The parent interface is likely to be an Ethernet card connected
to a properly configured switch port.
The VLAN tag should match one of those set up in the switched
network.
.Pp
Initially
.Nm
assumes the same minimum length for tagged and untagged frames.
This mode is selected by the
.Xr sysctl(8)
variable
.Va net.link.vlan.soft_pad
set to 0 (default).
However, there are network devices that fail to adjust frame length,
should it fall below the allowed minimum due to untagging.
Such devices should be able to interoperate with
.Nm
after changing the value of
.Va net.link.vlan.soft_pad
to 1.
In the latter mode,
.Nm
will pad short frames before tagging them
so that their length stays not less than the minimum value
after untagging by the non-compliant devices.
.Sh HARDWARE
The
.Nm
@ -205,7 +226,8 @@ can be corrected manually if used in conjunction with such parent interface.
.Sh SEE ALSO
.Xr kqueue 2 ,
.Xr miibus 4 ,
.Xr ifconfig 8
.Xr ifconfig 8 ,
.Xr sysctl 8
.Sh BUGS
No 802.1Q features except VLAN tagging are implemented.
.Pp

View File

@ -132,6 +132,10 @@ SYSCTL_DECL(_net_link);
SYSCTL_NODE(_net_link, IFT_L2VLAN, vlan, CTLFLAG_RW, 0, "IEEE 802.1Q VLAN");
SYSCTL_NODE(_net_link_vlan, PF_LINK, link, CTLFLAG_RW, 0, "for consistency");
static int soft_pad = 0;
SYSCTL_INT(_net_link_vlan, OID_AUTO, soft_pad, CTLFLAG_RW, &soft_pad, 0,
"pad short frames before tagging");
static MALLOC_DEFINE(M_VLAN, VLANNAME, "802.1Q Virtual LAN Interface");
static eventhandler_tag ifdetach_tag;
@ -808,6 +812,35 @@ vlan_start(struct ifnet *ifp)
continue;
}
/*
* Pad the frame to the minimum size allowed if told to.
* This option is in accord with IEEE Std 802.1Q, 2003 Ed.,
* paragraph C.4.4.3.b. It can help to work around buggy
* bridges that violate paragraph C.4.4.3.a from the same
* document, i.e., fail to pad short frames after untagging.
* E.g., a tagged frame 66 bytes long (incl. FCS) is OK, but
* untagging it will produce a 62-byte frame, which is a runt
* and requires padding. There are VLAN-enabled network
* devices that just discard such runts instead or mishandle
* them somehow.
*/
if (soft_pad) {
static char pad[8]; /* just zeros */
int n;
for (n = ETHERMIN + ETHER_HDR_LEN - m->m_pkthdr.len;
n > 0; n -= sizeof(pad))
if (!m_append(m, min(n, sizeof(pad)), pad))
break;
if (n > 0) {
if_printf(ifp, "cannot pad short frame\n");
ifp->if_oerrors++;
m_freem(m);
continue;
}
}
/*
* If underlying interface can do VLAN tag insertion itself,
* just pass the packet along. However, we need some way to