get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2231771,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2231771/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260501122237.296262-5-pablo@netfilter.org/",
    "project": {
        "id": 26,
        "url": "http://patchwork.ozlabs.org/api/1.1/projects/26/?format=api",
        "name": "Netfilter Development",
        "link_name": "netfilter-devel",
        "list_id": "netfilter-devel.vger.kernel.org",
        "list_email": "netfilter-devel@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null
    },
    "msgid": "<20260501122237.296262-5-pablo@netfilter.org>",
    "date": "2026-05-01T12:22:27",
    "name": "[net,04/14] netfilter: x_tables: add .check_hooks to matches and targets",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "796a2f57417cca9264fe7fe3dfe150863bc9bf7a",
    "submitter": {
        "id": 1315,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/1315/?format=api",
        "name": "Pablo Neira Ayuso",
        "email": "pablo@netfilter.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/netfilter-devel/patch/20260501122237.296262-5-pablo@netfilter.org/mbox/",
    "series": [
        {
            "id": 502449,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/502449/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netfilter-devel/list/?series=502449",
            "date": "2026-05-01T12:22:23",
            "name": "[net,01/14] netfilter: replace skb_try_make_writable() by skb_ensure_writable()",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/502449/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2231771/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2231771/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "\n <netfilter-devel+bounces-12375-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "netfilter-devel@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=netfilter.org header.i=@netfilter.org\n header.a=rsa-sha256 header.s=2025 header.b=Gzsd6rRy;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-12375-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=\"Gzsd6rRy\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=217.70.190.124",
            "smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org",
            "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=netfilter.org"
        ],
        "Received": [
            "from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g6VYn5nCmz1yJv\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 01 May 2026 22:23:09 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 87C39301C92B\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  1 May 2026 12:22:53 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id EFA4B3A1A59;\n\tFri,  1 May 2026 12:22:52 +0000 (UTC)",
            "from mail.netfilter.org (mail.netfilter.org [217.70.190.124])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DE6518DB01;\n\tFri,  1 May 2026 12:22:49 +0000 (UTC)",
            "from localhost.localdomain (mail-agni [217.70.190.124])\n\tby mail.netfilter.org (Postfix) with ESMTPSA id D61B460253;\n\tFri,  1 May 2026 14:22:46 +0200 (CEST)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777638172; cv=none;\n b=ZIZhFjiP7kgsEmN7gkiCtX4JysIkGLoVr+E9pm5XR0WwquRBDjaifsw5LXyrSIhQjxxKczH7G0FaM8+Pzmu880on94cYTzCS4RaKSa+kRLlkLDOSlbleof/KrzF+C4jL4JKE6IkS/GnvzrjMwssUNn81uITeswfGLuaMDAgXIEI=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777638172; c=relaxed/simple;\n\tbh=6dEL9sDOAJOUR54tpkalkGaIXilvLaIEGt67G3UFRiw=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=kL0G8noZnXUWsekVxddb6kEvUKYh+5kZFirTizVZTw6zwUJUHD1MXKInMHpg9QDzlfL4h1ZA4I4+iAC9ypISHcZcGLZcuy9CR7owZcrVD23cOtHhQYRiSyOI5WtxcAM2qe3+2JeO1wpkK2FZXqrtNozfO2z7y9fx6ZDtitMVHTs=",
        "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org;\n spf=pass smtp.mailfrom=netfilter.org;\n dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=Gzsd6rRy; arc=none smtp.client-ip=217.70.190.124",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org;\n\ts=2025; t=1777638167;\n\tbh=HJ0gyI6q78dQqxVhrj+i20Ul62wION/SbOydKnouNU0=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Gzsd6rRyVtD9+hCcuUh+nZ74dJQp3cfIIHqeBm4HbEbNk1PiBjihqHf5FSHKLsbq2\n\t MieCCP9h4PTKwiueeRmW7nDYZejs1I/M5T1Y+x5AqvEaPHyCteE2UbE4CfLznq/bWd\n\t TGZEoZ0pw/J+VTX2eJQ5qocZ3zQSGCM/+pDN0Na6LqzX+yRM9GWkPIpemzpJPeyXzo\n\t 17Ecdb0psZCqKIm6rypHG98pBWLK+TqHS9NLC+HJ3eNn5sMkE/arvkUjbpfJRzBucU\n\t wGrTMX/poD491TlON3kHl9sy0c+8u29zAZ1D7H1QluA7kOa09lyHCiIasvLXzQYJQ1\n\t YJscDkY+3ffwQ==",
        "From": "Pablo Neira Ayuso <pablo@netfilter.org>",
        "To": "netfilter-devel@vger.kernel.org",
        "Cc": "davem@davemloft.net,\n\tnetdev@vger.kernel.org,\n\tkuba@kernel.org,\n\tpabeni@redhat.com,\n\tedumazet@google.com,\n\tfw@strlen.de,\n\thorms@kernel.org",
        "Subject": "[PATCH net 04/14] netfilter: x_tables: add .check_hooks to matches\n and targets",
        "Date": "Fri,  1 May 2026 14:22:27 +0200",
        "Message-ID": "<20260501122237.296262-5-pablo@netfilter.org>",
        "X-Mailer": "git-send-email 2.47.3",
        "In-Reply-To": "<20260501122237.296262-1-pablo@netfilter.org>",
        "References": "<20260501122237.296262-1-pablo@netfilter.org>",
        "Precedence": "bulk",
        "X-Mailing-List": "netfilter-devel@vger.kernel.org",
        "List-Id": "<netfilter-devel.vger.kernel.org>",
        "List-Subscribe": "<mailto:netfilter-devel+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:netfilter-devel+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit"
    },
    "content": "Add a new .check_hooks interface for checking if the match/target is\nused from the validate hook according to its configuration.\n\nMove existing conditional hook check based on the match/target\nconfiguration from .checkentry to .check_hooks for the following\nmatches/targets:\n\n- addrtype\n- devgroup\n- physdev\n- policy\n- set\n- TCPMSS\n- SET\n\nThis is a preparation patch to fix nft_compat, not functional changes\nare intended.\n\nBased on patch from Florian Westphal.\n\nSigned-off-by: Pablo Neira Ayuso <pablo@netfilter.org>\n---\n include/linux/netfilter/x_tables.h |  8 +++\n net/netfilter/x_tables.c           | 79 +++++++++++++++++++++++++++---\n net/netfilter/xt_TCPMSS.c          | 33 +++++++------\n net/netfilter/xt_addrtype.c        | 25 +++++++---\n net/netfilter/xt_devgroup.c        | 18 +++++--\n net/netfilter/xt_physdev.c         | 20 ++++++--\n net/netfilter/xt_policy.c          | 24 +++++++--\n net/netfilter/xt_set.c             | 39 +++++++++------\n 8 files changed, 187 insertions(+), 59 deletions(-)",
    "diff": "diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h\nindex 77c778d84d4c..a81b46af5118 100644\n--- a/include/linux/netfilter/x_tables.h\n+++ b/include/linux/netfilter/x_tables.h\n@@ -146,6 +146,9 @@ struct xt_match {\n \t/* Called when user tries to insert an entry of this type. */\n \tint (*checkentry)(const struct xt_mtchk_param *);\n \n+\t/* Called to validate hooks based on the match configuration. */\n+\tint (*check_hooks)(const struct xt_mtchk_param *);\n+\n \t/* Called when entry of this type deleted. */\n \tvoid (*destroy)(const struct xt_mtdtor_param *);\n #ifdef CONFIG_NETFILTER_XTABLES_COMPAT\n@@ -187,6 +190,9 @@ struct xt_target {\n \t/* Should return 0 on success or an error code otherwise (-Exxxx). */\n \tint (*checkentry)(const struct xt_tgchk_param *);\n \n+\t/* Called to validate hooks based on the target configuration. */\n+\tint (*check_hooks)(const struct xt_tgchk_param *);\n+\n \t/* Called when entry of this type deleted. */\n \tvoid (*destroy)(const struct xt_tgdtor_param *);\n #ifdef CONFIG_NETFILTER_XTABLES_COMPAT\n@@ -279,8 +285,10 @@ bool xt_find_jump_offset(const unsigned int *offsets,\n \n int xt_check_proc_name(const char *name, unsigned int size);\n \n+int xt_check_hooks_match(struct xt_mtchk_param *par);\n int xt_check_match(struct xt_mtchk_param *, unsigned int size, u16 proto,\n \t\t   bool inv_proto);\n+int xt_check_hooks_target(struct xt_tgchk_param *par);\n int xt_check_target(struct xt_tgchk_param *, unsigned int size, u16 proto,\n \t\t    bool inv_proto);\n \ndiff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c\nindex 9f837fb5ceb4..2c67c2e6b132 100644\n--- a/net/netfilter/x_tables.c\n+++ b/net/netfilter/x_tables.c\n@@ -477,11 +477,9 @@ int xt_check_proc_name(const char *name, unsigned int size)\n }\n EXPORT_SYMBOL(xt_check_proc_name);\n \n-int xt_check_match(struct xt_mtchk_param *par,\n-\t\t   unsigned int size, u16 proto, bool inv_proto)\n+static int xt_check_match_common(struct xt_mtchk_param *par,\n+\t\t\t\t unsigned int size, u16 proto, bool inv_proto)\n {\n-\tint ret;\n-\n \tif (XT_ALIGN(par->match->matchsize) != size &&\n \t    par->match->matchsize != -1) {\n \t\t/*\n@@ -530,6 +528,14 @@ int xt_check_match(struct xt_mtchk_param *par,\n \t\t\t\t    par->match->proto);\n \t\treturn -EINVAL;\n \t}\n+\n+\treturn 0;\n+}\n+\n+static int xt_checkentry_match(struct xt_mtchk_param *par)\n+{\n+\tint ret;\n+\n \tif (par->match->checkentry != NULL) {\n \t\tret = par->match->checkentry(par);\n \t\tif (ret < 0)\n@@ -538,8 +544,34 @@ int xt_check_match(struct xt_mtchk_param *par,\n \t\t\t/* Flag up potential errors. */\n \t\t\treturn -EIO;\n \t}\n+\n+\treturn 0;\n+}\n+\n+int xt_check_hooks_match(struct xt_mtchk_param *par)\n+{\n+\tif (par->match->check_hooks != NULL)\n+\t\treturn par->match->check_hooks(par);\n+\n \treturn 0;\n }\n+EXPORT_SYMBOL_GPL(xt_check_hooks_match);\n+\n+int xt_check_match(struct xt_mtchk_param *par,\n+\t\t   unsigned int size, u16 proto, bool inv_proto)\n+{\n+\tint ret;\n+\n+\tret = xt_check_match_common(par, size, proto, inv_proto);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = xt_check_hooks_match(par);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn xt_checkentry_match(par);\n+}\n EXPORT_SYMBOL_GPL(xt_check_match);\n \n /** xt_check_entry_match - check that matches end before start of target\n@@ -1012,11 +1044,9 @@ bool xt_find_jump_offset(const unsigned int *offsets,\n }\n EXPORT_SYMBOL(xt_find_jump_offset);\n \n-int xt_check_target(struct xt_tgchk_param *par,\n-\t\t    unsigned int size, u16 proto, bool inv_proto)\n+static int xt_check_target_common(struct xt_tgchk_param *par,\n+\t\t\t\t  unsigned int size, u16 proto, bool inv_proto)\n {\n-\tint ret;\n-\n \tif (XT_ALIGN(par->target->targetsize) != size) {\n \t\tpr_err_ratelimited(\"%s_tables: %s.%u target: invalid size %u (kernel) != (user) %u\\n\",\n \t\t\t\t   xt_prefix[par->family], par->target->name,\n@@ -1061,6 +1091,23 @@ int xt_check_target(struct xt_tgchk_param *par,\n \t\t\t\t    par->target->proto);\n \t\treturn -EINVAL;\n \t}\n+\n+\treturn 0;\n+}\n+\n+int xt_check_hooks_target(struct xt_tgchk_param *par)\n+{\n+\tif (par->target->check_hooks != NULL)\n+\t\treturn par->target->check_hooks(par);\n+\n+\treturn 0;\n+}\n+EXPORT_SYMBOL_GPL(xt_check_hooks_target);\n+\n+static int xt_checkentry_target(struct xt_tgchk_param *par)\n+{\n+\tint ret;\n+\n \tif (par->target->checkentry != NULL) {\n \t\tret = par->target->checkentry(par);\n \t\tif (ret < 0)\n@@ -1071,6 +1118,22 @@ int xt_check_target(struct xt_tgchk_param *par,\n \t}\n \treturn 0;\n }\n+\n+int xt_check_target(struct xt_tgchk_param *par,\n+\t\t    unsigned int size, u16 proto, bool inv_proto)\n+{\n+\tint ret;\n+\n+\tret = xt_check_target_common(par, size, proto, inv_proto);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\tret = xt_check_hooks_target(par);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn xt_checkentry_target(par);\n+}\n EXPORT_SYMBOL_GPL(xt_check_target);\n \n /**\ndiff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c\nindex 116a885adb3c..80e1634bc51f 100644\n--- a/net/netfilter/xt_TCPMSS.c\n+++ b/net/netfilter/xt_TCPMSS.c\n@@ -247,6 +247,21 @@ tcpmss_tg6(struct sk_buff *skb, const struct xt_action_param *par)\n }\n #endif\n \n+static int tcpmss_tg4_check_hooks(const struct xt_tgchk_param *par)\n+{\n+\tconst struct xt_tcpmss_info *info = par->targinfo;\n+\n+\tif (info->mss == XT_TCPMSS_CLAMP_PMTU &&\n+\t    (par->hook_mask & ~((1 << NF_INET_FORWARD) |\n+\t\t\t   (1 << NF_INET_LOCAL_OUT) |\n+\t\t\t   (1 << NF_INET_POST_ROUTING))) != 0) {\n+\t\tpr_info_ratelimited(\"path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n /* Must specify -p tcp --syn */\n static inline bool find_syn_match(const struct xt_entry_match *m)\n {\n@@ -262,17 +277,9 @@ static inline bool find_syn_match(const struct xt_entry_match *m)\n \n static int tcpmss_tg4_check(const struct xt_tgchk_param *par)\n {\n-\tconst struct xt_tcpmss_info *info = par->targinfo;\n \tconst struct ipt_entry *e = par->entryinfo;\n \tconst struct xt_entry_match *ematch;\n \n-\tif (info->mss == XT_TCPMSS_CLAMP_PMTU &&\n-\t    (par->hook_mask & ~((1 << NF_INET_FORWARD) |\n-\t\t\t   (1 << NF_INET_LOCAL_OUT) |\n-\t\t\t   (1 << NF_INET_POST_ROUTING))) != 0) {\n-\t\tpr_info_ratelimited(\"path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\\n\");\n-\t\treturn -EINVAL;\n-\t}\n \tif (par->nft_compat)\n \t\treturn 0;\n \n@@ -286,17 +293,9 @@ static int tcpmss_tg4_check(const struct xt_tgchk_param *par)\n #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)\n static int tcpmss_tg6_check(const struct xt_tgchk_param *par)\n {\n-\tconst struct xt_tcpmss_info *info = par->targinfo;\n \tconst struct ip6t_entry *e = par->entryinfo;\n \tconst struct xt_entry_match *ematch;\n \n-\tif (info->mss == XT_TCPMSS_CLAMP_PMTU &&\n-\t    (par->hook_mask & ~((1 << NF_INET_FORWARD) |\n-\t\t\t   (1 << NF_INET_LOCAL_OUT) |\n-\t\t\t   (1 << NF_INET_POST_ROUTING))) != 0) {\n-\t\tpr_info_ratelimited(\"path-MTU clamping only supported in FORWARD, OUTPUT and POSTROUTING hooks\\n\");\n-\t\treturn -EINVAL;\n-\t}\n \tif (par->nft_compat)\n \t\treturn 0;\n \n@@ -312,6 +311,7 @@ static struct xt_target tcpmss_tg_reg[] __read_mostly = {\n \t{\n \t\t.family\t\t= NFPROTO_IPV4,\n \t\t.name\t\t= \"TCPMSS\",\n+\t\t.check_hooks\t= tcpmss_tg4_check_hooks,\n \t\t.checkentry\t= tcpmss_tg4_check,\n \t\t.target\t\t= tcpmss_tg4,\n \t\t.targetsize\t= sizeof(struct xt_tcpmss_info),\n@@ -322,6 +322,7 @@ static struct xt_target tcpmss_tg_reg[] __read_mostly = {\n \t{\n \t\t.family\t\t= NFPROTO_IPV6,\n \t\t.name\t\t= \"TCPMSS\",\n+\t\t.check_hooks\t= tcpmss_tg4_check_hooks,\n \t\t.checkentry\t= tcpmss_tg6_check,\n \t\t.target\t\t= tcpmss_tg6,\n \t\t.targetsize\t= sizeof(struct xt_tcpmss_info),\ndiff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c\nindex a77088943107..913dbe3aa5e2 100644\n--- a/net/netfilter/xt_addrtype.c\n+++ b/net/netfilter/xt_addrtype.c\n@@ -153,14 +153,10 @@ addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)\n \treturn ret;\n }\n \n-static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)\n+static int addrtype_mt_check_hooks(const struct xt_mtchk_param *par)\n {\n-\tconst char *errmsg = \"both incoming and outgoing interface limitation cannot be selected\";\n \tstruct xt_addrtype_info_v1 *info = par->matchinfo;\n-\n-\tif (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN &&\n-\t    info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)\n-\t\tgoto err;\n+\tconst char *errmsg;\n \n \tif (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |\n \t    (1 << NF_INET_LOCAL_IN)) &&\n@@ -176,6 +172,21 @@ static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)\n \t\tgoto err;\n \t}\n \n+\treturn 0;\n+err:\n+\tpr_info_ratelimited(\"%s\\n\", errmsg);\n+\treturn -EINVAL;\n+}\n+\n+static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)\n+{\n+\tconst char *errmsg = \"both incoming and outgoing interface limitation cannot be selected\";\n+\tstruct xt_addrtype_info_v1 *info = par->matchinfo;\n+\n+\tif (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN &&\n+\t    info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)\n+\t\tgoto err;\n+\n #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)\n \tif (par->family == NFPROTO_IPV6) {\n \t\tif ((info->source | info->dest) & XT_ADDRTYPE_BLACKHOLE) {\n@@ -211,6 +222,7 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = {\n \t\t.family\t\t= NFPROTO_IPV4,\n \t\t.revision\t= 1,\n \t\t.match\t\t= addrtype_mt_v1,\n+\t\t.check_hooks\t= addrtype_mt_check_hooks,\n \t\t.checkentry\t= addrtype_mt_checkentry_v1,\n \t\t.matchsize\t= sizeof(struct xt_addrtype_info_v1),\n \t\t.me\t\t= THIS_MODULE\n@@ -221,6 +233,7 @@ static struct xt_match addrtype_mt_reg[] __read_mostly = {\n \t\t.family\t\t= NFPROTO_IPV6,\n \t\t.revision\t= 1,\n \t\t.match\t\t= addrtype_mt_v1,\n+\t\t.check_hooks\t= addrtype_mt_check_hooks,\n \t\t.checkentry\t= addrtype_mt_checkentry_v1,\n \t\t.matchsize\t= sizeof(struct xt_addrtype_info_v1),\n \t\t.me\t\t= THIS_MODULE\ndiff --git a/net/netfilter/xt_devgroup.c b/net/netfilter/xt_devgroup.c\nindex 9520dd00070b..6d1a44ab5eee 100644\n--- a/net/netfilter/xt_devgroup.c\n+++ b/net/netfilter/xt_devgroup.c\n@@ -33,14 +33,10 @@ static bool devgroup_mt(const struct sk_buff *skb, struct xt_action_param *par)\n \treturn true;\n }\n \n-static int devgroup_mt_checkentry(const struct xt_mtchk_param *par)\n+static int devgroup_mt_check_hooks(const struct xt_mtchk_param *par)\n {\n \tconst struct xt_devgroup_info *info = par->matchinfo;\n \n-\tif (info->flags & ~(XT_DEVGROUP_MATCH_SRC | XT_DEVGROUP_INVERT_SRC |\n-\t\t\t    XT_DEVGROUP_MATCH_DST | XT_DEVGROUP_INVERT_DST))\n-\t\treturn -EINVAL;\n-\n \tif (info->flags & XT_DEVGROUP_MATCH_SRC &&\n \t    par->hook_mask & ~((1 << NF_INET_PRE_ROUTING) |\n \t\t\t       (1 << NF_INET_LOCAL_IN) |\n@@ -56,9 +52,21 @@ static int devgroup_mt_checkentry(const struct xt_mtchk_param *par)\n \treturn 0;\n }\n \n+static int devgroup_mt_checkentry(const struct xt_mtchk_param *par)\n+{\n+\tconst struct xt_devgroup_info *info = par->matchinfo;\n+\n+\tif (info->flags & ~(XT_DEVGROUP_MATCH_SRC | XT_DEVGROUP_INVERT_SRC |\n+\t\t\t    XT_DEVGROUP_MATCH_DST | XT_DEVGROUP_INVERT_DST))\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n static struct xt_match devgroup_mt_reg __read_mostly = {\n \t.name\t\t= \"devgroup\",\n \t.match\t\t= devgroup_mt,\n+\t.check_hooks\t= devgroup_mt_check_hooks,\n \t.checkentry\t= devgroup_mt_checkentry,\n \t.matchsize\t= sizeof(struct xt_devgroup_info),\n \t.family\t\t= NFPROTO_UNSPEC,\ndiff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c\nindex d2b0b52434fa..dd98f758176c 100644\n--- a/net/netfilter/xt_physdev.c\n+++ b/net/netfilter/xt_physdev.c\n@@ -91,14 +91,10 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par)\n \treturn (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT));\n }\n \n-static int physdev_mt_check(const struct xt_mtchk_param *par)\n+static int physdev_mt_check_hooks(const struct xt_mtchk_param *par)\n {\n \tconst struct xt_physdev_info *info = par->matchinfo;\n-\tstatic bool brnf_probed __read_mostly;\n \n-\tif (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||\n-\t    info->bitmask & ~XT_PHYSDEV_OP_MASK)\n-\t\treturn -EINVAL;\n \tif (info->bitmask & (XT_PHYSDEV_OP_OUT | XT_PHYSDEV_OP_ISOUT) &&\n \t    (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||\n \t     info->invert & XT_PHYSDEV_OP_BRIDGED) &&\n@@ -107,6 +103,18 @@ static int physdev_mt_check(const struct xt_mtchk_param *par)\n \t\treturn -EINVAL;\n \t}\n \n+\treturn 0;\n+}\n+\n+static int physdev_mt_check(const struct xt_mtchk_param *par)\n+{\n+\tconst struct xt_physdev_info *info = par->matchinfo;\n+\tstatic bool brnf_probed __read_mostly;\n+\n+\tif (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||\n+\t    info->bitmask & ~XT_PHYSDEV_OP_MASK)\n+\t\treturn -EINVAL;\n+\n #define X(memb) strnlen(info->memb, sizeof(info->memb)) >= sizeof(info->memb)\n \tif (info->bitmask & XT_PHYSDEV_OP_IN) {\n \t\tif (info->physindev[0] == '\\0')\n@@ -141,6 +149,7 @@ static struct xt_match physdev_mt_reg[] __read_mostly = {\n \t{\n \t\t.name\t\t= \"physdev\",\n \t\t.family\t\t= NFPROTO_IPV4,\n+\t\t.check_hooks\t= physdev_mt_check_hooks,\n \t\t.checkentry\t= physdev_mt_check,\n \t\t.match\t\t= physdev_mt,\n \t\t.matchsize\t= sizeof(struct xt_physdev_info),\n@@ -149,6 +158,7 @@ static struct xt_match physdev_mt_reg[] __read_mostly = {\n \t{\n \t\t.name\t\t= \"physdev\",\n \t\t.family\t\t= NFPROTO_IPV6,\n+\t\t.check_hooks\t= physdev_mt_check_hooks,\n \t\t.checkentry\t= physdev_mt_check,\n \t\t.match\t\t= physdev_mt,\n \t\t.matchsize\t= sizeof(struct xt_physdev_info),\ndiff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c\nindex b5fa65558318..ff54e3a8581e 100644\n--- a/net/netfilter/xt_policy.c\n+++ b/net/netfilter/xt_policy.c\n@@ -126,13 +126,10 @@ policy_mt(const struct sk_buff *skb, struct xt_action_param *par)\n \treturn ret;\n }\n \n-static int policy_mt_check(const struct xt_mtchk_param *par)\n+static int policy_mt_check_hooks(const struct xt_mtchk_param *par)\n {\n \tconst struct xt_policy_info *info = par->matchinfo;\n-\tconst char *errmsg = \"neither incoming nor outgoing policy selected\";\n-\n-\tif (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT)))\n-\t\tgoto err;\n+\tconst char *errmsg;\n \n \tif (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |\n \t    (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) {\n@@ -144,6 +141,21 @@ static int policy_mt_check(const struct xt_mtchk_param *par)\n \t\terrmsg = \"input policy not valid in POSTROUTING and OUTPUT\";\n \t\tgoto err;\n \t}\n+\n+\treturn 0;\n+err:\n+\tpr_info_ratelimited(\"%s\\n\", errmsg);\n+\treturn -EINVAL;\n+}\n+\n+static int policy_mt_check(const struct xt_mtchk_param *par)\n+{\n+\tconst struct xt_policy_info *info = par->matchinfo;\n+\tconst char *errmsg = \"neither incoming nor outgoing policy selected\";\n+\n+\tif (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT)))\n+\t\tgoto err;\n+\n \tif (info->len > XT_POLICY_MAX_ELEM) {\n \t\terrmsg = \"too many policy elements\";\n \t\tgoto err;\n@@ -158,6 +170,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = {\n \t{\n \t\t.name\t\t= \"policy\",\n \t\t.family\t\t= NFPROTO_IPV4,\n+\t\t.check_hooks\t= policy_mt_check_hooks,\n \t\t.checkentry \t= policy_mt_check,\n \t\t.match\t\t= policy_mt,\n \t\t.matchsize\t= sizeof(struct xt_policy_info),\n@@ -166,6 +179,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = {\n \t{\n \t\t.name\t\t= \"policy\",\n \t\t.family\t\t= NFPROTO_IPV6,\n+\t\t.check_hooks\t= policy_mt_check_hooks,\n \t\t.checkentry\t= policy_mt_check,\n \t\t.match\t\t= policy_mt,\n \t\t.matchsize\t= sizeof(struct xt_policy_info),\ndiff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c\nindex 731bc2cafae4..4ae04bba9358 100644\n--- a/net/netfilter/xt_set.c\n+++ b/net/netfilter/xt_set.c\n@@ -430,6 +430,29 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)\n \treturn XT_CONTINUE;\n }\n \n+static int\n+set_target_v3_check_hooks(const struct xt_tgchk_param *par)\n+{\n+\tconst struct xt_set_info_target_v3 *info = par->targinfo;\n+\n+\tif (info->map_set.index != IPSET_INVALID_ID) {\n+\t\tif (strncmp(par->table, \"mangle\", 7)) {\n+\t\t\tpr_info_ratelimited(\"--map-set only usable from mangle table\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tif (((info->flags & IPSET_FLAG_MAP_SKBPRIO) |\n+\t\t     (info->flags & IPSET_FLAG_MAP_SKBQUEUE)) &&\n+\t\t     (par->hook_mask & ~(1 << NF_INET_FORWARD |\n+\t\t\t\t\t 1 << NF_INET_LOCAL_OUT |\n+\t\t\t\t\t 1 << NF_INET_POST_ROUTING))) {\n+\t\t\tpr_info_ratelimited(\"mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n set_target_v3_checkentry(const struct xt_tgchk_param *par)\n {\n@@ -459,20 +482,6 @@ set_target_v3_checkentry(const struct xt_tgchk_param *par)\n \t}\n \n \tif (info->map_set.index != IPSET_INVALID_ID) {\n-\t\tif (strncmp(par->table, \"mangle\", 7)) {\n-\t\t\tpr_info_ratelimited(\"--map-set only usable from mangle table\\n\");\n-\t\t\tret = -EINVAL;\n-\t\t\tgoto cleanup_del;\n-\t\t}\n-\t\tif (((info->flags & IPSET_FLAG_MAP_SKBPRIO) |\n-\t\t     (info->flags & IPSET_FLAG_MAP_SKBQUEUE)) &&\n-\t\t     (par->hook_mask & ~(1 << NF_INET_FORWARD |\n-\t\t\t\t\t 1 << NF_INET_LOCAL_OUT |\n-\t\t\t\t\t 1 << NF_INET_POST_ROUTING))) {\n-\t\t\tpr_info_ratelimited(\"mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\\n\");\n-\t\t\tret = -EINVAL;\n-\t\t\tgoto cleanup_del;\n-\t\t}\n \t\tindex = ip_set_nfnl_get_byindex(par->net,\n \t\t\t\t\t\tinfo->map_set.index);\n \t\tif (index == IPSET_INVALID_ID) {\n@@ -672,6 +681,7 @@ static struct xt_target set_targets[] __read_mostly = {\n \t\t.family\t\t= NFPROTO_IPV4,\n \t\t.target\t\t= set_target_v3,\n \t\t.targetsize\t= sizeof(struct xt_set_info_target_v3),\n+\t\t.check_hooks\t= set_target_v3_check_hooks,\n \t\t.checkentry\t= set_target_v3_checkentry,\n \t\t.destroy\t= set_target_v3_destroy,\n \t\t.me\t\t= THIS_MODULE\n@@ -682,6 +692,7 @@ static struct xt_target set_targets[] __read_mostly = {\n \t\t.family\t\t= NFPROTO_IPV6,\n \t\t.target\t\t= set_target_v3,\n \t\t.targetsize\t= sizeof(struct xt_set_info_target_v3),\n+\t\t.check_hooks\t= set_target_v3_check_hooks,\n \t\t.checkentry\t= set_target_v3_checkentry,\n \t\t.destroy\t= set_target_v3_destroy,\n \t\t.me\t\t= THIS_MODULE\n",
    "prefixes": [
        "net",
        "04/14"
    ]
}