netfilter: nf_tables: add NFTA_VERDICT_CHAIN_ID attribute
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 30 Jun 2020 17:21:21 +0000 (19:21 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 3 Jul 2020 23:18:41 +0000 (01:18 +0200)
This netlink attribute allows you to identify the chain to jump/goto by
means of the chain ID.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/uapi/linux/netfilter/nf_tables.h
net/netfilter/nf_tables_api.c

index 2304d1b..683e751 100644 (file)
@@ -471,11 +471,13 @@ enum nft_data_attributes {
  *
  * @NFTA_VERDICT_CODE: nf_tables verdict (NLA_U32: enum nft_verdicts)
  * @NFTA_VERDICT_CHAIN: jump target chain name (NLA_STRING)
+ * @NFTA_VERDICT_CHAIN_ID: jump target chain ID (NLA_U32)
  */
 enum nft_verdict_attributes {
        NFTA_VERDICT_UNSPEC,
        NFTA_VERDICT_CODE,
        NFTA_VERDICT_CHAIN,
+       NFTA_VERDICT_CHAIN_ID,
        __NFTA_VERDICT_MAX
 };
 #define NFTA_VERDICT_MAX       (__NFTA_VERDICT_MAX - 1)
index fbe8f92..d866027 100644 (file)
@@ -8242,6 +8242,7 @@ static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
        [NFTA_VERDICT_CODE]     = { .type = NLA_U32 },
        [NFTA_VERDICT_CHAIN]    = { .type = NLA_STRING,
                                    .len = NFT_CHAIN_MAXNAMELEN - 1 },
+       [NFTA_VERDICT_CHAIN_ID] = { .type = NLA_U32 },
 };
 
 static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
@@ -8278,10 +8279,19 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
                break;
        case NFT_JUMP:
        case NFT_GOTO:
-               if (!tb[NFTA_VERDICT_CHAIN])
+               if (tb[NFTA_VERDICT_CHAIN]) {
+                       chain = nft_chain_lookup(ctx->net, ctx->table,
+                                                tb[NFTA_VERDICT_CHAIN],
+                                                genmask);
+               } else if (tb[NFTA_VERDICT_CHAIN_ID]) {
+                       chain = nft_chain_lookup_byid(ctx->net,
+                                                     tb[NFTA_VERDICT_CHAIN_ID]);
+                       if (IS_ERR(chain))
+                               return PTR_ERR(chain);
+               } else {
                        return -EINVAL;
-               chain = nft_chain_lookup(ctx->net, ctx->table,
-                                        tb[NFTA_VERDICT_CHAIN], genmask);
+               }
+
                if (IS_ERR(chain))
                        return PTR_ERR(chain);
                if (nft_is_base_chain(chain))