]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
netfilter: nf_tables: add NFTA_CHAIN_ID attribute
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 30 Jun 2020 17:21:11 +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 refer to chains inside a
transaction as an alternative to the name and the handle. The chain
binding support requires this new chain ID approach.

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

index 6f0f6fca9ac3e3564174b6bbf251f7da46148b93..3e52266840178a86f1e0197e215dc2aaf2db8b67 100644 (file)
@@ -1433,6 +1433,7 @@ struct nft_trans_chain {
        char                            *name;
        struct nft_stats __percpu       *stats;
        u8                              policy;
+       u32                             chain_id;
 };
 
 #define nft_trans_chain_update(trans)  \
@@ -1443,6 +1444,8 @@ struct nft_trans_chain {
        (((struct nft_trans_chain *)trans->data)->stats)
 #define nft_trans_chain_policy(trans)  \
        (((struct nft_trans_chain *)trans->data)->policy)
+#define nft_trans_chain_id(trans)      \
+       (((struct nft_trans_chain *)trans->data)->chain_id)
 
 struct nft_trans_table {
        bool                            update;
index 4565456c0ef447e44e59791b23be2e702b828054..477779595b78f72ef059db8ee9bda96d56f1cf01 100644 (file)
@@ -196,6 +196,7 @@ enum nft_table_attributes {
  * @NFTA_CHAIN_TYPE: type name of the string (NLA_NUL_STRING)
  * @NFTA_CHAIN_COUNTERS: counter specification of the chain (NLA_NESTED: nft_counter_attributes)
  * @NFTA_CHAIN_FLAGS: chain flags
+ * @NFTA_CHAIN_ID: uniquely identifies a chain in a transaction (NLA_U32)
  */
 enum nft_chain_attributes {
        NFTA_CHAIN_UNSPEC,
@@ -209,6 +210,7 @@ enum nft_chain_attributes {
        NFTA_CHAIN_COUNTERS,
        NFTA_CHAIN_PAD,
        NFTA_CHAIN_FLAGS,
+       NFTA_CHAIN_ID,
        __NFTA_CHAIN_MAX
 };
 #define NFTA_CHAIN_MAX         (__NFTA_CHAIN_MAX - 1)
index 7647ecfa0d4078e6fd62d73238d52b61f29a7795..650ef0dd0773e2f366490fd72d3c02754730eb32 100644 (file)
@@ -280,9 +280,15 @@ static struct nft_trans *nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
        if (trans == NULL)
                return ERR_PTR(-ENOMEM);
 
-       if (msg_type == NFT_MSG_NEWCHAIN)
+       if (msg_type == NFT_MSG_NEWCHAIN) {
                nft_activate_next(ctx->net, ctx->chain);
 
+               if (ctx->nla[NFTA_CHAIN_ID]) {
+                       nft_trans_chain_id(trans) =
+                               ntohl(nla_get_be32(ctx->nla[NFTA_CHAIN_ID]));
+               }
+       }
+
        list_add_tail(&trans->list, &ctx->net->nft.commit_list);
        return trans;
 }
@@ -1274,6 +1280,7 @@ static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
                                    .len = NFT_MODULE_AUTOLOAD_LIMIT },
        [NFTA_CHAIN_COUNTERS]   = { .type = NLA_NESTED },
        [NFTA_CHAIN_FLAGS]      = { .type = NLA_U32 },
+       [NFTA_CHAIN_ID]         = { .type = NLA_U32 },
 };
 
 static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
@@ -2154,9 +2161,9 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        u8 genmask = nft_genmask_next(net);
        int family = nfmsg->nfgen_family;
+       struct nft_chain *chain = NULL;
        const struct nlattr *attr;
        struct nft_table *table;
-       struct nft_chain *chain;
        u8 policy = NF_ACCEPT;
        struct nft_ctx ctx;
        u64 handle = 0;
@@ -2181,7 +2188,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
                        return PTR_ERR(chain);
                }
                attr = nla[NFTA_CHAIN_HANDLE];
-       } else {
+       } else if (nla[NFTA_CHAIN_NAME]) {
                chain = nft_chain_lookup(net, table, attr, genmask);
                if (IS_ERR(chain)) {
                        if (PTR_ERR(chain) != -ENOENT) {
@@ -2190,6 +2197,8 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
                        }
                        chain = NULL;
                }
+       } else if (!nla[NFTA_CHAIN_ID]) {
+               return -EINVAL;
        }
 
        if (nla[NFTA_CHAIN_POLICY]) {