get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 808445,
    "url": "http://patchwork.ozlabs.org/api/patches/808445/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170831222239.21509-2-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": "<20170831222239.21509-2-tom@quantonium.net>",
    "list_archive_url": null,
    "date": "2017-08-31T22:22:38",
    "name": "[net-next,1/2] flow_dissector: Cleanup control flow",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "58189c069e645add1a7658beb0f105cd9c374c52",
    "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/20170831222239.21509-2-tom@quantonium.net/mbox/",
    "series": [
        {
            "id": 914,
            "url": "http://patchwork.ozlabs.org/api/series/914/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=914",
            "date": "2017-08-31T22:22:37",
            "name": "flow_dissector: Flow dissector fixes",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/914/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/808445/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/808445/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=\"u+RHWdkr\"; dkim-atps=neutral"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xjxjm4TFFz9s7f\n\tfor <patchwork-incoming@ozlabs.org>;\n\tFri,  1 Sep 2017 08:23:56 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1751792AbdHaWXy (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tThu, 31 Aug 2017 18:23:54 -0400",
            "from mail-pf0-f182.google.com ([209.85.192.182]:35549 \"EHLO\n\tmail-pf0-f182.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1751205AbdHaWXx (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Thu, 31 Aug 2017 18:23:53 -0400",
            "by mail-pf0-f182.google.com with SMTP id g13so2749261pfm.2\n\tfor <netdev@vger.kernel.org>; Thu, 31 Aug 2017 15:23:53 -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\to22sm772493pgn.59.2017.08.31.15.23.51\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 31 Aug 2017 15:23:51 -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=V1h58NOsY0j3K6Q7Z956Lcz/dlU3nVLspX0/57ShnSA=;\n\tb=u+RHWdkrNclMV+o+D4EWqTYRA2vSBIDHs43yXIyxwqNp5IHIKeUEVTRF2YpOwfjXmB\n\tzrer8c2K8+t97voDgga0uYorABSUqN28M0nVuonz7RPR+fMXlb5J7bsWqH8s3zTc66av\n\t8oPO9lkkRupct33mtKz2YjEODdaMsxf6fiCh1ApSTNzsCXDRI3Ilb5FP6GRBZn2AggXH\n\t65cPwP/so9JuFswFXEJE55bkifbysEMIOYhevmAgLmO27NFe8U/dYoaHHBDdG3x88T88\n\tnc+G3o2b2aGgW5IRzD58ahYvi1gD+MXEqcwJLpX3x1e//K54vh95sQn9zyHxvhj/n6rM\n\t6SDw==",
        "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=V1h58NOsY0j3K6Q7Z956Lcz/dlU3nVLspX0/57ShnSA=;\n\tb=S7o1p2PSCL0uqR8j9dGKsqZUgJI0ARb218IbuzenEmBYsZ0Qz43xXZyAEJDbShgJXN\n\tL1wRMdN/GblWGL82aZP5nuz5tSz4UI2U5p9/8vMqI0n5UoYxojYMvgQw6DhkHYg1eBQX\n\t6BtQQ5LOeXHmRVtuPqowZXMGoWr/3XHty3E7U9R4mvlXmQR4VLT0QAD8nNOC6xC46TGI\n\tQLkyiQJXYjUI2b3jB3AHiYCplGS3IXsLfRrhEfwWCrmp15KGK+EUaxt3kuBBHNT4clwu\n\twni6qiZL7CNiyHzS1Xjm/B4M7djOD0NhXObgToRHxIBWLqLTqRgkM+xEJGTMO/XHLFfe\n\tW/Lw==",
        "X-Gm-Message-State": "AHYfb5jGFY83TzUV2/Ay6TucjcxvchDDWJw8hgu5UrrfIEMyOSnTGjTX\n\tJ15S0D/UnwjRATrlOQU=",
        "X-Google-Smtp-Source": "ADKCNb49LReYV2Kw5+blBbFkFOIvp/WSrpa80Ra1vkaZEZ/BT/9DVBCCCFDvFYgg/0UPE3OJnURAAw==",
        "X-Received": "by 10.98.220.137 with SMTP id c9mr3960495pfl.190.1504218232907; \n\tThu, 31 Aug 2017 15:23:52 -0700 (PDT)",
        "From": "Tom Herbert <tom@quantonium.net>",
        "To": "davem@davemloft.net",
        "Cc": "netdev@vger.kernel.org, alex.popov@linux.com,\n\thannes@stressinduktion.org, Tom Herbert <tom@quantonium.net>",
        "Subject": "[PATCH net-next 1/2] flow_dissector: Cleanup control flow",
        "Date": "Thu, 31 Aug 2017 15:22:38 -0700",
        "Message-Id": "<20170831222239.21509-2-tom@quantonium.net>",
        "X-Mailer": "git-send-email 2.11.0",
        "In-Reply-To": "<20170831222239.21509-1-tom@quantonium.net>",
        "References": "<20170831222239.21509-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": "__skb_flow_dissect is riddled with gotos that make discerning the flow,\ndebugging, and extending the capability difficult. This patch\nreorganizes things so that we only perform goto's after the two main\nswitch statements (no gotos within the cases now). It also eliminates\nseveral goto labels so that there are only two labels that can be target\nfor goto.\n\nReported-by: Alexander Popov <alex.popov@linux.com>\nSigned-off-by: Tom Herbert <tom@quantonium.net>\n---\n include/net/flow_dissector.h |   9 ++\n net/core/flow_dissector.c    | 225 ++++++++++++++++++++++++++++---------------\n 2 files changed, 156 insertions(+), 78 deletions(-)",
    "diff": "diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h\nindex e2663e900b0a..c358c3ff6acc 100644\n--- a/include/net/flow_dissector.h\n+++ b/include/net/flow_dissector.h\n@@ -19,6 +19,15 @@ struct flow_dissector_key_control {\n #define FLOW_DIS_FIRST_FRAG\tBIT(1)\n #define FLOW_DIS_ENCAPSULATION\tBIT(2)\n \n+enum flow_dissect_ret {\n+\tFLOW_DISSECT_RET_OUT_GOOD,\n+\tFLOW_DISSECT_RET_OUT_BAD,\n+\tFLOW_DISSECT_RET_PROTO_AGAIN,\n+\tFLOW_DISSECT_RET_IPPROTO_AGAIN,\n+\tFLOW_DISSECT_RET_IPPROTO_AGAIN_EH,\n+\tFLOW_DISSECT_RET_CONTINUE,\n+};\n+\n /**\n  * struct flow_dissector_key_basic:\n  * @thoff: Transport header offset\ndiff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c\nindex e2eaa1ff948d..5110180a3e96 100644\n--- a/net/core/flow_dissector.c\n+++ b/net/core/flow_dissector.c\n@@ -115,12 +115,6 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,\n }\n EXPORT_SYMBOL(__skb_flow_get_ports);\n \n-enum flow_dissect_ret {\n-\tFLOW_DISSECT_RET_OUT_GOOD,\n-\tFLOW_DISSECT_RET_OUT_BAD,\n-\tFLOW_DISSECT_RET_OUT_PROTO_AGAIN,\n-};\n-\n static enum flow_dissect_ret\n __skb_flow_dissect_mpls(const struct sk_buff *skb,\n \t\t\tstruct flow_dissector *flow_dissector,\n@@ -341,7 +335,7 @@ __skb_flow_dissect_gre(const struct sk_buff *skb,\n \tif (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)\n \t\treturn FLOW_DISSECT_RET_OUT_GOOD;\n \n-\treturn FLOW_DISSECT_RET_OUT_PROTO_AGAIN;\n+\treturn FLOW_DISSECT_RET_PROTO_AGAIN;\n }\n \n static void\n@@ -431,6 +425,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \tstruct flow_dissector_key_icmp *key_icmp;\n \tstruct flow_dissector_key_tags *key_tags;\n \tstruct flow_dissector_key_vlan *key_vlan;\n+\tenum flow_dissect_ret fdret;\n \tbool skip_vlan = false;\n \tu8 ip_proto = 0;\n \tbool ret;\n@@ -482,14 +477,19 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t}\n \n proto_again:\n+\tfdret = FLOW_DISSECT_RET_CONTINUE;\n+\n \tswitch (proto) {\n \tcase htons(ETH_P_IP): {\n \t\tconst struct iphdr *iph;\n \t\tstruct iphdr _iph;\n-ip:\n+\n \t\tiph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);\n-\t\tif (!iph || iph->ihl < 5)\n-\t\t\tgoto out_bad;\n+\t\tif (!iph || iph->ihl < 5) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n+\t\t}\n+\n \t\tnhoff += iph->ihl * 4;\n \n \t\tip_proto = iph->protocol;\n@@ -509,19 +509,25 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\t\tkey_control->flags |= FLOW_DIS_IS_FRAGMENT;\n \n \t\t\tif (iph->frag_off & htons(IP_OFFSET)) {\n-\t\t\t\tgoto out_good;\n+\t\t\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\t\t\tbreak;\n \t\t\t} else {\n \t\t\t\tkey_control->flags |= FLOW_DIS_FIRST_FRAG;\n-\t\t\t\tif (!(flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG))\n-\t\t\t\t\tgoto out_good;\n+\t\t\t\tif (!(flags &\n+\t\t\t\t      FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) {\n+\t\t\t\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n \n \t\t__skb_flow_dissect_ipv4(skb, flow_dissector,\n \t\t\t\t\ttarget_container, data, iph);\n \n-\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_L3)\n-\t\t\tgoto out_good;\n+\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_L3) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\t\tbreak;\n+\t\t}\n \n \t\tbreak;\n \t}\n@@ -529,10 +535,11 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\tconst struct ipv6hdr *iph;\n \t\tstruct ipv6hdr _iph;\n \n-ipv6:\n \t\tiph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);\n-\t\tif (!iph)\n-\t\t\tgoto out_bad;\n+\t\tif (!iph) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n+\t\t}\n \n \t\tip_proto = iph->nexthdr;\n \t\tnhoff += sizeof(struct ipv6hdr);\n@@ -561,15 +568,17 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\t\t\t\t\t\t\t     target_container);\n \t\t\t\tkey_tags->flow_label = ntohl(flow_label);\n \t\t\t}\n-\t\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)\n-\t\t\t\tgoto out_good;\n+\t\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) {\n+\t\t\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\t\t\tbreak;\n+\t\t\t}\n \t\t}\n \n \t\t__skb_flow_dissect_ipv6(skb, flow_dissector,\n \t\t\t\t\ttarget_container, data, iph);\n \n \t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_L3)\n-\t\t\tgoto out_good;\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n \n \t\tbreak;\n \t}\n@@ -585,12 +594,17 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\tif (!vlan_tag_present || eth_type_vlan(skb->protocol)) {\n \t\t\tvlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan),\n \t\t\t\t\t\t    data, hlen, &_vlan);\n-\t\t\tif (!vlan)\n-\t\t\t\tgoto out_bad;\n+\t\t\tif (!vlan) {\n+\t\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\n \t\t\tproto = vlan->h_vlan_encapsulated_proto;\n \t\t\tnhoff += sizeof(*vlan);\n-\t\t\tif (skip_vlan)\n-\t\t\t\tgoto proto_again;\n+\t\t\tif (skip_vlan) {\n+\t\t\t\tfdret = FLOW_DISSECT_RET_PROTO_AGAIN;\n+\t\t\t\tbreak;\n+\t\t\t}\n \t\t}\n \n \t\tskip_vlan = true;\n@@ -613,7 +627,8 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\t\t}\n \t\t}\n \n-\t\tgoto proto_again;\n+\t\tfdret = FLOW_DISSECT_RET_PROTO_AGAIN;\n+\t\tbreak;\n \t}\n \tcase htons(ETH_P_PPP_SES): {\n \t\tstruct {\n@@ -621,18 +636,27 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\t\t__be16 proto;\n \t\t} *hdr, _hdr;\n \t\thdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);\n-\t\tif (!hdr)\n-\t\t\tgoto out_bad;\n+\t\tif (!hdr) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n+\t\t}\n+\n \t\tproto = hdr->proto;\n \t\tnhoff += PPPOE_SES_HLEN;\n \t\tswitch (proto) {\n \t\tcase htons(PPP_IP):\n-\t\t\tgoto ip;\n+\t\t\tproto = htons(ETH_P_IP);\n+\t\t\tfdret = FLOW_DISSECT_RET_PROTO_AGAIN;\n+\t\t\tbreak;\n \t\tcase htons(PPP_IPV6):\n-\t\t\tgoto ipv6;\n+\t\t\tproto = htons(ETH_P_IPV6);\n+\t\t\tfdret = FLOW_DISSECT_RET_PROTO_AGAIN;\n+\t\t\tbreak;\n \t\tdefault:\n-\t\t\tgoto out_bad;\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n \t\t}\n+\t\tbreak;\n \t}\n \tcase htons(ETH_P_TIPC): {\n \t\tstruct {\n@@ -640,8 +664,10 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\t\t__be32 srcnode;\n \t\t} *hdr, _hdr;\n \t\thdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);\n-\t\tif (!hdr)\n-\t\t\tgoto out_bad;\n+\t\tif (!hdr) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n+\t\t}\n \n \t\tif (dissector_uses_key(flow_dissector,\n \t\t\t\t       FLOW_DISSECTOR_KEY_TIPC_ADDRS)) {\n@@ -651,56 +677,63 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\t\tkey_addrs->tipcaddrs.srcnode = hdr->srcnode;\n \t\t\tkey_control->addr_type = FLOW_DISSECTOR_KEY_TIPC_ADDRS;\n \t\t}\n-\t\tgoto out_good;\n+\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\tbreak;\n \t}\n \n \tcase htons(ETH_P_MPLS_UC):\n \tcase htons(ETH_P_MPLS_MC):\n-mpls:\n-\t\tswitch (__skb_flow_dissect_mpls(skb, flow_dissector,\n+\t\tfdret = __skb_flow_dissect_mpls(skb, flow_dissector,\n \t\t\t\t\t\ttarget_container, data,\n-\t\t\t\t\t\tnhoff, hlen)) {\n-\t\tcase FLOW_DISSECT_RET_OUT_GOOD:\n-\t\t\tgoto out_good;\n-\t\tcase FLOW_DISSECT_RET_OUT_BAD:\n-\t\tdefault:\n-\t\t\tgoto out_bad;\n-\t\t}\n+\t\t\t\t\t\tnhoff, hlen);\n+\t\tbreak;\n \tcase htons(ETH_P_FCOE):\n-\t\tif ((hlen - nhoff) < FCOE_HEADER_LEN)\n-\t\t\tgoto out_bad;\n+\t\tif ((hlen - nhoff) < FCOE_HEADER_LEN) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n+\t\t}\n \n \t\tnhoff += FCOE_HEADER_LEN;\n-\t\tgoto out_good;\n+\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\tbreak;\n \n \tcase htons(ETH_P_ARP):\n \tcase htons(ETH_P_RARP):\n-\t\tswitch (__skb_flow_dissect_arp(skb, flow_dissector,\n+\t\tfdret = __skb_flow_dissect_arp(skb, flow_dissector,\n \t\t\t\t\t       target_container, data,\n-\t\t\t\t\t       nhoff, hlen)) {\n-\t\tcase FLOW_DISSECT_RET_OUT_GOOD:\n-\t\t\tgoto out_good;\n-\t\tcase FLOW_DISSECT_RET_OUT_BAD:\n-\t\tdefault:\n-\t\t\tgoto out_bad;\n-\t\t}\n+\t\t\t\t\t       nhoff, hlen);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\tbreak;\n+\t}\n+\n+\t/* Process result of proto processing */\n+\tswitch (fdret) {\n+\tcase FLOW_DISSECT_RET_OUT_GOOD:\n+\t\tgoto out_good;\n+\tcase FLOW_DISSECT_RET_PROTO_AGAIN:\n+\t\tgoto proto_again;\n+\tcase FLOW_DISSECT_RET_CONTINUE:\n+\tcase FLOW_DISSECT_RET_IPPROTO_AGAIN:\n+\tcase FLOW_DISSECT_RET_IPPROTO_AGAIN_EH:\n+\t\tbreak;\n+\tcase FLOW_DISSECT_RET_OUT_BAD:\n \tdefault:\n \t\tgoto out_bad;\n \t}\n \n ip_proto_again:\n+\tfdret = FLOW_DISSECT_RET_CONTINUE;\n+\n \tswitch (ip_proto) {\n \tcase IPPROTO_GRE:\n-\t\tswitch (__skb_flow_dissect_gre(skb, key_control, flow_dissector,\n+\t\tfdret = __skb_flow_dissect_gre(skb, key_control, flow_dissector,\n \t\t\t\t\t       target_container, data,\n-\t\t\t\t\t       &proto, &nhoff, &hlen, flags)) {\n-\t\tcase FLOW_DISSECT_RET_OUT_GOOD:\n-\t\t\tgoto out_good;\n-\t\tcase FLOW_DISSECT_RET_OUT_BAD:\n-\t\t\tgoto out_bad;\n-\t\tcase FLOW_DISSECT_RET_OUT_PROTO_AGAIN:\n-\t\t\tgoto proto_again;\n-\t\t}\n+\t\t\t\t\t       &proto, &nhoff, &hlen, flags);\n+\t\tbreak;\n+\n \tcase NEXTHDR_HOP:\n \tcase NEXTHDR_ROUTING:\n \tcase NEXTHDR_DEST: {\n@@ -711,13 +744,16 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \n \t\topthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr),\n \t\t\t\t\t      data, hlen, &_opthdr);\n-\t\tif (!opthdr)\n-\t\t\tgoto out_bad;\n+\t\tif (!opthdr) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n+\t\t}\n \n \t\tip_proto = opthdr[0];\n \t\tnhoff += (opthdr[1] + 1) << 3;\n \n-\t\tgoto ip_proto_again;\n+\t\tfdret = FLOW_DISSECT_RET_IPPROTO_AGAIN_EH;\n+\t\tbreak;\n \t}\n \tcase NEXTHDR_FRAGMENT: {\n \t\tstruct frag_hdr _fh, *fh;\n@@ -728,8 +764,10 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\tfh = __skb_header_pointer(skb, nhoff, sizeof(_fh),\n \t\t\t\t\t  data, hlen, &_fh);\n \n-\t\tif (!fh)\n-\t\t\tgoto out_bad;\n+\t\tif (!fh) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_BAD;\n+\t\t\tbreak;\n+\t\t}\n \n \t\tkey_control->flags |= FLOW_DIS_IS_FRAGMENT;\n \n@@ -738,34 +776,50 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \n \t\tif (!(fh->frag_off & htons(IP6_OFFSET))) {\n \t\t\tkey_control->flags |= FLOW_DIS_FIRST_FRAG;\n-\t\t\tif (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG)\n-\t\t\t\tgoto ip_proto_again;\n+\t\t\tif (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG) {\n+\t\t\t\tfdret = FLOW_DISSECT_RET_IPPROTO_AGAIN_EH;\n+\t\t\t\tbreak;\n+\t\t\t}\n \t\t}\n-\t\tgoto out_good;\n+\n+\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\tbreak;\n \t}\n \tcase IPPROTO_IPIP:\n \t\tproto = htons(ETH_P_IP);\n \n \t\tkey_control->flags |= FLOW_DIS_ENCAPSULATION;\n-\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)\n-\t\t\tgoto out_good;\n+\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tfdret = FLOW_DISSECT_RET_PROTO_AGAIN;\n+\t\tbreak;\n \n-\t\tgoto ip;\n \tcase IPPROTO_IPV6:\n \t\tproto = htons(ETH_P_IPV6);\n \n \t\tkey_control->flags |= FLOW_DIS_ENCAPSULATION;\n-\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)\n-\t\t\tgoto out_good;\n+\t\tif (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {\n+\t\t\tfdret = FLOW_DISSECT_RET_OUT_GOOD;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tfdret = FLOW_DISSECT_RET_PROTO_AGAIN;\n+\t\tbreak;\n+\n \n-\t\tgoto ipv6;\n \tcase IPPROTO_MPLS:\n \t\tproto = htons(ETH_P_MPLS_UC);\n-\t\tgoto mpls;\n+\t\tfdret = FLOW_DISSECT_RET_PROTO_AGAIN;\n+\t\tbreak;\n+\n \tcase IPPROTO_TCP:\n \t\t__skb_flow_dissect_tcp(skb, flow_dissector, target_container,\n \t\t\t\t       data, nhoff, hlen);\n \t\tbreak;\n+\n \tdefault:\n \t\tbreak;\n \t}\n@@ -787,6 +841,21 @@ bool __skb_flow_dissect(const struct sk_buff *skb,\n \t\tkey_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen);\n \t}\n \n+\t/* Process result of IP proto processing */\n+\tswitch (fdret) {\n+\tcase FLOW_DISSECT_RET_PROTO_AGAIN:\n+\t\tgoto proto_again;\n+\tcase FLOW_DISSECT_RET_IPPROTO_AGAIN:\n+\tcase FLOW_DISSECT_RET_IPPROTO_AGAIN_EH:\n+\t\tgoto ip_proto_again;\n+\tcase FLOW_DISSECT_RET_OUT_GOOD:\n+\tcase FLOW_DISSECT_RET_CONTINUE:\n+\t\tbreak;\n+\tcase FLOW_DISSECT_RET_OUT_BAD:\n+\tdefault:\n+\t\tgoto out_bad;\n+\t}\n+\n out_good:\n \tret = true;\n \n",
    "prefixes": [
        "net-next",
        "1/2"
    ]
}