]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
src: add support for chain ID attribute
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 24 Jun 2020 14:27:00 +0000 (16:27 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 21 Jul 2020 00:34:29 +0000 (02:34 +0200)
his patch allows you to refer to chains via the chain ID. The semantics
are similar to the NFTA_RULE_ID attribute.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/data_reg.h
include/libnftnl/chain.h
include/libnftnl/expr.h
include/linux/netfilter/nf_tables.h
src/chain.c
src/expr/data_reg.c
src/expr/immediate.c

index 10517ba9b4ed0b0cd8fed9b9c3fb59cf8f224108..d9578aa47990143063bcc824522339c8f1340b13 100644 (file)
@@ -21,6 +21,7 @@ union nftnl_data_reg {
        struct {
                uint32_t        verdict;
                const char      *chain;
+               uint32_t        chain_id;
        };
 };
 
index 291bf22a2fddf8afd9322af71c3023a745667647..0e57a5a0ef2f94fada65c9121f5a3fad0134c7cb 100644 (file)
@@ -33,6 +33,7 @@ enum nftnl_chain_attr {
        NFTNL_CHAIN_DEV,
        NFTNL_CHAIN_DEVICES,
        NFTNL_CHAIN_FLAGS,
+       NFTNL_CHAIN_ID,
        __NFTNL_CHAIN_MAX
 };
 #define NFTNL_CHAIN_MAX (__NFTNL_CHAIN_MAX - 1)
index cfe456dbc7a57adb77dbf81ce3fd5d9946cd5a63..dcbcf5c5c575b7a82a093cf0caa95b7cae069f12 100644 (file)
@@ -98,6 +98,7 @@ enum {
        NFTNL_EXPR_IMM_DATA,
        NFTNL_EXPR_IMM_VERDICT,
        NFTNL_EXPR_IMM_CHAIN,
+       NFTNL_EXPR_IMM_CHAIN_ID,
 };
 
 enum {
index 30f2a87270dc5622cf616084d542cdc765193a44..d9b0daa4d5484bfb104577d01333c1809e5f2648 100644 (file)
@@ -209,6 +209,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)
@@ -471,6 +472,7 @@ 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 5f1213013e53044e6f153515085e494b461258ec..94efa9088c97498d1cd448c521a597e5fb316f68 100644 (file)
@@ -49,6 +49,7 @@ struct nftnl_chain {
        uint64_t        bytes;
        uint64_t        handle;
        uint32_t        flags;
+       uint32_t        chain_id;
 
        struct list_head rule_list;
 };
@@ -167,6 +168,7 @@ void nftnl_chain_unset(struct nftnl_chain *c, uint16_t attr)
        case NFTNL_CHAIN_HANDLE:
        case NFTNL_CHAIN_FAMILY:
        case NFTNL_CHAIN_FLAGS:
+       case NFTNL_CHAIN_ID:
                break;
        case NFTNL_CHAIN_DEV:
                xfree(c->dev);
@@ -192,6 +194,7 @@ static uint32_t nftnl_chain_validate[NFTNL_CHAIN_MAX + 1] = {
        [NFTNL_CHAIN_HANDLE]            = sizeof(uint64_t),
        [NFTNL_CHAIN_FAMILY]            = sizeof(uint32_t),
        [NFTNL_CHAIN_FLAGS]             = sizeof(uint32_t),
+       [NFTNL_CHAIN_ID]                = sizeof(uint32_t),
 };
 
 EXPORT_SYMBOL(nftnl_chain_set_data);
@@ -284,6 +287,9 @@ int nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr,
        case NFTNL_CHAIN_FLAGS:
                memcpy(&c->chain_flags, data, sizeof(c->chain_flags));
                break;
+       case NFTNL_CHAIN_ID:
+               memcpy(&c->chain_id, data, sizeof(c->chain_id));
+               break;
        }
        c->flags |= (1 << attr);
        return 0;
@@ -382,6 +388,9 @@ const void *nftnl_chain_get_data(const struct nftnl_chain *c, uint16_t attr,
        case NFTNL_CHAIN_FLAGS:
                *data_len = sizeof(uint32_t);
                return &c->chain_flags;
+       case NFTNL_CHAIN_ID:
+               *data_len = sizeof(uint32_t);
+               return &c->chain_id;
        }
        return NULL;
 }
