summaryrefslogtreecommitdiffstats
path: root/src/rule.c
diff options
context:
space:
mode:
authorEric Leblond <eric@regit.org>2013-07-06 17:33:13 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-07-19 13:20:35 +0200
commit28d03e97ec0d155c6d9708522985915530cbb356 (patch)
treef03dd1ae8ad3bb8a46ee8bb053d72501dd2f1cb9 /src/rule.c
parent6cdc49ffbe0a672c27f4fffe831563b12a8e2e61 (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>
Diffstat (limited to 'src/rule.c')
-rw-r--r--src/rule.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/rule.c b/src/rule.c
index 9a93f33..fc34dd9 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -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);