Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1149674/?format=api
{ "id": 1149674, "url": "http://patchwork.ozlabs.org/api/patches/1149674/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1566254665-5200-4-git-send-email-tom@herbertland.com/", "project": { "id": 46, "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api", "name": "Intel Wired Ethernet development", "link_name": "intel-wired-lan", "list_id": "intel-wired-lan.osuosl.org", "list_email": "intel-wired-lan@osuosl.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1566254665-5200-4-git-send-email-tom@herbertland.com>", "list_archive_url": null, "date": "2019-08-19T22:44:21", "name": "[v3,net-next,3/7] ipeh: Generic TLV parser", "commit_ref": null, "pull_url": null, "state": "rejected", "archived": false, "hash": "2d5cc82b132616d253cfda718381d7dbbe38b04f", "submitter": { "id": 65986, "url": "http://patchwork.ozlabs.org/api/people/65986/?format=api", "name": "Tom Herbert", "email": "tom@herbertland.com" }, "delegate": { "id": 68, "url": "http://patchwork.ozlabs.org/api/users/68/?format=api", "username": "jtkirshe", "first_name": "Jeff", "last_name": "Kirsher", "email": "jeffrey.t.kirsher@intel.com" }, "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/1566254665-5200-4-git-send-email-tom@herbertland.com/mbox/", "series": [ { "id": 126065, "url": "http://patchwork.ozlabs.org/api/series/126065/?format=api", "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=126065", "date": "2019-08-19T22:44:18", "name": "ipv6: Extension header infrastructure", "version": 3, "mbox": "http://patchwork.ozlabs.org/series/126065/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1149674/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1149674/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<intel-wired-lan-bounces@osuosl.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "Intel-wired-lan@lists.osuosl.org" ], "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "Intel-wired-lan@lists.osuosl.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.138; helo=whitealder.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dmarc=none (p=none dis=none)\n\theader.from=herbertland.com", "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=herbertland-com.20150623.gappssmtp.com\n\theader.i=@herbertland-com.20150623.gappssmtp.com\n\theader.b=\"QuuRDylC\"; dkim-atps=neutral" ], "Received": [ "from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 46C8Bh50c9z9sN1\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 20 Aug 2019 08:45:00 +1000 (AEST)", "from localhost (localhost [127.0.0.1])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 29C9D86ADB;\n\tMon, 19 Aug 2019 22:44:58 +0000 (UTC)", "from whitealder.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id B75zBdWWWkJV; Mon, 19 Aug 2019 22:44:56 +0000 (UTC)", "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby whitealder.osuosl.org (Postfix) with ESMTP id 0D1DC86457;\n\tMon, 19 Aug 2019 22:44:56 +0000 (UTC)", "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\tby ash.osuosl.org (Postfix) with ESMTP id 8DC0A1BF2AB\n\tfor <Intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Aug 2019 22:44:54 +0000 (UTC)", "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id 889682226B\n\tfor <Intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Aug 2019 22:44:54 +0000 (UTC)", "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id JeDhZpIzMTft for <Intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Aug 2019 22:44:51 +0000 (UTC)", "from mail-pl1-f195.google.com (mail-pl1-f195.google.com\n\t[209.85.214.195])\n\tby silver.osuosl.org (Postfix) with ESMTPS id DA0CD2044F\n\tfor <Intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Aug 2019 22:44:51 +0000 (UTC)", "by mail-pl1-f195.google.com with SMTP id m9so1658687pls.8\n\tfor <Intel-wired-lan@lists.osuosl.org>;\n\tMon, 19 Aug 2019 15:44:51 -0700 (PDT)", "from localhost.localdomain (c-73-202-182-113.hsd1.ca.comcast.net.\n\t[73.202.182.113]) by smtp.gmail.com with ESMTPSA id\n\tx10sm14676947pjo.4.2019.08.19.15.44.49\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tMon, 19 Aug 2019 15:44:50 -0700 (PDT)" ], "X-Virus-Scanned": [ "amavisd-new at osuosl.org", "amavisd-new at osuosl.org" ], "X-Greylist": "from auto-whitelisted by SQLgrey-1.7.6", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=herbertland-com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=Qg3ELsCDd2TlkD3X4Kus7eMR+Pz9DIIAqMi2dpjbmxg=;\n\tb=QuuRDylC/qEOp4oN1gFPLPvbU0IipFdNL+qquqHdoCQJnWsuWxnwzrLhnmkSzRcyyQ\n\ttDrbm6qfEhQ+8FwxoL7FRWxbpFwboZB3usCo3DQyzj9CDrCOHxdeqcnrtrwRNGCb9Hx5\n\tsOpsqILdpF8S5xrmM6apkd+wKwVj4E9NPQvSimVIRMe7gG85hMjLhoXTR8gCyDfbzZWp\n\tCpG4gqIXNt6MOja7RNLIsTopiTqvAQh0reD2m9XNrqNtkG2QbbqZ5p8Cml8uskIeD3+o\n\t8yBvQ233A4Li1V6cn46B/vazynfiqVbUh+jk9cuHLJ8aVxDPOfAGqHjH8798+JYfarvU\n\tKqiw==", "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=Qg3ELsCDd2TlkD3X4Kus7eMR+Pz9DIIAqMi2dpjbmxg=;\n\tb=hBq3YC3zg5zDkxoK091urhskbLSaRRf7oEetU2vBIBd7Jm++5UFuwwmh3oqmq97v/j\n\t/zC5BcOnQ+fskkW3S8SmLSwXy6nL1rYYjsOTd0Jy5uAJMAaNQMnnY8loI3XTy/Md20Lo\n\tgJi2/XGw5/rjamu38HjmInnhdIuyatz3nEkUllHMKjaE2FnrQld7Nq8I+u74OW8PRevN\n\t6R7zZYYR2e7MITIh8ZAGVFjqxmaekzpZEc4JpDuTfJuA48ojmCkxbTfhbd0SSQ3Zlo/a\n\t56ulcW8ZZ47BkhS2qgxF0VJpLKbnQCUGUF75t9DKHu2y6u2OUeFC5PvA52fuTgPSTE1u\n\typWQ==", "X-Gm-Message-State": "APjAAAUY96c0JqwyJrllL/wZwiea7RL+xdimh3pkDYYcsw3ZCpTHwh/2\n\toz+wZA4xzV2IGemf+4bU7P+mlXrIApk=", "X-Google-Smtp-Source": "APXvYqzJioCoOMgTf59fgC3Yr1knjeWPBQueYxhwAoYK28KlkW+1/GTI7Knl1cww0+y1Q2RnROrUoA==", "X-Received": "by 2002:a17:902:9f8e:: with SMTP id\n\tg14mr25223590plq.67.1566254690871; \n\tMon, 19 Aug 2019 15:44:50 -0700 (PDT)", "From": "Tom Herbert <tom@herbertland.com>", "To": "Intel-wired-lan@lists.osuosl.org", "Date": "Mon, 19 Aug 2019 15:44:21 -0700", "Message-Id": "<1566254665-5200-4-git-send-email-tom@herbertland.com>", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1566254665-5200-1-git-send-email-tom@herbertland.com>", "References": "<1566254665-5200-1-git-send-email-tom@herbertland.com>", "Subject": "[Intel-wired-lan] [PATCH v3 net-next 3/7] ipeh: Generic TLV parser", "X-BeenThere": "intel-wired-lan@osuosl.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>", "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>", "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>", "List-Post": "<mailto:intel-wired-lan@osuosl.org>", "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>", "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>", "Cc": "Tom Herbert <tom@herbertland.com>, Tom Herbert <tom@quantonium.net>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Errors-To": "intel-wired-lan-bounces@osuosl.org", "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>" }, "content": "From: Tom Herbert <tom@quantonium.net>\n\nCreate a generic TLV parser. This will be used with various\nextension headers that carry options including Destination,\nHop-by-Hop, Segment Routing TLVs, and other cases of simple\nstateless parsing.\n\nSigned-off-by: Tom Herbert <tom@herbertland.com>\n---\n include/net/ipeh.h | 25 ++++++++\n net/ipv6/exthdrs.c | 159 +++++++++++-----------------------------------\n net/ipv6/exthdrs_common.c | 114 +++++++++++++++++++++++++++++++++\n 3 files changed, 177 insertions(+), 121 deletions(-)", "diff": "diff --git a/include/net/ipeh.h b/include/net/ipeh.h\nindex 3b24831..c1aa7b6 100644\n--- a/include/net/ipeh.h\n+++ b/include/net/ipeh.h\n@@ -31,4 +31,29 @@ struct ipv6_txoptions *ipeh_renew_options(struct sock *sk,\n struct ipv6_txoptions *ipeh_fixup_options(struct ipv6_txoptions *opt_space,\n \t\t\t\t\t struct ipv6_txoptions *opt);\n \n+/* Generic extension header TLV parser */\n+\n+enum ipeh_parse_errors {\n+\tIPEH_PARSE_ERR_PAD1,\t\t/* Excessive PAD1 */\n+\tIPEH_PARSE_ERR_PADN,\t\t/* Excessive PADN */\n+\tIPEH_PARSE_ERR_PADNZ,\t\t/* Non-zero padding data */\n+\tIPEH_PARSE_ERR_EH_TOOBIG,\t/* Length of EH exceeds limit */\n+\tIPEH_PARSE_ERR_OPT_TOOBIG,\t/* Option size exceeds limit */\n+\tIPEH_PARSE_ERR_OPT_TOOMANY,\t/* Option count exceeds limit */\n+\tIPEH_PARSE_ERR_OPT_UNK_DISALW,\t/* Unknown option disallowed */\n+\tIPEH_PARSE_ERR_OPT_UNK,\t\t/* Unknown option */\n+};\n+\n+/* The generic TLV parser assumes that the type value of PAD1 is 0, and PADN\n+ * is 1. This is true for Destination, Hop-by-Hop and current definition\n+ * of Segment Routing TLVs.\n+ */\n+#define IPEH_TLV_PAD1\t0\n+#define IPEH_TLV_PADN\t1\n+\n+bool ipeh_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb,\n+\t\t int max_count, int off, int len,\n+\t\t bool (*parse_error)(struct sk_buff *skb,\n+\t\t\t\t\tint off, enum ipeh_parse_errors error));\n+\n #endif /* _NET_IPEH_H */\ndiff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c\nindex e12d3a5..939d27c 100644\n--- a/net/ipv6/exthdrs.c\n+++ b/net/ipv6/exthdrs.c\n@@ -54,135 +54,50 @@\n Generic functions\n *********************/\n \n-/* An unknown option is detected, decide what to do */\n-\n-static bool ip6_tlvopt_unknown(struct sk_buff *skb, int optoff,\n-\t\t\t bool disallow_unknowns)\n+/* Handle parse errors from ipeh generic TLV parser */\n+static bool ipv6_parse_error(struct sk_buff *skb, int off,\n+\t\t\t enum ipeh_parse_errors error)\n {\n-\tif (disallow_unknowns) {\n-\t\t/* If unknown TLVs are disallowed by configuration\n-\t\t * then always silently drop packet. Note this also\n-\t\t * means no ICMP parameter problem is sent which\n-\t\t * could be a good property to mitigate a reflection DOS\n-\t\t * attack.\n-\t\t */\n-\n-\t\tgoto drop;\n-\t}\n-\n-\tswitch ((skb_network_header(skb)[optoff] & 0xC0) >> 6) {\n-\tcase 0: /* ignore */\n-\t\treturn true;\n-\n-\tcase 1: /* drop packet */\n-\t\tbreak;\n-\n-\tcase 3: /* Send ICMP if not a multicast address and drop packet */\n-\t\t/* Actually, it is redundant check. icmp_send\n-\t\t will recheck in any case.\n-\t\t */\n-\t\tif (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))\n+\tswitch (error) {\n+\tcase IPEH_PARSE_ERR_OPT_UNK_DISALW:\n+\t\t/* Disallow unknown skip */\n+\t\tif (((skb_network_header(skb)[off] & 0xC0) >> 6) == 0) {\n+\t\t\t/* Silent drop */\n \t\t\tbreak;\n+\t\t}\n \t\t/* fall through */\n-\tcase 2: /* send ICMP PARM PROB regardless and drop packet */\n-\t\ticmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);\n-\t\treturn false;\n-\t}\n-\n-drop:\n-\tkfree_skb(skb);\n-\treturn false;\n-}\n+\tcase IPEH_PARSE_ERR_OPT_UNK:\n+\t\tswitch ((skb_network_header(skb)[off] & 0xC0) >> 6) {\n+\t\tcase 0: /* ignore */\n+\t\t\treturn true;\n \n-/* Parse tlv encoded option header (hop-by-hop or destination) */\n-\n-static bool ip6_parse_tlv(const struct tlvtype_proc *procs,\n-\t\t\t struct sk_buff *skb,\n-\t\t\t int max_count)\n-{\n-\tint len = (skb_transport_header(skb)[1] + 1) << 3;\n-\tconst unsigned char *nh = skb_network_header(skb);\n-\tint off = skb_network_header_len(skb);\n-\tconst struct tlvtype_proc *curr;\n-\tbool disallow_unknowns = false;\n-\tint tlv_count = 0;\n-\tint padlen = 0;\n-\n-\tif (unlikely(max_count < 0)) {\n-\t\tdisallow_unknowns = true;\n-\t\tmax_count = -max_count;\n-\t}\n-\n-\tif (skb_transport_offset(skb) + len > skb_headlen(skb))\n-\t\tgoto bad;\n-\n-\toff += 2;\n-\tlen -= 2;\n-\n-\twhile (len > 0) {\n-\t\tint optlen = nh[off + 1] + 2;\n-\t\tint i;\n-\n-\t\tswitch (nh[off]) {\n-\t\tcase IPV6_TLV_PAD1:\n-\t\t\toptlen = 1;\n-\t\t\tpadlen++;\n-\t\t\tif (padlen > 7)\n-\t\t\t\tgoto bad;\n+\t\tcase 1: /* drop packet */\n \t\t\tbreak;\n \n-\t\tcase IPV6_TLV_PADN:\n-\t\t\t/* RFC 2460 states that the purpose of PadN is\n-\t\t\t * to align the containing header to multiples\n-\t\t\t * of 8. 7 is therefore the highest valid value.\n-\t\t\t * See also RFC 4942, Section 2.1.9.5.\n-\t\t\t */\n-\t\t\tpadlen += optlen;\n-\t\t\tif (padlen > 7)\n-\t\t\t\tgoto bad;\n-\t\t\t/* RFC 4942 recommends receiving hosts to\n-\t\t\t * actively check PadN payload to contain\n-\t\t\t * only zeroes.\n+\t\tcase 3: /* Send ICMP if not a multicast address and drop packet\n+\t\t\t *\n+\t\t\t * Actually, it is redundant check. icmp_send\n+\t\t\t * will recheck in any case.\n \t\t\t */\n-\t\t\tfor (i = 2; i < optlen; i++) {\n-\t\t\t\tif (nh[off + i] != 0)\n-\t\t\t\t\tgoto bad;\n-\t\t\t}\n-\t\t\tbreak;\n+\t\t\tif (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))\n+\t\t\t\tbreak;\n \n-\t\tdefault: /* Other TLV code so scan list */\n-\t\t\tif (optlen > len)\n-\t\t\t\tgoto bad;\n-\n-\t\t\ttlv_count++;\n-\t\t\tif (tlv_count > max_count)\n-\t\t\t\tgoto bad;\n-\n-\t\t\tfor (curr = procs; curr->type >= 0; curr++) {\n-\t\t\t\tif (curr->type == nh[off]) {\n-\t\t\t\t\t/* type specific length/alignment\n-\t\t\t\t\t checks will be performed in the\n-\t\t\t\t\t func(). */\n-\t\t\t\t\tif (curr->func(skb, off) == false)\n-\t\t\t\t\t\treturn false;\n-\t\t\t\t\tbreak;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\tif (curr->type < 0 &&\n-\t\t\t !ip6_tlvopt_unknown(skb, off, disallow_unknowns))\n-\t\t\t\treturn false;\n-\n-\t\t\tpadlen = 0;\n+\t\t\t/* fall through */\n+\t\tcase 2: /* send ICMP PARM PROB regardless and drop packet */\n+\t\t\ticmpv6_send(skb, ICMPV6_PARAMPROB,\n+\t\t\t\t ICMPV6_UNK_OPTION, off);\n \t\t\tbreak;\n \t\t}\n-\t\toff += optlen;\n-\t\tlen -= optlen;\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\n \t}\n \n-\tif (len == 0)\n-\t\treturn true;\n-bad:\n-\tkfree_skb(skb);\n+\t/* Will be dropping packet */\n+\n+\t__IP6_INC_STATS(dev_net(skb->dev), __in6_dev_get(skb->dev),\n+\t\t\tIPSTATS_MIB_INHDRERRORS);\n+\n \treturn false;\n }\n \n@@ -216,8 +131,9 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)\n \tdstbuf = opt->dst1;\n #endif\n \n-\tif (ip6_parse_tlv(tlvprocdestopt_lst, skb,\n-\t\t\t init_net.ipv6.sysctl.max_dst_opts_cnt)) {\n+\tif (ipeh_parse_tlv(tlvprocdestopt_lst, skb,\n+\t\t\t init_net.ipv6.sysctl.max_dst_opts_cnt,\n+\t\t\t 2, extlen - 2, ipv6_parse_error)) {\n \t\tskb->transport_header += extlen;\n \t\topt = IP6CB(skb);\n #if IS_ENABLED(CONFIG_IPV6_MIP6)\n@@ -639,8 +555,9 @@ int ipv6_parse_hopopts(struct sk_buff *skb)\n \t\tgoto fail_and_free;\n \n \topt->flags |= IP6SKB_HOPBYHOP;\n-\tif (ip6_parse_tlv(tlvprochopopt_lst, skb,\n-\t\t\t init_net.ipv6.sysctl.max_hbh_opts_cnt)) {\n+\tif (ipeh_parse_tlv(tlvprochopopt_lst, skb,\n+\t\t\t init_net.ipv6.sysctl.max_hbh_opts_cnt,\n+\t\t\t 2, extlen - 2, ipv6_parse_error)) {\n \t\tskb->transport_header += extlen;\n \t\topt = IP6CB(skb);\n \t\topt->nhoff = sizeof(struct ipv6hdr);\ndiff --git a/net/ipv6/exthdrs_common.c b/net/ipv6/exthdrs_common.c\nindex 2c68184..99a0911 100644\n--- a/net/ipv6/exthdrs_common.c\n+++ b/net/ipv6/exthdrs_common.c\n@@ -142,3 +142,117 @@ struct ipv6_txoptions *ipeh_fixup_options(struct ipv6_txoptions *opt_space,\n \treturn opt;\n }\n EXPORT_SYMBOL_GPL(ipeh_fixup_options);\n+\n+/* Generic extension header TLV parser\n+ *\n+ * Arguments:\n+ * - skb_transport_header points to the extension header containing options\n+ * - off is offset from skb_transport_header where first TLV is\n+ * - len is length of TLV block\n+ */\n+bool ipeh_parse_tlv(const struct tlvtype_proc *procs, struct sk_buff *skb,\n+\t\t int max_count, int off, int len,\n+\t\t bool (*parse_error)(struct sk_buff *skb,\n+\t\t\t\t\tint off, enum ipeh_parse_errors error))\n+{\n+\tconst unsigned char *nh = skb_network_header(skb);\n+\tconst struct tlvtype_proc *curr;\n+\tbool disallow_unknowns = false;\n+\tint tlv_count = 0;\n+\tint padlen = 0;\n+\n+\tif (unlikely(max_count < 0)) {\n+\t\tdisallow_unknowns = true;\n+\t\tmax_count = -max_count;\n+\t}\n+\n+\tif (skb_transport_offset(skb) + off + len > skb_headlen(skb)) {\n+\t\tif (!parse_error(skb, skb_transport_offset(skb),\n+\t\t\t\t IPEH_PARSE_ERR_EH_TOOBIG))\n+\t\t\tgoto bad;\n+\n+\t\tlen = skb_headlen(skb) - skb_transport_offset(skb) - off;\n+\t}\n+\n+\t/* ops function based offset on network header */\n+\toff += skb_network_header_len(skb);\n+\n+\twhile (len > 0) {\n+\t\tint optlen = nh[off + 1] + 2;\n+\t\tint i;\n+\n+\t\tswitch (nh[off]) {\n+\t\tcase IPEH_TLV_PAD1:\n+\t\t\toptlen = 1;\n+\t\t\tpadlen++;\n+\t\t\tif (padlen > 7 &&\n+\t\t\t !parse_error(skb, off, IPEH_PARSE_ERR_PAD1))\n+\t\t\t\tgoto bad;\n+\n+\t\t\tbreak;\n+\n+\t\tcase IPEH_TLV_PADN:\n+\t\t\t/* RFC 2460 states that the purpose of PadN is\n+\t\t\t * to align the containing header to multiples\n+\t\t\t * of 8. 7 is therefore the highest valid value.\n+\t\t\t * See also RFC 4942, Section 2.1.9.5.\n+\t\t\t */\n+\t\t\tpadlen += optlen;\n+\t\t\tif (padlen > 7 &&\n+\t\t\t !parse_error(skb, off, IPEH_PARSE_ERR_PADN))\n+\t\t\t\tgoto bad;\n+\n+\t\t\t/* RFC 4942 recommends receiving hosts to\n+\t\t\t * actively check PadN payload to contain\n+\t\t\t * only zeroes.\n+\t\t\t */\n+\t\t\tfor (i = 2; i < optlen; i++) {\n+\t\t\t\tif (nh[off + i] != 0 &&\n+\t\t\t\t !parse_error(skb, off + i,\n+\t\t\t\t\t\t IPEH_PARSE_ERR_PADNZ))\n+\t\t\t\t\tgoto bad;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tdefault: /* Other TLV code so scan list */\n+\t\t\tif (optlen > len &&\n+\t\t\t !parse_error(skb, off, IPEH_PARSE_ERR_OPT_TOOBIG))\n+\t\t\t\tgoto bad;\n+\n+\t\t\ttlv_count++;\n+\t\t\tif (tlv_count > max_count &&\n+\t\t\t parse_error(skb, off, IPEH_PARSE_ERR_OPT_TOOMANY))\n+\t\t\t\tgoto bad;\n+\n+\t\t\tfor (curr = procs; curr->type >= 0; curr++) {\n+\t\t\t\tif (curr->type == nh[off]) {\n+\t\t\t\t\t/* type specific length/alignment\n+\t\t\t\t\t * checks will be performed in the\n+\t\t\t\t\t * func().\n+\t\t\t\t\t */\n+\t\t\t\t\tif (curr->func(skb, off) == false)\n+\t\t\t\t\t\treturn false;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tif (curr->type < 0 &&\n+\t\t\t !parse_error(skb, off,\n+\t\t\t\t\t disallow_unknowns ?\n+\t\t\t\t\t\tIPEH_PARSE_ERR_OPT_UNK_DISALW :\n+\t\t\t\t\t\tIPEH_PARSE_ERR_OPT_UNK))\n+\t\t\t\tgoto bad;\n+\n+\t\t\tpadlen = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t\toff += optlen;\n+\t\tlen -= optlen;\n+\t}\n+\n+\tif (len == 0)\n+\t\treturn true;\n+bad:\n+\tkfree_skb(skb);\n+\treturn false;\n+}\n+EXPORT_SYMBOL(ipeh_parse_tlv);\n", "prefixes": [ "v3", "net-next", "3/7" ] }