Bug #26

vlan(4) broken.

Added by dragonfly over 8 years ago. Updated almost 8 years ago.

Status:ClosedStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:-
Target version:-

Description

Hello,

I have been experiencing problems with vlan(4) on DragonFlyBSD HEAD.
Received tagged packets are not being passed down to ether_input()
correctly and transmitted packets are not being tagged. [Packet capture
shows no 802.1Q header on transmitted packets from DragonFlyBSD PC.]

The error message "ether_input got mbuf without embedded
ethernet header" was added to if_ethersubr.c during the recent if_bridge
import.

I have included details below.

Regards

G.Allan

DragonFlyBSD HEAD

ifconfig vr0
vr0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet6 fe80::240:63ff:fed8:230d%vr0 prefixlen 64 scopeid 0x1
ether 00:40:63:d8:23:0d
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active

ifconfig vlan10
vlan10: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1496
inet 192.168.100.12 netmask 0xffffff00 broadcast 192.168.100.255
inet6 fe80::240:63ff:fed8:230d%vlan10 prefixlen 64 scopeid 0x8
ether 00:40:63:d8:23:0d
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
vlan: 10 parent interface: vr0

All received packets tagged with VLAN 10 generate the following diagnostic.

Dec 26 17:00:48 fire kernel: ether_input got mbuf without embedded
ethernet header
Dec 26 17:19:09 fire kernel: ether_input got mbuf without embedded
ethernet header
Dec 26 17:37:30 fire kernel: ether_input got mbuf without embedded
ethernet header

FreeBSD 4.11

ifconfig vlan10
vlan10: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1496
inet 192.168.100.10 netmask 0xffffff00 broadcast 192.168.100.255
ether 00:0c:29:b5:d3:29
vlan: 10 parent interface: fxp0

Attempts to ping 192.168.100.12 generate the following diagnostics.

Dec 18 17:08:40 build /kernel: arp: 192.168.100.12 is on vlan10 but got
reply from 00:40:63:d8:23:0d on fxp0
Dec 18 17:08:45 build last message repeated 4 times

vlan1.diff Magnifier (5.7 KB) dragonfly, 12/30/2005 01:16 PM

History

#1 Updated by dillon over 8 years ago

:Hello,
:
:I have been experiencing problems with vlan(4) on DragonFlyBSD HEAD.
:Received tagged packets are not being passed down to ether_input()
:correctly and transmitted packets are not being tagged. [Packet capture
:shows no 802.1Q header on transmitted packets from DragonFlyBSD PC.]
:
:The error message "ether_input got mbuf without embedded
:ethernet header" was added to if_ethersubr.c during the recent if_bridge
:import.
:
:I have included details below.
:
:Regards
:
:G.Allan

Ok, I will get this bug fixed before we release. The vlan code is
calling ether_input() with the ethernet header separated out.
The recent bridging commit removed that capability from ether_input().
It doesn't look too difficult to fix the vlan code.

-Matt

#2 Updated by dillon over 8 years ago

Gary, and anyone else who can test VLAN support, please try this
patch and tell me if it works.

-Matt

Index: net/vlan/if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/vlan/if_vlan.c,v
retrieving revision 1.18
diff -u -r1.18 if_vlan.c
--- net/vlan/if_vlan.c 28 Nov 2005 17:13:46 -0000 1.18
+++ net/vlan/if_vlan.c 27 Dec 2005 22:42:05 -0000
@@ -379,10 +379,8 @@
{
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);
@@ -392,14 +390,18 @@
* 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;
@@ -423,7 +425,7 @@
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;
@@ -434,6 +436,7 @@
{
struct ifvlan *ifv;
struct ifnet *rcvif;
+ struct ether_header eh_copy;

rcvif = m->m_pkthdr.rcvif;
ASSERT_SERIALIZED(rcvif->if_serializer);
@@ -455,20 +458,22 @@
/*
* 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;

#3 Updated by dragonfly over 8 years ago

Matthew Dillon wrote:
> Gary, and anyone else who can test VLAN support, please try this
> patch and tell me if it works.
>
> -Matt
>
>Index: net/vlan/if_vlan.c
>

Hello,

Thank you for your help. I have successfully tested your patch with
several NICs vr(4), fxp(4), xl(4) and re(4). I've added support for
honoring the VLAN_MTU and VLAN_HWTAGGING parent interface flags. I was
able to test VLAN_MTU and VLAN_HWTAGGING handling with re(4). This means
we no longer have to manually set LINK0 on the vlan interface to enable
hardware support. I have also updated the man page.

The only issue I can find is that tcpdump(1) listening on the parent
interface does not display the fact that the packets are encapsulated.

ifconfig vlan10 create vlan 10 vlandev vr0
ifconfig vlan10 inet 192.168.10.10 netmask 255.255.255.0
ping 192.168.10.20&

tcpdump -n -i vr0 icmp

This matches no packets so it seems the packets are being passed to
bpf(4) encapsulated. (Devices supporting VLAN_HWTAGGING would be an
exception.)

tcpdump -n -i vr0
tcpdump -n -i vr0 vlan

Both display the following: (-v and -vv are similar.)

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on vr0, link-type EN10MB (Ethernet), capture size 96 bytes
12:32:42.324429 IP 192.168.10.10 > 192.168.10.20: icmp 64: echo request
seq 39680
12:32:43.325558 IP 192.168.10.10 > 192.168.10.20: icmp 64: echo request
seq 39936

FreeBSD 4 displays:

tcpdump: listening on fxp0
23:04:37.370155 802.1Q vlan#10 P0 192.168.10.24 > 192.168.10.20: icmp:
echo request
23:04:38.378513 802.1Q vlan#10 P0 192.168.10.24 > 192.168.10.20: icmp:
echo request

I don't know if this is a bug or is just due to DragonFly using a newer
version of tcpdump. It had me thinking bpf handling wasn't working for a
while.

Regards

Gary

#4 Updated by hmp over 8 years ago

To those interested,

I recall Ruslan Ermilov of FreeBSD fame making some significant changes to
the VLAN support (in FreeBSD). It might be worth looking into so we can
improve our VLAN code as well.

#5 Updated by dillon over 8 years ago

:Hello,
:
:Thank you for your help. I have successfully tested your patch with
:several NICs vr(4), fxp(4), xl(4) and re(4). I've added support for
:honoring the VLAN_MTU and VLAN_HWTAGGING parent interface flags. I was
:able to test VLAN_MTU and VLAN_HWTAGGING handling with re(4). This means
:we no longer have to manually set LINK0 on the vlan interface to enable
:hardware support. I have also updated the man page.

All committed, thank you!

:The only issue I can find is that tcpdump(1) listening on the parent
:interface does not display the fact that the packets are encapsulated.
:
: ifconfig vlan10 create vlan 10 vlandev vr0
: ifconfig vlan10 inet 192.168.10.10 netmask 255.255.255.0
: ping 192.168.10.20&
:
: tcpdump -n -i vr0 icmp
:...
:I don't know if this is a bug or is just due to DragonFly using a newer
:version of tcpdump. It had me thinking bpf handling wasn't working for a
:while.
:
:Regards
:
:Gary

I'm not going to worry about this for the release. I suspect
that the BPF tap is either in the wrong place or is not constructing
the pseudo-header properly.

-Matt

Also available in: Atom PDF