Thread (13 messages) 13 messages, 3 authors, 2013-08-02

Re: How do I receive vlan tags on an AF_PACKET socket in 3.4 kernel?

From: Ronny Meeus <hidden>
Date: 2013-08-01 09:24:48

On Wed, Jul 31, 2013 at 10:47 PM, Eric Dumazet [off-list ref] wrote:
On Wed, 2013-07-31 at 22:01 +0200, Ronny Meeus wrote:
quoted
On Wed, Jul 31, 2013 at 5:09 PM, Eric Dumazet [off-list ref] wrote:
quoted
On Wed, 2013-07-31 at 16:42 +0200, Daniel Borkmann wrote:
quoted
You can use bpfc (git://github.com/borkmann/netsniff-ng.git), it also has
an extensive man page. That should probably do it:

$ cat foo
ld vlant
jneq #4094, drop
ret #-1
drop: ret #0

$ bpfc foo
{ 0x20, 0, 0, 0xfffff02c },
{ 0x15, 0, 1, 0x00000ffe },
{ 0x6, 0, 0, 0xffffffff },
{ 0x6, 0, 0, 0x00000000 },
Thanks Daniel, this is very useful information.
I have cloned the repo and compiled the tool myself. It will be very
useful in the future.
quoted
Thanks Daniel.

If the load of this BPF fails (because its an old kernel), then load
your old filter.
I created a small test application after I backported the filter code
to the 3.4 kernel.
I instrumented the kernel with a printk at the moment the
vlan_tx_tag_get call is done to see the actual value of the vlan tag
since it did not work initially.

These are the packets displayed by tcpdump:

tcpdump: WARNING: eth-ntb: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth-ntb, link-type EN10MB (Ethernet), capture size 65535 bytes
00:18:49.233283 06:00:00:00:00:80 > f7:00:00:00:ff:ff, ethertype
802.1Q (0x8100), length 64:
        0x0000:  f700 0000 ffff 0600 0000 0080 8100 affe
        0x0010:  08ab 0014 0000 0000 0f00 0001 0096 6000
        0x0020:  0096 0000 0001 0000 000d 0000 0000 0000
        0x0030:  0000 0000 0000 0000 0000 0000 0000 0000

So the Vlan is 0xffe and the priority/CFI field is 0xA.
Apparently the value I need to  use in the filter is 0xaffe to make it
work. Is this normal or is this a bug in the kernel?

This is the filter I used:
{ 0x20, 0, 0, 0xfffff02c }
{ 0x15, 0, 1, 0x0000affe }
{ 0x06, 0, 0, 0x00000800 }
{ 0x06, 0, 0, 0x00000000 }

And this is the trace of the kernel and my application:

[12529.357172] BPF_S_ANC_VLAN_TAG: affe
packets received:          1
[12533.020743] BPF_S_ANC_VLAN_TAG: affe
packets received:          2
[12536.667159] BPF_S_ANC_VLAN_TAG: affe
packets received:          3
[12540.343857] BPF_S_ANC_VLAN_TAG: affe
packets received:          4
Right, vlan_tx_tag_get() gets the whole tag, so you want to mask A with
0xfff before the compare (to strip the prio)

ld vlant
and #4095
jneq #4094, drop
ret #-1
drop: ret #0

or something like that.

OK the receiving side is clear now. Thanks.

Now the sending side.
I created an application that sends packets using libpcap. These
packets are full Ethernet packets, including VLAN tags etc.
If I connect a PC running Wireshark to the Ethernet port I'm sending
on I receive the packets, no issues.

If a start on the device that is sending the packets also the receive
application I created before I do not receive anything.
This is because the filter attached to the kernel by this application
is checking the VLAN tag in metadata of the buffer, which is in this
case not filled in.
If I do not attach a filter to the receiving application all packets I
send are also received by the receiving application, which is what I
expect since all packets sent on a raw socket are received by all
other sockets listening on the same interface.

I have the feeling that there is something wrong with the current
implementation.
In my opinion, the same VLAN processing as done for packets received
from the network (strip vlan and put it in the meta data) should be
done on packets that are sent by an application just before passing
them to other sockets listening on the same interface.
Right?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help