get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/815224/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 815224,
    "url": "http://patchwork.ozlabs.org/api/patches/815224/?format=api",
    "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=api",
        "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=api",
        "name": "Tom Herbert",
        "email": "tom@quantonium.net"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "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=api",
            "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"
    ]
}