@@ -502,6 +511,8 @@ void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ch
                mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, c->type);
        if (c->flags & (1 << NFTNL_CHAIN_FLAGS))
                mnl_attr_put_u32(nlh, NFTA_CHAIN_FLAGS, htonl(c->chain_flags));
+       if (c->flags & (1 << NFTNL_CHAIN_ID))
+               mnl_attr_put_u32(nlh, NFTA_CHAIN_ID, htonl(c->chain_id));
 }
 
 EXPORT_SYMBOL(nftnl_chain_rule_add);
@@ -557,6 +568,7 @@ static int nftnl_chain_parse_attr_cb(const struct nlattr *attr, void *data)
        case NFTA_CHAIN_POLICY:
        case NFTA_CHAIN_USE:
        case NFTA_CHAIN_FLAGS:
+       case NFTA_CHAIN_ID:
                if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
                        abi_breakage();
                break;
@@ -761,6 +773,10 @@ int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *c)
                c->chain_flags = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_FLAGS]));
                c->flags |= (1 << NFTNL_CHAIN_FLAGS);
        }
+       if (tb[NFTA_CHAIN_ID]) {
+               c->chain_id = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_ID]));
+               c->flags |= (1 << NFTNL_CHAIN_ID);
+       }
 
        c->family = nfg->nfgen_family;
        c->flags |= (1 << NFTNL_CHAIN_FAMILY);
@@ -827,6 +843,11 @@ static int nftnl_chain_snprintf_default(char *buf, size_t size,
                                       c->chain_flags);
                        SNPRINTF_BUFFER_SIZE(ret, remain, offset);
                }
+               if (c->flags & (1 << NFTNL_CHAIN_ID)) {
+                       ret = snprintf(buf + offset, remain, " id %x",
+                                      c->chain_id);
+                       SNPRINTF_BUFFER_SIZE(ret, remain, offset);
+               }
        }
 
        return offset;
index 67165feb931f185c12f3aa92a39b3a9857a77cd7..4e35a799e9591e536b9bf6e3ca4f82ee3e9e97ef 100644 (file)
@@ -125,6 +125,7 @@ static int nftnl_verdict_parse_cb(const struct nlattr *attr, void *data)
 
        switch(type) {
        case NFTA_VERDICT_CODE:
+       case NFTA_VERDICT_CHAIN_ID:
                if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
                        abi_breakage();
                break;
index 47106ae86675a6afe06c29d1ebedb0f80e882f29..7f34772bd001386a2b047ce75ef6eccb65a5006e 100644 (file)
@@ -50,6 +50,9 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type,
                if (!imm->data.chain)
                        return -1;
                break;
+       case NFTNL_EXPR_IMM_CHAIN_ID:
+               memcpy(&imm->data.chain_id, data, sizeof(uint32_t));
+               break;
        default:
                return -1;
        }
@@ -75,6 +78,9 @@ nftnl_expr_immediate_get(const struct nftnl_expr *e, uint16_t type,
        case NFTNL_EXPR_IMM_CHAIN:
                *data_len = strlen(imm->data.chain)+1;
                return imm->data.chain;
+       case NFTNL_EXPR_IMM_CHAIN_ID:
+               *data_len = sizeof(imm->data.chain_id);
+               return &imm->data.chain_id;
        }
        return NULL;
 }
@@ -126,6 +132,10 @@ nftnl_expr_immediate_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
                mnl_attr_put_u32(nlh, NFTA_VERDICT_CODE, htonl(imm->data.verdict));
                if (e->flags & (1 << NFTNL_EXPR_IMM_CHAIN))
                        mnl_attr_put_strz(nlh, NFTA_VERDICT_CHAIN, imm->data.chain);
+               if (e->flags & (1 << NFTNL_EXPR_IMM_CHAIN_ID)) {
+                       mnl_attr_put_u32(nlh, NFTA_VERDICT_CHAIN_ID,
+                                        htonl(imm->data.chain_id));
+               }
 
                mnl_attr_nest_end(nlh, nest1);
                mnl_attr_nest_end(nlh, nest2);