summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/internal.h1
-rw-r--r--include/libnftnl/chain.h15
-rw-r--r--include/rule.h26
-rw-r--r--src/chain.c104
-rw-r--r--src/libnftnl.map10
-rw-r--r--src/rule.c22
6 files changed, 155 insertions, 23 deletions
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 <linux/netfilter_arp.h>
#include <libnftnl/chain.h>
+#include <libnftnl/rule.h>
#include <buffer.h>
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 <libnftnl/set.h>
#include <libnftnl/expr.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;
-};
-
EXPORT_SYMBOL(nftnl_rule_alloc);
struct nftnl_rule *nftnl_rule_alloc(void)
{