From e33798478176f97edf2649cd61444e0375fdc12b Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Thu, 6 Dec 2018 17:17:51 +0100 Subject: chain: Support per chain rules list The implementation basically copies expr_list in struct nftnl_rule. Signed-off-by: Phil Sutter Signed-off-by: Pablo Neira Ayuso --- include/internal.h | 1 + include/libnftnl/chain.h | 15 +++++++ include/rule.h | 26 ++++++++++++ src/chain.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++- src/libnftnl.map | 10 +++++ src/rule.c | 22 ---------- 6 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 include/rule.h diff --git a/include/internal.h b/include/internal.h index b762a4a..a61b725 100644 --- a/include/internal.h +++ b/include/internal.h @@ -12,5 +12,6 @@ #include "expr.h" #include "expr_ops.h" #include "buffer.h" +#include "rule.h" #endif /* _LIBNFTNL_INTERNAL_H_ */ diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h index 237683e..f04f610 100644 --- a/include/libnftnl/chain.h +++ b/include/libnftnl/chain.h @@ -13,6 +13,7 @@ extern "C" { #endif struct nftnl_chain; +struct nftnl_rule; struct nftnl_chain *nftnl_chain_alloc(void); void nftnl_chain_free(const struct nftnl_chain *); @@ -54,6 +55,10 @@ uint32_t nftnl_chain_get_u32(const struct nftnl_chain *c, uint16_t attr); int32_t nftnl_chain_get_s32(const struct nftnl_chain *c, uint16_t attr); uint64_t nftnl_chain_get_u64(const struct nftnl_chain *c, uint16_t attr); +void nftnl_chain_rule_add(struct nftnl_rule *rule, struct nftnl_chain *c); +void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c); +void nftnl_chain_rule_insert_at(struct nftnl_rule *rule, struct nftnl_rule *pos); + struct nlmsghdr; void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_chain *t); @@ -68,6 +73,16 @@ int nftnl_chain_fprintf(FILE *fp, const struct nftnl_chain *c, uint32_t type, ui #define nftnl_chain_nlmsg_build_hdr nftnl_nlmsg_build_hdr int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *t); +int nftnl_rule_foreach(struct nftnl_chain *c, + int (*cb)(struct nftnl_rule *r, void *data), + void *data); + +struct nftnl_rule_iter; + +struct nftnl_rule_iter *nftnl_rule_iter_create(const struct nftnl_chain *c); +struct nftnl_rule *nftnl_rule_iter_next(struct nftnl_rule_iter *iter); +void nftnl_rule_iter_destroy(struct nftnl_rule_iter *iter); + struct nftnl_chain_list; struct nftnl_chain_list *nftnl_chain_list_alloc(void); diff --git a/include/rule.h b/include/rule.h new file mode 100644 index 0000000..5edcb6c --- /dev/null +++ b/include/rule.h @@ -0,0 +1,26 @@ +#ifndef _LIBNFTNL_RULE_INTERNAL_H_ +#define _LIBNFTNL_RULE_INTERNAL_H_ + +struct nftnl_rule { + struct list_head head; + + uint32_t flags; + uint32_t family; + const char *table; + const char *chain; + uint64_t handle; + uint64_t position; + uint32_t id; + struct { + void *data; + uint32_t len; + } user; + struct { + uint32_t flags; + uint32_t proto; + } compat; + + struct list_head expr_list; +}; + +#endif diff --git a/src/chain.c b/src/chain.c index 01d62c8..c8b7f9b 100644 --- a/src/chain.c +++ b/src/chain.c @@ -27,6 +27,7 @@ #include #include +#include #include struct nftnl_chain { @@ -45,6 +46,8 @@ struct nftnl_chain { uint64_t bytes; uint64_t handle; uint32_t flags; + + struct list_head rule_list; }; static const char *nftnl_hooknum2str(int family, int hooknum) @@ -90,12 +93,25 @@ static const char *nftnl_hooknum2str(int family, int hooknum) EXPORT_SYMBOL(nftnl_chain_alloc); struct nftnl_chain *nftnl_chain_alloc(void) { - return calloc(1, sizeof(struct nftnl_chain)); + struct nftnl_chain *c; + + c = calloc(1, sizeof(struct nftnl_chain)); + if (c == NULL) + return NULL; + + INIT_LIST_HEAD(&c->rule_list); + + return c; } EXPORT_SYMBOL(nftnl_chain_free); void nftnl_chain_free(const struct nftnl_chain *c) { + struct nftnl_rule *r, *tmp; + + list_for_each_entry_safe(r, tmp, &c->rule_list, head) + nftnl_rule_free(r); + if (c->flags & (1 << NFTNL_CHAIN_NAME)) xfree(c->name); if (c->flags & (1 << NFTNL_CHAIN_TABLE)) @@ -406,6 +422,24 @@ void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ch mnl_attr_put_strz(nlh, NFTA_CHAIN_TYPE, c->type); } +EXPORT_SYMBOL(nftnl_chain_rule_add); +void nftnl_chain_rule_add(struct nftnl_rule *rule, struct nftnl_chain *c) +{ + list_add(&rule->head, &c->rule_list); +} + +EXPORT_SYMBOL(nftnl_chain_rule_add_tail); +void nftnl_chain_rule_add_tail(struct nftnl_rule *rule, struct nftnl_chain *c) +{ + list_add_tail(&rule->head, &c->rule_list); +} + +EXPORT_SYMBOL(nftnl_chain_rule_insert_at); +void nftnl_chain_rule_insert_at(struct nftnl_rule *rule, struct nftnl_rule *pos) +{ + list_add(&rule->head, &pos->head); +} + static int nftnl_chain_parse_attr_cb(const struct nlattr *attr, void *data) { const struct nlattr **tb = data; @@ -684,6 +718,74 @@ int nftnl_chain_fprintf(FILE *fp, const struct nftnl_chain *c, uint32_t type, nftnl_chain_do_snprintf); } +EXPORT_SYMBOL(nftnl_rule_foreach); +int nftnl_rule_foreach(struct nftnl_chain *c, + int (*cb)(struct nftnl_rule *r, void *data), + void *data) +{ + struct nftnl_rule *cur, *tmp; + int ret; + + list_for_each_entry_safe(cur, tmp, &c->rule_list, head) { + ret = cb(cur, data); + if (ret < 0) + return ret; + } + return 0; +} + +struct nftnl_rule_iter { + const struct nftnl_chain *c; + struct nftnl_rule *cur; +}; + +static void nftnl_rule_iter_init(const struct nftnl_chain *c, + struct nftnl_rule_iter *iter) +{ + iter->c = c; + if (list_empty(&c->rule_list)) + iter->cur = NULL; + else + iter->cur = list_entry(c->rule_list.next, struct nftnl_rule, + head); +} + +EXPORT_SYMBOL(nftnl_rule_iter_create); +struct nftnl_rule_iter *nftnl_rule_iter_create(const struct nftnl_chain *c) +{ + struct nftnl_rule_iter *iter; + + iter = calloc(1, sizeof(struct nftnl_rule_iter)); + if (iter == NULL) + return NULL; + + nftnl_rule_iter_init(c, iter); + + return iter; +} + +EXPORT_SYMBOL(nftnl_rule_iter_next); +struct nftnl_rule *nftnl_rule_iter_next(struct nftnl_rule_iter *iter) +{ + struct nftnl_rule *rule = iter->cur; + + if (rule == NULL) + return NULL; + + /* get next rule, if any */ + iter->cur = list_entry(iter->cur->head.next, struct nftnl_rule, head); + if (&iter->cur->head == iter->c->rule_list.next) + return NULL; + + return rule; +} + +EXPORT_SYMBOL(nftnl_rule_iter_destroy); +void nftnl_rule_iter_destroy(struct nftnl_rule_iter *iter) +{ + xfree(iter); +} + struct nftnl_chain_list { struct list_head list; }; diff --git a/src/libnftnl.map b/src/libnftnl.map index 89414f2..96d5b5f 100644 --- a/src/libnftnl.map +++ b/src/libnftnl.map @@ -336,3 +336,13 @@ global: local: *; }; + +LIBNFTNL_12 { + nftnl_chain_rule_add; + nftnl_chain_rule_add_tail; + nftnl_chain_rule_insert_at; + nftnl_rule_foreach; + nftnl_rule_iter_create; + nftnl_rule_iter_next; + nftnl_rule_iter_destroy; +} LIBNFTNL_11; diff --git a/src/rule.c b/src/rule.c index 9af8fae..e5d21ef 100644 --- a/src/rule.c +++ b/src/rule.c @@ -30,28 +30,6 @@ #include #include -struct nftnl_rule { - struct list_head head; - - uint32_t flags; - uint32_t family; - const char *table; - const char *chain; - uint64_t handle; - uint64_t position; - uint32_t id; - struct { - void *data; - uint32_t len; - } user; - struct { - uint32_t flags; - uint32_t proto; - } compat; - - struct list_head expr_list; -}; - EXPORT_SYMBOL(nftnl_rule_alloc); struct nftnl_rule *nftnl_rule_alloc(void) { -- cgit v1.2.3