Project

General

Profile

Bug #26 ยป vlan1.diff

dragonfly, 12/30/2005 01:16 PM

View differences:

sys/net/vlan/if_vlan.c 30 Dec 2005 00:24:00 -0000
altq_etherclassify(&p->if_snd, m, &pktattr);
/*
* If the LINK0 flag is set, it means the underlying interface
* 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.
* If underlying interface can do VLAN tag insertion itself,
* 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
......
* following potentially bogus rcvif pointers off into
* never-never land.
*/
if (ifp->if_flags & IFF_LINK0) {
if (p->if_capenable & IFCAP_VLAN_HWTAGGING) {
m->m_pkthdr.rcvif = ifp;
m->m_flags |= M_PROTO1;
} else {
......
{
struct bpf_if *bif;
struct ifvlan *ifv;
struct ether_header *eh = mtod(m, struct ether_header *);
struct ifnet *rcvif;
m_adj(m, ETHER_HDR_LEN);
rcvif = m->m_pkthdr.rcvif;
ASSERT_SERIALIZED(rcvif->if_serializer);
......
* bpf tap if active.
*/
if ((bif = rcvif->if_bpf) != NULL) {
struct ether_header *eh;
struct ether_vlan_header evh;
eh = mtod(m, struct ether_header *);
m_adj(m, ETHER_HDR_LEN);
bcopy(eh, &evh, 2*ETHER_ADDR_LEN);
evh.evl_encap_proto = htons(ETHERTYPE_VLAN);
evh.evl_tag = htons(t);
evh.evl_proto = eh->ether_type;
bpf_ptap(bif, m, &evh, ETHER_HDR_LEN + EVL_ENCAPLEN);
/* XXX assumes data was left intact */
M_PREPEND(m, ETHER_HDR_LEN, MB_WAIT);
}
for (ifv = LIST_FIRST(&ifv_list); ifv != NULL;
......
ifv->ifv_if.if_ipackets++;
lwkt_serialize_exit(rcvif->if_serializer);
lwkt_serialize_enter(ifv->ifv_if.if_serializer);
ether_input(&ifv->ifv_if, eh, m);
ether_input(&ifv->ifv_if, NULL, m);
lwkt_serialize_exit(ifv->ifv_if.if_serializer);
lwkt_serialize_enter(rcvif->if_serializer);
return 0;
......
{
struct ifvlan *ifv;
struct ifnet *rcvif;
struct ether_header eh_copy;
rcvif = m->m_pkthdr.rcvif;
ASSERT_SERIALIZED(rcvif->if_serializer);
......
/*
* Having found a valid vlan interface corresponding to
* the given source interface and vlan tag, remove the
* encapsulation, and run the real packet through
* ether_input() a second time (it had better be
* remaining encapsulation (ether_vlan_header minus the ether_header
* that had already been removed) and run the real packet
* through ether_input() a second time (it had better be
* reentrant!).
*/
eh_copy = *eh;
eh_copy.ether_type = mtod(m, u_int16_t *)[1]; /* evl_proto */
m->m_pkthdr.rcvif = &ifv->ifv_if;
eh->ether_type = mtod(m, u_int16_t *)[1];
m->m_data += EVL_ENCAPLEN;
m->m_len -= EVL_ENCAPLEN;
m->m_pkthdr.len -= EVL_ENCAPLEN;
m_adj(m, EVL_ENCAPLEN);
M_PREPEND(m, ETHER_HDR_LEN, MB_WAIT);
*(struct ether_header *)mtod(m, void *) = eh_copy;
ifv->ifv_if.if_ipackets++;
lwkt_serialize_exit(rcvif->if_serializer);
lwkt_serialize_enter(ifv->ifv_if.if_serializer);
ether_input(&ifv->ifv_if, eh, m);
ether_input(&ifv->ifv_if, NULL, m);
lwkt_serialize_exit(ifv->ifv_if.if_serializer);
lwkt_serialize_enter(rcvif->if_serializer);
return 0;
......
if (ifv->ifv_p)
return EBUSY;
ifv->ifv_p = p;
if (p->if_data.ifi_hdrlen == sizeof(struct ether_vlan_header))
if (p->if_capenable & IFCAP_VLAN_MTU)
ifv->ifv_if.if_mtu = p->if_mtu;
else
ifv->ifv_if.if_mtu = p->if_data.ifi_mtu - EVL_ENCAPLEN;
share/man/man4/vlan.4 30 Dec 2005 00:00:41 -0000
.Pp
The
.Nm
driver supports physical devices that do
the VLAN demultiplexing in firmware.
The
.Cm link0
flag should be set on a
.Nm
interface
.Pq Em not on its parent
using
.Xr ifconfig 8
in that case to indicate that hardware support for
the 802.1Q VLANs is present in its parent.
driver supports efficient operation over parent interfaces that can provide
help in processing VLANs.
Such interfaces are automatically recognized by their capabilities.
Depending on the level of sophistication found in a physical
interface, it may do full VLAN processing or just be able to
receive and transmit frames exceeding the maximum Ethernet frame size
by the length of a 802.1Q header.
The capabilities may be user-controlled by the respective parameters to
.Xr ifconfig 8 ,
.Cm vlanhwtag
and
.Cm vlanmtu .
However, a physical interface is not obliged to react to them:
It may have either capability enabled permanently without
a way to turn it off.
The whole issue is very specific to a particular device and its driver.
.\"
.Ss "Selecting the Right Network Interface Card to Run VLANs Through"
By now, the only NICs that have both hardware support and proper
......
.Xr em 4 ,
.Xr gx 4 ,
.Xr nge 4 ,
.Xr re 4 ,
.Xr ti 4 ,
and
.Xr txp 4 .
    (1-1/1)