From patchwork Fri Oct 5 13:10:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Chavent X-Patchwork-Id: 189478 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id B79B02C0089 for ; Fri, 5 Oct 2012 23:26:40 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755960Ab2JEN0H (ORCPT ); Fri, 5 Oct 2012 09:26:07 -0400 Received: from briaree.onecert.fr ([134.212.190.4]:51386 "EHLO briaree.onecert.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755927Ab2JEN0D (ORCPT ); Fri, 5 Oct 2012 09:26:03 -0400 X-Greylist: delayed 497 seconds by postgrey-1.27 at vger.kernel.org; Fri, 05 Oct 2012 09:26:03 EDT Received: from neree.onecert.fr (thetis.onecert.fr [134.212.178.12]) by briaree.onecert.fr (8.14.3/8.14.3/ONERA-SRI) with ESMTP id q95DE3dN025778; Fri, 5 Oct 2012 15:14:03 +0200 Received: from neree.onecert.fr (thetis.antiviral [127.0.0.1]) by neree.onecert.fr (8.14.3/8.14.3/ONERA-SRI) with ESMTP id q95DE3Eg022884; Fri, 5 Oct 2012 15:14:03 +0200 Received: from wdcsd911h.onecert.fr (wdcsd911h.cert.fr [134.212.241.58]) by neree.onecert.fr (8.14.3/8.14.3/ONERA-SRI) with ESMTP id q95DE210022881; Fri, 5 Oct 2012 15:14:02 +0200 From: Paul Chavent To: davem@davemloft.net, edumazet@google.com, daniel.borkmann@tik.ee.ethz.ch, xemul@parallels.com, herbert@gondor.hengli.com.au, netdev@vger.kernel.org, johann.baudy@gnu-log.net, uaca@alumni.uv.es Cc: Paul Chavent Subject: [PATCH] Packet mmap : allow the user to choose the offset of the tx payload. Date: Fri, 5 Oct 2012 15:10:29 +0200 Message-Id: <1349442629-10960-1-git-send-email-paul.chavent@onera.fr> X-Mailer: git-send-email 1.7.12.1 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.3 (briaree.onecert.fr [134.212.190.4]); Fri, 05 Oct 2012 15:14:03 +0200 (CEST) X-Virus-Scanned: clamav-milter 0.97.3 at briaree.onecert.fr X-Virus-Status: Clean X-Spam-Status: No, score=-4.4 required=6.0 tests=ALL_TRUSTED, BAYES_00 autolearn=ham version=3.2.5-onera_sri_4 X-Spam-Checker-Version: SpamAssassin 3.2.5-onera_sri_4 (2008-06-10) on briaree.onecert.fr Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The tx offset of packet mmap tx ring used to be : (TPACKET2_HDRLEN - sizeof(struct sockaddr_ll)) The problem is that depending on the usage of SOCK_DGRAM or SOCK_RAW, the payload could be aligned or not. This patch allow to let the user give an offset for it's tx payload if he desires. Signed-off-by: Paul Chavent --- net/packet/af_packet.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 94060ed..5bf3100 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1851,7 +1851,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, struct tpacket2_hdr *h2; void *raw; } ph; - int to_write, offset, len, tp_len, nr_frags, len_max; + int to_write, offset, len, tp_len, nr_frags, len_max, off; struct socket *sock = po->sk.sk_socket; struct page *page; void *data; @@ -1868,9 +1868,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, switch (po->tp_version) { case TPACKET_V2: tp_len = ph.h2->tp_len; + off = ph.h2->tp_net; break; default: tp_len = ph.h1->tp_len; + off = ph.h1->tp_net; break; } if (unlikely(tp_len > size_max)) { @@ -1882,6 +1884,16 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, skb_reset_network_header(skb); data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll); + if (sock->type != SOCK_DGRAM) + off -= dev->hard_header_len; + if (likely((po->tp_hdrlen - sizeof(struct sockaddr_ll)) < off)) { + if (unlikely((off + tp_len) > size_max)) { + pr_err("packet size is too long (%d + %d > %d)\n", + off, tp_len, size_max); + return -EMSGSIZE; + } + data = ph.raw + off; + } to_write = tp_len; if (sock->type == SOCK_DGRAM) {