From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Borkmann Subject: Re: How do I receive vlan tags on an AF_PACKET socket in 3.4 kernel? Date: Wed, 31 Jul 2013 16:42:55 +0200 Message-ID: <51F9226F.30202@redhat.com> References: <1375193392.10515.28.camel@edumazet-glaptop> <1375280187.10515.92.camel@edumazet-glaptop> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Eric Dumazet , netdev To: Ronny Meeus Return-path: Received: from mx1.redhat.com ([209.132.183.28]:51357 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760313Ab3GaOm7 (ORCPT ); Wed, 31 Jul 2013 10:42:59 -0400 In-Reply-To: Sender: netdev-owner@vger.kernel.org List-ID: On 07/31/2013 04:36 PM, Ronny Meeus wrote: > On Wed, Jul 31, 2013 at 4:16 PM, Eric Dumazet wrote: >> On Wed, 2013-07-31 at 14:51 +0200, Ronny Meeus wrote: >> >>> Thanks for the feedback. High level it is almost clear. >>> >>> At implementation level I do not understand how it is supposed to work. >>> If I use tcpdump to generate a filter for example on vlan 4094 I see >>> no reference at all to the newly added instructions to get the VLAN. >>> >>> ~ # tcpdump -i eth-ntb vlan 4094 -d >>> tcpdump: WARNING: eth-ntb: no IPv4 address assigned >>> (000) ldh [12] >>> (001) jeq #0x8100 jt 3 jf 2 >>> (002) jeq #0x9100 jt 3 jf 7 >>> (003) ldh [14] >>> (004) and #0xfff >>> (005) jeq #0xffe jt 6 jf 7 >>> (006) ret #65535 >>> (007) ret #0 >>> >>> To me it looks like to code above is just checking the bytes in the >>> raw Ethernet packet at offset 12 and 14. >>> Since the command above seems to work it looks to me that the >>> filtering is done in the tcpdump application instead of in the kernel. >>> >>> If I use the strace command while starting tcpdump I see that the >>> SO_ATTACH_FILTER sockopt is passed to the kernel: >>> >>> >>> setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, "\0\1\0\0\20\f\366\340", 8) = 0 >>> fcntl64(3, F_GETFL) = 0x2 (flags O_RDWR) >>> fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 >>> recvfrom(3, 0x7f6f6630, 1, 32, 0, 0) = -1 EAGAIN (Resource >>> temporarily unavailable) >>> fcntl64(3, F_SETFL, O_RDWR) = 0 >>> setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, "\0\10\0\0\20>\210@", 8) = 0 >>> >>> >>> So I'm confused. I would expect to see some commands to read access >>> the VLAN field in the additional data and compare it to the VLAN >>> (4094) I want to filter. >> >> I assumed from you initial mail you were using a BPF filter, not >> libpcap, which presumably doesnt use these new 'instructions' > > I used the tcpdump tool to generate the filter I need to use in my application. > >> Adapting the BPF filter generated by libpcap is a matter of adding 3 or >> 4 instructions. In your case 2 instructions actually >> >> One to load tag id into A >> One to compare A against immediate value 4094 and conditional jump. > > Can you give an real example of a filter that passes all packets that > have a VLAN 4094 attached and drops all others? 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 },