diff options
author | Eric Leblond <eric@regit.org> | 2013-07-06 17:33:13 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-07-19 13:20:35 +0200 |
commit | 28d03e97ec0d155c6d9708522985915530cbb356 (patch) | |
tree | f03dd1ae8ad3bb8a46ee8bb053d72501dd2f1cb9 | |
parent | 6cdc49ffbe0a672c27f4fffe831563b12a8e2e61 (diff) |
rule: add support for position attribute
This patch adds support for position attribute which can be used
to insert a rule at a given position.
Signed-off-by: Eric Leblond <eric@regit.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/libnftables/rule.h | 1 | ||||
-rw-r--r-- | include/linux/netfilter/nf_tables.h | 1 | ||||
-rw-r--r-- | src/rule.c | 19 |
3 files changed, 21 insertions, 0 deletions
diff --git a/include/libnftables/rule.h b/include/libnftables/rule.h index ea136ff..9adfcfc 100644 --- a/include/libnftables/rule.h +++ b/include/libnftables/rule.h @@ -22,6 +22,7 @@ enum { NFT_RULE_ATTR_FLAGS, NFT_RULE_ATTR_COMPAT_PROTO, NFT_RULE_ATTR_COMPAT_FLAGS, + NFT_RULE_ATTR_POSITION, }; void nft_rule_attr_unset(struct nft_rule *r, uint16_t attr); diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index d40a7f9..d9bf8ea 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -143,6 +143,7 @@ enum nft_rule_attributes { NFTA_RULE_EXPRESSIONS, NFTA_RULE_FLAGS, NFTA_RULE_COMPAT, + NFTA_RULE_POSITION, __NFTA_RULE_MAX }; #define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1) @@ -39,6 +39,7 @@ struct nft_rule { uint8_t family; uint32_t rule_flags; uint64_t handle; + uint64_t position; struct { uint32_t flags; uint32_t proto; @@ -99,6 +100,7 @@ void nft_rule_attr_unset(struct nft_rule *r, uint16_t attr) case NFT_RULE_ATTR_FLAGS: case NFT_RULE_ATTR_COMPAT_PROTO: case NFT_RULE_ATTR_COMPAT_FLAGS: + case NFT_RULE_ATTR_POSITION: case NFT_RULE_ATTR_FAMILY: break; default: @@ -139,6 +141,9 @@ void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data) case NFT_RULE_ATTR_FAMILY: r->family = *((uint8_t *)data); break; + case NFT_RULE_ATTR_POSITION: + r->position = *((uint64_t *)data); + break; default: return; } @@ -184,6 +189,8 @@ const void *nft_rule_attr_get(const struct nft_rule *r, uint16_t attr) return &r->compat.proto; case NFT_RULE_ATTR_COMPAT_FLAGS: return &r->compat.flags; + case NFT_RULE_ATTR_POSITION: + return &r->position; } return NULL; } @@ -248,6 +255,8 @@ void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *r) mnl_attr_put_strz(nlh, NFTA_RULE_CHAIN, r->chain); if (r->flags & (1 << NFT_RULE_ATTR_HANDLE)) mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(r->handle)); + if (r->flags & (1 << NFT_RULE_ATTR_POSITION)) + mnl_attr_put_u64(nlh, NFTA_RULE_POSITION, htobe64(r->position)); if (r->flags & (1 << NFT_RULE_ATTR_FLAGS)) mnl_attr_put_u32(nlh, NFTA_RULE_FLAGS, htonl(r->rule_flags)); @@ -310,6 +319,12 @@ static int nft_rule_parse_attr_cb(const struct nlattr *attr, void *data) return MNL_CB_ERROR; } break; + case NFTA_RULE_POSITION: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) { + perror("mnl_attr_validate"); + return MNL_CB_ERROR; + } + break; } tb[type] = attr; @@ -444,6 +459,10 @@ int nft_rule_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_rule *r) ret = nft_rule_parse_expr(tb[NFTA_RULE_EXPRESSIONS], r); if (tb[NFTA_RULE_COMPAT]) ret = nft_rule_parse_compat(tb[NFTA_RULE_COMPAT], r); + if (tb[NFTA_RULE_POSITION]) { + r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION])); + r->flags |= (1 << NFT_RULE_ATTR_POSITION); + } r->family = nfg->nfgen_family; r->flags |= (1 << NFT_RULE_ATTR_FAMILY); |