{"id":815224,"url":"http://patchwork.ozlabs.org/api/patches/815224/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/patch/20170919003904.5124-14-tom@quantonium.net/","project":{"id":7,"url":"http://patchwork.ozlabs.org/api/projects/7/?format=json","name":"Linux network development","link_name":"netdev","list_id":"netdev.vger.kernel.org","list_email":"netdev@vger.kernel.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20170919003904.5124-14-tom@quantonium.net>","list_archive_url":null,"date":"2017-09-19T00:39:03","name":"[net-next,13/14] gtp: Support for GRO","commit_ref":null,"pull_url":null,"state":"changes-requested","archived":true,"hash":"8cfeee5664185bf4adfade003012e2189d17eb84","submitter":{"id":72064,"url":"http://patchwork.ozlabs.org/api/people/72064/?format=json","name":"Tom Herbert","email":"tom@quantonium.net"},"delegate":{"id":34,"url":"http://patchwork.ozlabs.org/api/users/34/?format=json","username":"davem","first_name":"David","last_name":"Miller","email":"davem@davemloft.net"},"mbox":"http://patchwork.ozlabs.org/project/netdev/patch/20170919003904.5124-14-tom@quantonium.net/mbox/","series":[{"id":3758,"url":"http://patchwork.ozlabs.org/api/series/3758/?format=json","web_url":"http://patchwork.ozlabs.org/project/netdev/list/?series=3758","date":"2017-09-19T00:38:50","name":"gtp: Additional feature support","version":1,"mbox":"http://patchwork.ozlabs.org/series/3758/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/815224/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/815224/checks/","tags":{},"related":[],"headers":{"Return-Path":"<netdev-owner@vger.kernel.org>","X-Original-To":"patchwork-incoming@ozlabs.org","Delivered-To":"patchwork-incoming@ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=quantonium-net.20150623.gappssmtp.com\n\theader.i=@quantonium-net.20150623.gappssmtp.com\n\theader.b=\"gL5PrtIR\"; dkim-atps=neutral"],"Received":["from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xx3tc5Bs7z9s5L\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 19 Sep 2017 10:40:08 +1000 (AEST)","(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751549AbdISAkG (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 18 Sep 2017 20:40:06 -0400","from mail-pf0-f173.google.com ([209.85.192.173]:45201 \"EHLO\n\tmail-pf0-f173.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751541AbdISAkD (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 18 Sep 2017 20:40:03 -0400","by mail-pf0-f173.google.com with SMTP id q76so1109936pfq.2\n\tfor <netdev@vger.kernel.org>; Mon, 18 Sep 2017 17:40:03 -0700 (PDT)","from localhost.localdomain (c-73-162-13-107.hsd1.ca.comcast.net.\n\t[73.162.13.107]) by smtp.gmail.com with ESMTPSA id\n\tk78sm662018pfb.157.2017.09.18.17.40.01\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tMon, 18 Sep 2017 17:40:01 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=quantonium-net.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=TGyPfjP7tOUbqXkiuGDdw5mlZaZd0OcOu8cLIQaFrLk=;\n\tb=gL5PrtIR5YGbWZaYMIGrQNBt3Ruw1VrD7EpltZwAvBnDNL19+SarJ577Pw/rEH2wyx\n\t/QKd8Fr0GTRk8V/NaSDzprG1bHZ539yZVu2tEuEDcqri7otAtDgnvC741zNdEf6GPkCq\n\tKQZFI88Iz7edVjcoDyYWkHkLWuglMUxA3Guh4CQrFVE7a4p+pAbCN57Xd9arQ+D9G5N6\n\t4Ito/Mlzewl2MfUN6+NuB0MiHknNzCffM+1DoLo+X06g0ec2D3MaiKZbC6tWaTG0EQcj\n\tpeAfLz7j/G4504GhZXrs2noLsDHJ2k44X/o6vkE5qgZGDo+enUDDVVGr2eEJTcqYU5cX\n\taEWA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=TGyPfjP7tOUbqXkiuGDdw5mlZaZd0OcOu8cLIQaFrLk=;\n\tb=IfKaT8mwAe7iV/m/g3MxSzzgzA0qI1oRmjvUTLBB2YGiFOvrTttRqsK8ztB0T/ZB+b\n\t3QPN//xdRxUq6OhFCy5YiTGcCkwmphMOM/OKP5m1S6GaD4/l4e3Y27FH7xODYZ6qS4mV\n\tYwUMd2VF6rm3/VH1Q1b+FhkLrT8oRjvgGt6KwkReMSFMY9ATrlO0S7ksAof8zNC+9C/v\n\twOr2dqBshNGgCRCtdVjV33milkzE4uhhrByAkMZeexo7bwjQFs9VBIih88c4OyBW42Kg\n\tOLph5EEr0hfEY6ng/ked9kzQkFjFfnLd/DR4ATHaTPLBmC3WVxCZghpK/ME6h5NM6GMM\n\tVXSg==","X-Gm-Message-State":"AHPjjUjiotDjW+clKX1d5BP5O+EeXrh/O4Dd7PShohkLkOaiCG6LZwPE\n\tz2JHKcFTZHVSFl0Ns60=","X-Google-Smtp-Source":"AOwi7QBJlzgGCmoJkzX2YXkhgqoYW6fwr+DsG1smaZ2tgnVTxQO2LvjhILGA09urN/0YKIPYEeShWA==","X-Received":"by 10.99.140.29 with SMTP id m29mr363150pgd.126.1505781602842;\n\tMon, 18 Sep 2017 17:40:02 -0700 (PDT)","From":"Tom Herbert <tom@quantonium.net>","To":"davem@davemloft.net","Cc":"netdev@vger.kernel.org, pablo@netfilter.org, laforge@gnumonks.org,\n\trohit@quantonium.net, Tom Herbert <tom@quantonium.net>","Subject":"[PATCH net-next 13/14] gtp: Support for GRO","Date":"Mon, 18 Sep 2017 17:39:03 -0700","Message-Id":"<20170919003904.5124-14-tom@quantonium.net>","X-Mailer":"git-send-email 2.11.0","In-Reply-To":"<20170919003904.5124-1-tom@quantonium.net>","References":"<20170919003904.5124-1-tom@quantonium.net>","Sender":"netdev-owner@vger.kernel.org","Precedence":"bulk","List-ID":"<netdev.vger.kernel.org>","X-Mailing-List":"netdev@vger.kernel.org"},"content":"Populate GRO receive and GRO complete functions for GTP-Uv0 and v1.\n\nSigned-off-by: Tom Herbert <tom@quantonium.net>\n---\n drivers/net/gtp.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 204 insertions(+)","diff":"diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c\nindex b53946f8b10b..2f9d810cf19f 100644\n--- a/drivers/net/gtp.c\n+++ b/drivers/net/gtp.c\n@@ -22,6 +22,7 @@\n #include <linux/jhash.h>\n #include <linux/if_tunnel.h>\n #include <linux/net.h>\n+#include <linux/netdevice.h>\n #include <linux/file.h>\n #include <linux/gtp.h>\n \n@@ -429,6 +430,205 @@ static int gtp1u_udp_encap_recv(struct sock *sk, struct sk_buff *skb)\n \treturn 1;\n }\n \n+static struct sk_buff **gtp_gro_receive_finish(struct sock *sk,\n+\t\t\t\t\t       struct sk_buff **head,\n+\t\t\t\t\t       struct sk_buff *skb,\n+\t\t\t\t\t       void *hdr, size_t hdrlen)\n+{\n+\tconst struct packet_offload *ptype;\n+\tstruct sk_buff **pp;\n+\t__be16 type;\n+\n+\ttype = ipver_to_eth((struct iphdr *)((void *)hdr + hdrlen));\n+\tif (!type)\n+\t\tgoto out_err;\n+\n+\trcu_read_lock();\n+\n+\tptype = gro_find_receive_by_type(type);\n+\tif (!ptype)\n+\t\tgoto out_unlock_err;\n+\n+\tskb_gro_pull(skb, hdrlen);\n+\tskb_gro_postpull_rcsum(skb, hdr, hdrlen);\n+\tpp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);\n+\n+\trcu_read_unlock();\n+\n+\treturn pp;\n+\n+out_unlock_err:\n+\trcu_read_unlock();\n+out_err:\n+\tNAPI_GRO_CB(skb)->flush |= 1;\n+\treturn NULL;\n+}\n+\n+static struct sk_buff **gtp0_gro_receive(struct sock *sk,\n+\t\t\t\t\t struct sk_buff **head,\n+\t\t\t\t\t struct sk_buff *skb)\n+{\n+\tstruct gtp0_header *gtp0;\n+\tsize_t len, hdrlen, off;\n+\tstruct sk_buff *p;\n+\n+\toff = skb_gro_offset(skb);\n+\tlen = off + sizeof(*gtp0);\n+\thdrlen = sizeof(*gtp0);\n+\n+\tgtp0 = skb_gro_header_fast(skb, off);\n+\tif (skb_gro_header_hard(skb, len)) {\n+\t\tgtp0 = skb_gro_header_slow(skb, len, off);\n+\t\tif (unlikely(!gtp0))\n+\t\t\tgoto out;\n+\t}\n+\n+\tif ((gtp0->flags >> 5) != GTP_V0 || gtp0->type != GTP_TPDU)\n+\t\tgoto out;\n+\n+\thdrlen += sizeof(*gtp0);\n+\n+\t/* To get IP version */\n+\tlen += sizeof(struct iphdr);\n+\n+\t/* Now get header with GTP header an IPv4 header (for version) */\n+\tif (skb_gro_header_hard(skb, len)) {\n+\t\tgtp0 = skb_gro_header_slow(skb, len, off);\n+\t\tif (unlikely(!gtp0))\n+\t\t\tgoto out;\n+\t}\n+\n+\tfor (p = *head; p; p = p->next) {\n+\t\tconst struct gtp0_header *gtp0_t;\n+\n+\t\tif (!NAPI_GRO_CB(p)->same_flow)\n+\t\t\tcontinue;\n+\n+\t\tgtp0_t = (struct gtp0_header *)(p->data + off);\n+\n+\t\tif (gtp0->flags != gtp0_t->flags ||\n+\t\t    gtp0->type != gtp0_t->type ||\n+\t\t    gtp0->flow != gtp0_t->flow ||\n+\t\t    gtp0->tid != gtp0_t->tid) {\n+\t\t\tNAPI_GRO_CB(p)->same_flow = 0;\n+\t\t\tcontinue;\n+\t\t}\n+\t}\n+\n+\treturn gtp_gro_receive_finish(sk, head, skb, gtp0, hdrlen);\n+\n+out:\n+\tNAPI_GRO_CB(skb)->flush |= 1;\n+\n+\treturn NULL;\n+}\n+\n+static struct sk_buff **gtp1u_gro_receive(struct sock *sk,\n+\t\t\t\t\t  struct sk_buff **head,\n+\t\t\t\t\t  struct sk_buff *skb)\n+{\n+\tstruct gtp1_header *gtp1;\n+\tsize_t len, hdrlen, off;\n+\tstruct sk_buff *p;\n+\n+\toff = skb_gro_offset(skb);\n+\tlen = off + sizeof(*gtp1);\n+\thdrlen = sizeof(*gtp1);\n+\n+\tgtp1 = skb_gro_header_fast(skb, off);\n+\tif (skb_gro_header_hard(skb, len)) {\n+\t\tgtp1 = skb_gro_header_slow(skb, len, off);\n+\t\tif (unlikely(!gtp1))\n+\t\t\tgoto out;\n+\t}\n+\n+\tif ((gtp1->flags >> 5) != GTP_V1 || gtp1->type != GTP_TPDU)\n+\t\tgoto out;\n+\n+\tif (gtp1->flags & GTP1_F_MASK) {\n+\t\thdrlen += 4;\n+\t\tlen += 4;\n+\t}\n+\n+\tlen += sizeof(struct iphdr);\n+\n+\t/* Now get header with GTP header an IPv4 header (for version) */\n+\tif (skb_gro_header_hard(skb, len)) {\n+\t\tgtp1 = skb_gro_header_slow(skb, len, off);\n+\t\tif (unlikely(!gtp1))\n+\t\t\tgoto out;\n+\t}\n+\n+\tfor (p = *head; p; p = p->next) {\n+\t\tconst struct gtp1_header *gtp1_t;\n+\n+\t\tif (!NAPI_GRO_CB(p)->same_flow)\n+\t\t\tcontinue;\n+\n+\t\tgtp1_t = (struct gtp1_header *)(p->data + off);\n+\n+\t\tif (gtp1->flags != gtp1_t->flags ||\n+\t\t    gtp1->type != gtp1_t->type ||\n+\t\t    gtp1->tid != gtp1_t->tid) {\n+\t\t\tNAPI_GRO_CB(p)->same_flow = 0;\n+\t\t\tcontinue;\n+\t\t}\n+\t}\n+\n+\treturn gtp_gro_receive_finish(sk, head, skb, gtp1, hdrlen);\n+\n+out:\n+\tNAPI_GRO_CB(skb)->flush = 1;\n+\n+\treturn NULL;\n+}\n+\n+static int gtp_gro_complete_finish(struct sock *sk, struct sk_buff *skb,\n+\t\t\t\t   int nhoff, size_t hdrlen)\n+{\n+\tstruct packet_offload *ptype;\n+\tint err = -EINVAL;\n+\t__be16 type;\n+\n+\ttype = ipver_to_eth((struct iphdr *)(skb->data + nhoff + hdrlen));\n+\tif (!type)\n+\t\treturn err;\n+\n+\trcu_read_lock();\n+\tptype = gro_find_complete_by_type(type);\n+\tif (ptype)\n+\t\terr = ptype->callbacks.gro_complete(skb, nhoff + hdrlen);\n+\n+\trcu_read_unlock();\n+\n+\tskb_set_inner_mac_header(skb, nhoff + hdrlen);\n+\n+\treturn err;\n+}\n+\n+static int gtp0_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)\n+{\n+\tstruct gtp0_header *gtp0 = (struct gtp0_header *)(skb->data + nhoff);\n+\tsize_t hdrlen = sizeof(struct gtp0_header);\n+\n+\tgtp0->length = htons(skb->len - nhoff - hdrlen);\n+\n+\treturn gtp_gro_complete_finish(sk, skb, nhoff, hdrlen);\n+}\n+\n+static int gtp1u_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)\n+{\n+\tstruct gtp1_header *gtp1 = (struct gtp1_header *)(skb->data + nhoff);\n+\tsize_t hdrlen = sizeof(struct gtp1_header);\n+\n+\tif (gtp1->flags & GTP1_F_MASK)\n+\t\thdrlen += 4;\n+\n+\tgtp1->length = htons(skb->len - nhoff - hdrlen);\n+\n+\treturn gtp_gro_complete_finish(sk, skb, nhoff, hdrlen);\n+}\n+\n static void gtp_encap_destroy(struct sock *sk)\n {\n \tstruct gtp_dev *gtp;\n@@ -946,9 +1146,13 @@ static int gtp_encap_enable_sock(struct socket *sock, int type,\n \tswitch (type) {\n \tcase UDP_ENCAP_GTP0:\n \t\ttuncfg.encap_rcv = gtp0_udp_encap_recv;\n+\t\ttuncfg.gro_receive = gtp0_gro_receive;\n+\t\ttuncfg.gro_complete = gtp0_gro_complete;\n \t\tbreak;\n \tcase UDP_ENCAP_GTP1U:\n \t\ttuncfg.encap_rcv = gtp1u_udp_encap_recv;\n+\t\ttuncfg.gro_receive = gtp1u_gro_receive;\n+\t\ttuncfg.gro_complete = gtp1u_gro_complete;\n \t\tbreak;\n \tdefault:\n \t\tpr_debug(\"Unknown encap type %u\\n\", type);\n","prefixes":["net-next","13/14"]}