[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAD6jFUS7L+3uMqP3zi1S2bocNVQFFBNbzdRpymKv=Tq9R7AmZQ@mail.gmail.com>
Date: Thu, 8 Nov 2012 09:00:04 +0100
From: Daniel Borkmann <danborkmann@...earbox.net>
To: Ronny Meeus <ronny.meeus@...il.com>
Cc: netdev <netdev@...r.kernel.org>
Subject: Re: mmap RX_RING socket issue 32b application running on 64b kernel.
On Thu, Nov 8, 2012 at 8:32 AM, Ronny Meeus <ronny.meeus@...il.com> wrote:
> On Wed, Nov 7, 2012 at 7:54 PM, Ronny Meeus <ronny.meeus@...il.com> wrote:
>> On Wed, Nov 7, 2012 at 7:26 PM, Daniel Borkmann
>> <danborkmann@...earbox.net> wrote:
>>> On Wed, Nov 7, 2012 at 6:58 PM, Ronny Meeus <ronny.meeus@...il.com> wrote:
>>>> I have an application using raw Ethernet sockets in combination with
>>>> the mmaped RX_RING.
>>>> The application is running on a Cavium MIPS processor (64bit) and the
>>>> application code is compiled with the N32 ABI.
>>>>
>>>> Since the ring buffer is shared between the Linux kernel and the
>>>> application there is a conflict in the way the data is presented.
>>>> Each buffer in the ring has a header that has following structure:
>>>> (File http://lxr.free-electrons.com/source/include/linux/if_packet.h )
>>>> 103 struct tpacket_hdr {
>>>> 104 unsigned long tp_status;
>>>> 105 unsigned int tp_len;
>>>> 106 unsigned int tp_snaplen;
>>>> 107 unsigned short tp_mac;
>>>> 108 unsigned short tp_net;
>>>> 109 unsigned int tp_sec;
>>>> 110 unsigned int tp_usec;
>>>> 111 };
>>>>
>>>> The status field indicates that the buffer belongs to the kernel or to
>>>> the user. Note that an unsigned long is used to represent the field.
>>>> In the kernel the long is 64 bit while in application space the long
>>>> is only 32bit, so the bits do not match.
>>>>
>>>> After adapting the code to take this into account my program works well.
>>>> In my test program I have defined a new struct where I change the
>>>> “unsigned long” into an “unsigned long long”:
>>>>
>>>> struct tpacket_hdr_64 {
>>>> unsigned long long tp_status;
>>>> unsigned int tp_len;
>>>> unsigned int tp_snaplen;
>>>> unsigned short tp_mac;
>>>> unsigned short tp_net;
>>>> unsigned int tp_sec;
>>>> unsigned int tp_usec;
>>>> };
>>>>
>>>> In my opinion this is not a correct solution. It should be solved
>>>> somewhere in the include file I used so that it is transparent for the
>>>> application.
>>>> Please comment.
>>>
>>> Have you tried to use packet_mmap with TPACKET version 2 [1]?
>>>
>>> In my understanding, it was introduced because of such issues that you
>>> described.
>>>
>>> [1] E.g. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=bbd6ef87c544d88c30e4b762b1b61ef267a7d279
>>
>> I did not try this. I will do it tomorrow.
>> Thanks for the quick response.
>
> With the code below it indeed works.
>
> req.tp_block_size = FRAME_SIZE * NR_FRAMES_PER_BLOCK;
> req.tp_frame_size = FRAME_SIZE;
> req.tp_block_nr = NR_FRAMES / NR_FRAMES_PER_BLOCK;
> req.tp_frame_nr = NR_FRAMES;
>
> val = TPACKET_V2;
> setsockopt(eth_sock, SOL_PACKET,PACKET_VERSION, &val, sizeof(val));
> setsockopt(eth_sock,SOL_PACKET,PACKET_RX_RING,(char *)&req,sizeof(req));
> packet_mem = mmap(NULL,req.tp_block_size * req.tp_block_nr,
> PROT_READ|PROT_WRITE|PROT_EXEC,MAP_SHARED,eth_sock, 0);
>
> I wonder why there are so many examples available on the Internet that
> either do not set the version or set the version to 1.
Maybe it should be documented somewhere. ;)
> I would assume that the only correct usage of this interface is to use
> version 2 since this is working on all platforms.
> Is this correct?
For using RX_RING/TX_RING ... yep. I think version 1 is only for
backwards compatibility.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists