All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
To: Daniel Borkmann <dborkman@redhat.com>
Cc: <jbrouer@redhat.com>, <netdev@vger.kernel.org>
Subject: Setting skb->protocol efficiently for AF_PACKETs via TX_RING
Date: Mon, 24 Feb 2014 22:40:01 +0100	[thread overview]
Message-ID: <530BBC31.60107@fokus.fraunhofer.de> (raw)
In-Reply-To: <5309FE75.8030802@redhat.com>

Hi all,

for our application, basically a light weight (wireless) MPLS switch, we 
are looking for an efficient way to push Ethernet Frames onto NICs via 
TX_RING.

One challenge here is that we might be heavily mixing EtherTypes (MPLS 
unicast & multicast, as well as signalling traffic).

As far as I understand, the fastest method to push packets onto the NIC 
is to not specify a protocol in the socket() call and also to omit the 
protocol for the bind() call.

Hence, the last option to specify the protocol would be the send() call.
The beauty about the TX_RING implementation is that one can push a large 
batch of frames towards the kernel - as long as the EtherType/protocol 
is identical...

In out case, this means fragmenting a nice large send() into potentially 
single frame send() calls.

So, essentially, we're looking for an efficient method to set 
skb->protocol from the EtherType of the respective Ethernet frame.

Looking into the tpacket_fill_skb() function, it seems that the most 
efficient way accomplish this would be to set skb->protocol after 
importing the hard_header into the skb:

     skb_push(skb, dev->hard_header_len);
     err = skb_store_bits(skb, 0, data,
                      dev->hard_header_len);
     if (unlikely(err))
         return err;

     if (skb->protocol == 0) { /* protocol not yet set bu other means */
         struct ethhdr *ehdr = (struct ethhdr*) data;
         skb->protocol = ehdr->h_proto;
     }

This way tpacket_fill_skb() would return with a fully valid skb for 
further processing. And, this would only be done if skb->protocol was 
not set before via socket(), bind() or send().

Hence, there is no need to break a large send() call down into small 
fragments, while the 'skb->protocol = ehdr->h_proto' assignment would 
have to be done in any case. Using the send() method this would require 
an additional overhead since we'd have to fill in a msghdr and pass it 
along.

Needless to say, we tried it and it seems to work fine (on AMD geode and 
also on a more modern Intel Atom).

We'd be open to alternative solutions. Otherwise we would propose those 
few lines to be added to the af_packet code.

Best regards,

Mathias

      parent reply	other threads:[~2014-02-24 21:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-23 11:03 TX_RING and VLAN : (packet size is too long 1518 > 1514) Mathias Kretschmer
2014-02-23 13:58 ` Daniel Borkmann
2014-02-24  9:03   ` Mathias Kretschmer
2014-02-24 22:33     ` Daniel Borkmann
2014-02-26  7:28       ` Mathias Kretschmer
2014-02-26 10:33         ` Daniel Borkmann
2014-02-24 21:40   ` Mathias Kretschmer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=530BBC31.60107@fokus.fraunhofer.de \
    --to=mathias.kretschmer@fokus.fraunhofer.de \
    --cc=dborkman@redhat.com \
    --cc=jbrouer@redhat.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.