get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 808997,
    "url": "http://patchwork.ozlabs.org/api/patches/808997/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/20170901210412.2915-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": "<20170901210412.2915-2-tom@quantonium.net>",
    "list_archive_url": null,
    "date": "2017-09-01T21:04:11",
    "name": "[v2,net-next,1/2] flow_dissector: Cleanup control flow",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "af7c180d84ad3bbfbc10ed144e72ec0402045c32",
    "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/20170901210412.2915-2-tom@quantonium.net/mbox/",
    "series": [
        {
            "id": 1115,
            "url": "http://patchwork.ozlabs.org/api/series/1115/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=1115",
            "date": "2017-09-01T21:04:10",
            "name": "flow_dissector: Flow dissector fixes",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/1115/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/808997/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/808997/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=\"sfCnTftQ\"; dkim-atps=neutral"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xkWw21Cy1z9sNr\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSat,  2 Sep 2017 07:04:50 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752532AbdIAVEs (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tFri, 1 Sep 2017 17:04:48 -0400",
            "from mail-pg0-f47.google.com ([74.125.83.47]:36034 \"EHLO\n\tmail-pg0-f47.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1752416AbdIAVEr (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Fri, 1 Sep 2017 17:04:47 -0400",
            "by mail-pg0-f47.google.com with SMTP id r133so3613700pgr.3\n\tfor <netdev@vger.kernel.org>; Fri, 01 Sep 2017 14:04:46 -0700 (PDT)",
            "from localhost.localdomain (67-207-98-108.static.wiline.com.\n\t[67.207.98.108]) by smtp.gmail.com with ESMTPSA id\n\ti187sm1381624pfe.67.2017.09.01.14.04.45\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tFri, 01 Sep 2017 14:04:45 -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=k3nrUBckF4s0eo5PtwdpTykSh1lRC2igDjJ7meE25NA=;\n\tb=sfCnTftQrpV0lPZ48CVbjCfIslL+JMcYJyigl1YPris9+9yOf/CtpN+K679qBmJpO6\n\tgj0ZGnKNig+EH5eEqeak5eBWKNhyxcvTxkd0BMxT4mkD3Rcw4smjK7esnzs1/FaGs3+o\n\tj+9s/BU238ApcyJ5l/yk7w63ZUEzxplNJzUOHDhqXS4Ijz/fym9N56QrLreb/4ZPh+y8\n\tee8H6jEltg7vgZefeCdAW5EgDfI4kgkLb+w0OpNWavRs6vIcXVjhfh2WxeD/5SJ2/3NM\n\tO7kHUyWmkFPGQb/WzM7jmkdrEzy/g6KGgIx1+cDkJkcN4F7B3fkefChAd5khbeehVpDD\n\t8pgw==",
        "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=k3nrUBckF4s0eo5PtwdpTykSh1lRC2igDjJ7meE25NA=;\n\tb=A9pvZUxWGxgVmSJ+OaQ/t9QqyXYwfmACcCLqqKNHQ50vexQYibVU3m3DPLxcOYSfb9\n\tDZuT7r8wgc4qeVWl/+41Fng/fk6lSh+x7ZA3OTRpRovBE/DNeNpvLnToeQroPO11VXRD\n\tNV+gkRNL/qpa15WQ17ARzjVgFdCcaodmIsboSn5SbnO+//b92itmPRIzEgaCKbKQP6MT\n\tixl91xIFGbR1wEVeyUfoiXOGxwUsIWbuATeTSgm80eruyGXGZWbr+LLAPheNUFUuiRvb\n\taaEGD7hFVr7qLslgHUMv3W3Eq87r1nAWGZZSwTqWf2u96s9plKftFVZQZyjXk4Is+i27\n\t0cNw==",
        "X-Gm-Message-State": "AHPjjUjVFln6kYdE/j2HlOTgFjhZuey+NMUQnePW00GA8CVni/SkNaTh\n\tIkuJZ85eY6VLTPfk",
        "X-Google-Smtp-Source": "ADKCNb7o02umcQknEdyezdtMbU0Apw2wjhIy1XD4FsBtv0wrpiaWv6NubB8phPKEz79fSfZb2+2C9w==",
        "X-Received": "by 10.99.172.87 with SMTP id z23mr3771780pgn.42.1504299886512;\n\tFri, 01 Sep 2017 14:04:46 -0700 (PDT)",
        "From": "Tom Herbert <tom@quantonium.net>",
        "To": "davem@davemloft.net",
        "Cc": "netdev@vger.kernel.org, hannes@stressinduktion.org,\n\talex.popov@linux.com, Tom Herbert <tom@quantonium.net>",
        "Subject": "[PATCH v2 net-next 1/2] flow_dissector: Cleanup control flow",
        "Date": "Fri,  1 Sep 2017 14:04:11 -0700",
        "Message-Id": "<20170901210412.2915-2-tom@quantonium.net>",
        "X-Mailer": "git-send-email 2.11.0",
        "In-Reply-To": "<20170901210412.2915-1-tom@quantonium.net>",
        "References": "<20170901210412.2915-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 |   8 ++\n net/core/flow_dissector.c    | 223 ++++++++++++++++++++++++++++---------------\n 2 files changed, 153 insertions(+), 78 deletions(-)",
    "diff": "diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h\nindex e2663e900b0a..fc3dce730a6b 100644\n--- a/include/net/flow_dissector.h\n+++ b/include/net/flow_dissector.h\n@@ -19,6 +19,14 @@ 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_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..e0ea17d1c7fc 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,62 @@ 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+\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 +743,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;\n+\t\tbreak;\n \t}\n \tcase NEXTHDR_FRAGMENT: {\n \t\tstruct frag_hdr _fh, *fh;\n@@ -728,8 +763,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 +775,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;\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 +840,20 @@ 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+\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": [
        "v2",
        "net-next",
        "1/2"
    ]
}