summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2020-06-24 16:27:00 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2020-07-21 02:34:29 +0200
commit20e0e8f2bec3b06ba5d77ec17d8e635750f4c085 (patch)
tree3b0ea888c0d2f7a3d58745ff368029564858be9e
parenteedafeb6db330b8adff1b7cdd3dac325f9144195 (diff)
src: add support for chain ID attribute
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>
-rw-r--r--include/data_reg.h1
-rw-r--r--include/libnftnl/chain.h1
-rw-r--r--include/libnftnl/expr.h1
-rw-r--r--include/linux/netfilter/nf_tables.h2
-rw-r--r--src/chain.c21
-rw-r--r--src/expr/data_reg.c1
-rw-r--r--src/expr/immediate.c10
7 files changed, 37 insertions, 0 deletions
diff --git a/include/data_reg.h b/include/data_reg.h
index 10517ba..d9578aa 100644
--- a/include/data_reg.h
+++ b/include/data_reg.h
@@ -21,6 +21,7 @@ union nftnl_data_reg {
struct {
uint32_t verdict;
const char *chain;
+ uint32_t chain_id;
};
};
diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h
index 291bf22..0e57a5a 100644
--- a/include/libnftnl/chain.h
+++ b/include/libnftnl/chain.h
@@ -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)
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index cfe456d..dcbcf5c 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -98,6 +98,7 @@ enum {
NFTNL_EXPR_IMM_DATA,
NFTNL_EXPR_IMM_VERDICT,
NFTNL_EXPR_IMM_CHAIN,
+ NFTNL_EXPR_IMM_CHAIN_ID,
};
enum {
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 30f2a87..d9b0daa 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -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)
diff --git a/src/chain.c b/src/chain.c
index 5f12130..94efa90 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -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;
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index 67165fe..4e35a79 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -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;
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index 47106ae..7f34772 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -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);