Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/809464/?format=api
{ "id": 809464, "url": "http://patchwork.ozlabs.org/api/1.2/patches/809464/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1504478435-13160-7-git-send-email-pablo@netfilter.org/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/1.2/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": "<1504478435-13160-7-git-send-email-pablo@netfilter.org>", "list_archive_url": null, "date": "2017-09-03T22:40:17", "name": "[29/47] netfilter: exthdr: tcp option set support", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": true, "hash": "90acd2632239eaa8be950b659f45893e39aadfe9", "submitter": { "id": 1315, "url": "http://patchwork.ozlabs.org/api/1.2/people/1315/?format=api", "name": "Pablo Neira Ayuso", "email": "pablo@netfilter.org" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/1.2/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1504478435-13160-7-git-send-email-pablo@netfilter.org/mbox/", "series": [ { "id": 1283, "url": "http://patchwork.ozlabs.org/api/1.2/series/1283/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=1283", "date": "2017-09-03T22:40:11", "name": null, "version": 1, "mbox": "http://patchwork.ozlabs.org/series/1283/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/809464/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/809464/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>)", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xlp355BnMz9s06\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon, 4 Sep 2017 08:45:21 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1753317AbdICWlA (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tSun, 3 Sep 2017 18:41:00 -0400", "from mail.us.es ([193.147.175.20]:52730 \"EHLO mail.us.es\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1753294AbdICWk5 (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tSun, 3 Sep 2017 18:40:57 -0400", "from antivirus1-rhel7.int (unknown [192.168.2.11])\n\tby mail.us.es (Postfix) with ESMTP id CE0A8190F65\n\tfor <netdev@vger.kernel.org>; Mon, 4 Sep 2017 00:40:30 +0200 (CEST)", "from antivirus1-rhel7.int (localhost [127.0.0.1])\n\tby antivirus1-rhel7.int (Postfix) with ESMTP id B9D7EB5026\n\tfor <netdev@vger.kernel.org>; Mon, 4 Sep 2017 00:40:30 +0200 (CEST)", "by antivirus1-rhel7.int (Postfix, from userid 99)\n\tid AF6962DC84; Mon, 4 Sep 2017 00:40:30 +0200 (CEST)", "from antivirus1-rhel7.int (localhost [127.0.0.1])\n\tby antivirus1-rhel7.int (Postfix) with ESMTP id 53B27B5026;\n\tMon, 4 Sep 2017 00:40:27 +0200 (CEST)", "from 192.168.1.97 (192.168.1.97) by antivirus1-rhel7.int\n\t(F-Secure/fsigk_smtp/550/antivirus1-rhel7.int); \n\tMon, 04 Sep 2017 00:40:27 +0200 (CEST)", "from salvia.here (unknown [31.4.193.113])\n\t(Authenticated sender: 1984lsi)\n\tby entrada.int (Postfix) with ESMTPA id 08A304265A20;\n\tMon, 4 Sep 2017 00:40:26 +0200 (CEST)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.1 (2015-04-28) on\n\tantivirus1-rhel7.int", "X-Spam-Level": "", "X-Spam-Status": "No, score=-108.2 required=7.5 tests=ALL_TRUSTED,BAYES_50,\n\tSMTPAUTH_US2,USER_IN_WHITELIST autolearn=disabled version=3.4.1", "X-Virus-Status": "clean(F-Secure/fsigk_smtp/550/antivirus1-rhel7.int)", "X-SMTPAUTHUS": "auth mail.us.es", "From": "Pablo Neira Ayuso <pablo@netfilter.org>", "To": "netfilter-devel@vger.kernel.org", "Cc": "davem@davemloft.net, netdev@vger.kernel.org", "Subject": "[PATCH 29/47] netfilter: exthdr: tcp option set support", "Date": "Mon, 4 Sep 2017 00:40:17 +0200", "Message-Id": "<1504478435-13160-7-git-send-email-pablo@netfilter.org>", "X-Mailer": "git-send-email 2.1.4", "In-Reply-To": "<1504478435-13160-1-git-send-email-pablo@netfilter.org>", "References": "<1504478435-13160-1-git-send-email-pablo@netfilter.org>", "X-Virus-Scanned": "ClamAV using ClamSMTP", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "From: Florian Westphal <fw@strlen.de>\n\nThis allows setting 2 and 4 byte quantities in the tcp option space.\nMain purpose is to allow native replacement for xt_TCPMSS to\nwork around pmtu blackholes.\n\nWrites to kind and len are now allowed at the moment, it does not seem\nuseful to do this as it causes corruption of the tcp option space.\n\nWe can always lift this restriction later if a use-case appears.\n\nSigned-off-by: Florian Westphal <fw@strlen.de>\nSigned-off-by: Pablo Neira Ayuso <pablo@netfilter.org>\n---\n include/uapi/linux/netfilter/nf_tables.h | 4 +-\n net/netfilter/nft_exthdr.c | 164 ++++++++++++++++++++++++++++++-\n 2 files changed, 165 insertions(+), 3 deletions(-)", "diff": "diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h\nindex be25cf69295b..40fd199f7531 100644\n--- a/include/uapi/linux/netfilter/nf_tables.h\n+++ b/include/uapi/linux/netfilter/nf_tables.h\n@@ -732,7 +732,8 @@ enum nft_exthdr_op {\n * @NFTA_EXTHDR_OFFSET: extension header offset (NLA_U32)\n * @NFTA_EXTHDR_LEN: extension header length (NLA_U32)\n * @NFTA_EXTHDR_FLAGS: extension header flags (NLA_U32)\n- * @NFTA_EXTHDR_OP: option match type (NLA_U8)\n+ * @NFTA_EXTHDR_OP: option match type (NLA_U32)\n+ * @NFTA_EXTHDR_SREG: option match type (NLA_U32)\n */\n enum nft_exthdr_attributes {\n \tNFTA_EXTHDR_UNSPEC,\n@@ -742,6 +743,7 @@ enum nft_exthdr_attributes {\n \tNFTA_EXTHDR_LEN,\n \tNFTA_EXTHDR_FLAGS,\n \tNFTA_EXTHDR_OP,\n+\tNFTA_EXTHDR_SREG,\n \t__NFTA_EXTHDR_MAX\n };\n #define NFTA_EXTHDR_MAX\t\t(__NFTA_EXTHDR_MAX - 1)\ndiff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c\nindex e3a6eebe7e0c..f5a0bf5e3bdd 100644\n--- a/net/netfilter/nft_exthdr.c\n+++ b/net/netfilter/nft_exthdr.c\n@@ -8,6 +8,7 @@\n * Development of this code funded by Astaro AG (http://www.astaro.com/)\n */\n \n+#include <asm/unaligned.h>\n #include <linux/kernel.h>\n #include <linux/init.h>\n #include <linux/module.h>\n@@ -23,6 +24,7 @@ struct nft_exthdr {\n \tu8\t\t\tlen;\n \tu8\t\t\top;\n \tenum nft_registers\tdreg:8;\n+\tenum nft_registers\tsreg:8;\n \tu8\t\t\tflags;\n };\n \n@@ -124,6 +126,88 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr,\n \t\tregs->verdict.code = NFT_BREAK;\n }\n \n+static void nft_exthdr_tcp_set_eval(const struct nft_expr *expr,\n+\t\t\t\t struct nft_regs *regs,\n+\t\t\t\t const struct nft_pktinfo *pkt)\n+{\n+\tu8 buff[sizeof(struct tcphdr) + MAX_TCP_OPTION_SPACE];\n+\tstruct nft_exthdr *priv = nft_expr_priv(expr);\n+\tunsigned int i, optl, tcphdr_len, offset;\n+\tstruct tcphdr *tcph;\n+\tu8 *opt;\n+\tu32 src;\n+\n+\ttcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len);\n+\tif (!tcph)\n+\t\treturn;\n+\n+\topt = (u8 *)tcph;\n+\tfor (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) {\n+\t\tunion {\n+\t\t\tu8 octet;\n+\t\t\t__be16 v16;\n+\t\t\t__be32 v32;\n+\t\t} old, new;\n+\n+\t\toptl = optlen(opt, i);\n+\n+\t\tif (priv->type != opt[i])\n+\t\t\tcontinue;\n+\n+\t\tif (i + optl > tcphdr_len || priv->len + priv->offset > optl)\n+\t\t\treturn;\n+\n+\t\tif (!skb_make_writable(pkt->skb, pkt->xt.thoff + i + priv->len))\n+\t\t\treturn;\n+\n+\t\ttcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff,\n+\t\t\t\t\t &tcphdr_len);\n+\t\tif (!tcph)\n+\t\t\treturn;\n+\n+\t\tsrc = regs->data[priv->sreg];\n+\t\toffset = i + priv->offset;\n+\n+\t\tswitch (priv->len) {\n+\t\tcase 2:\n+\t\t\told.v16 = get_unaligned((u16 *)(opt + offset));\n+\t\t\tnew.v16 = src;\n+\n+\t\t\tswitch (priv->type) {\n+\t\t\tcase TCPOPT_MSS:\n+\t\t\t\t/* increase can cause connection to stall */\n+\t\t\t\tif (ntohs(old.v16) <= ntohs(new.v16))\n+\t\t\t\t\treturn;\n+\t\t\tbreak;\n+\t\t\t}\n+\n+\t\t\tif (old.v16 == new.v16)\n+\t\t\t\treturn;\n+\n+\t\t\tput_unaligned(new.v16, (u16*)(opt + offset));\n+\t\t\tinet_proto_csum_replace2(&tcph->check, pkt->skb,\n+\t\t\t\t\t\t old.v16, new.v16, false);\n+\t\t\tbreak;\n+\t\tcase 4:\n+\t\t\tnew.v32 = src;\n+\t\t\told.v32 = get_unaligned((u32 *)(opt + offset));\n+\n+\t\t\tif (old.v32 == new.v32)\n+\t\t\t\treturn;\n+\n+\t\t\tput_unaligned(new.v32, (u32*)(opt + offset));\n+\t\t\tinet_proto_csum_replace4(&tcph->check, pkt->skb,\n+\t\t\t\t\t\t old.v32, new.v32, false);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tWARN_ON_ONCE(1);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\treturn;\n+\t}\n+}\n+\n static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = {\n \t[NFTA_EXTHDR_DREG]\t\t= { .type = NLA_U32 },\n \t[NFTA_EXTHDR_TYPE]\t\t= { .type = NLA_U8 },\n@@ -180,6 +264,55 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,\n \t\t\t\t\t NFT_DATA_VALUE, priv->len);\n }\n \n+static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,\n+\t\t\t\t const struct nft_expr *expr,\n+\t\t\t\t const struct nlattr * const tb[])\n+{\n+\tstruct nft_exthdr *priv = nft_expr_priv(expr);\n+\tu32 offset, len, flags = 0, op = NFT_EXTHDR_OP_IPV6;\n+\tint err;\n+\n+\tif (!tb[NFTA_EXTHDR_SREG] ||\n+\t !tb[NFTA_EXTHDR_TYPE] ||\n+\t !tb[NFTA_EXTHDR_OFFSET] ||\n+\t !tb[NFTA_EXTHDR_LEN])\n+\t\treturn -EINVAL;\n+\n+\tif (tb[NFTA_EXTHDR_DREG] || tb[NFTA_EXTHDR_FLAGS])\n+\t\treturn -EINVAL;\n+\n+\terr = nft_parse_u32_check(tb[NFTA_EXTHDR_OFFSET], U8_MAX, &offset);\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\terr = nft_parse_u32_check(tb[NFTA_EXTHDR_LEN], U8_MAX, &len);\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\tif (offset < 2)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tswitch (len) {\n+\tcase 2: break;\n+\tcase 4: break;\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\terr = nft_parse_u32_check(tb[NFTA_EXTHDR_OP], U8_MAX, &op);\n+\tif (err < 0)\n+\t\treturn err;\n+\n+\tpriv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);\n+\tpriv->offset = offset;\n+\tpriv->len = len;\n+\tpriv->sreg = nft_parse_register(tb[NFTA_EXTHDR_SREG]);\n+\tpriv->flags = flags;\n+\tpriv->op = op;\n+\n+\treturn nft_validate_register_load(priv->sreg, priv->len);\n+}\n+\n static int nft_exthdr_dump_common(struct sk_buff *skb, const struct nft_exthdr *priv)\n {\n \tif (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type))\n@@ -208,6 +341,16 @@ static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr)\n \treturn nft_exthdr_dump_common(skb, priv);\n }\n \n+static int nft_exthdr_dump_set(struct sk_buff *skb, const struct nft_expr *expr)\n+{\n+\tconst struct nft_exthdr *priv = nft_expr_priv(expr);\n+\n+\tif (nft_dump_register(skb, NFTA_EXTHDR_SREG, priv->sreg))\n+\t\treturn -1;\n+\n+\treturn nft_exthdr_dump_common(skb, priv);\n+}\n+\n static struct nft_expr_type nft_exthdr_type;\n static const struct nft_expr_ops nft_exthdr_ipv6_ops = {\n \t.type\t\t= &nft_exthdr_type,\n@@ -225,6 +368,14 @@ static const struct nft_expr_ops nft_exthdr_tcp_ops = {\n \t.dump\t\t= nft_exthdr_dump,\n };\n \n+static const struct nft_expr_ops nft_exthdr_tcp_set_ops = {\n+\t.type\t\t= &nft_exthdr_type,\n+\t.size\t\t= NFT_EXPR_SIZE(sizeof(struct nft_exthdr)),\n+\t.eval\t\t= nft_exthdr_tcp_set_eval,\n+\t.init\t\t= nft_exthdr_tcp_set_init,\n+\t.dump\t\t= nft_exthdr_dump_set,\n+};\n+\n static const struct nft_expr_ops *\n nft_exthdr_select_ops(const struct nft_ctx *ctx,\n \t\t const struct nlattr * const tb[])\n@@ -234,12 +385,21 @@ nft_exthdr_select_ops(const struct nft_ctx *ctx,\n \tif (!tb[NFTA_EXTHDR_OP])\n \t\treturn &nft_exthdr_ipv6_ops;\n \n+\tif (tb[NFTA_EXTHDR_SREG] && tb[NFTA_EXTHDR_DREG])\n+\t\treturn ERR_PTR(-EOPNOTSUPP);\n+\n \top = ntohl(nla_get_u32(tb[NFTA_EXTHDR_OP]));\n \tswitch (op) {\n \tcase NFT_EXTHDR_OP_TCPOPT:\n-\t\treturn &nft_exthdr_tcp_ops;\n+\t\tif (tb[NFTA_EXTHDR_SREG])\n+\t\t\treturn &nft_exthdr_tcp_set_ops;\n+\t\tif (tb[NFTA_EXTHDR_DREG])\n+\t\t\treturn &nft_exthdr_tcp_ops;\n+\t\tbreak;\n \tcase NFT_EXTHDR_OP_IPV6:\n-\t\treturn &nft_exthdr_ipv6_ops;\n+\t\tif (tb[NFTA_EXTHDR_DREG])\n+\t\t\treturn &nft_exthdr_ipv6_ops;\n+\t\tbreak;\n \t}\n \n \treturn ERR_PTR(-EOPNOTSUPP);\n", "prefixes": [ "29/47" ] }