314 lines
8.0 KiB
Diff
314 lines
8.0 KiB
Diff
|
From 8fcb95ed6dcd47c94a924b4018177d8a833d6983 Mon Sep 17 00:00:00 2001
|
||
|
From: Phil Sutter <psutter@redhat.com>
|
||
|
Date: Mon, 17 Dec 2018 17:30:06 +0100
|
||
|
Subject: [PATCH] chain: Support per chain rules list
|
||
|
|
||
|
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1658533
|
||
|
Upstream Status: libnftnl commit e33798478176f
|
||
|
|
||
|
commit e33798478176f97edf2649cd61444e0375fdc12b
|
||
|
Author: Phil Sutter <phil@nwl.cc>
|
||
|
Date: Thu Dec 6 17:17:51 2018 +0100
|
||
|
|
||
|
chain: Support per chain rules list
|
||
|
|
||
|
The implementation basically copies expr_list in struct nftnl_rule.
|
||
|
|
||
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||
|
---
|
||
|
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 7e97c4a..323f825 100644
|
||
|
--- a/include/internal.h
|
||
|
+++ b/include/internal.h
|
||
|
@@ -13,5 +13,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 eff5186..c374923 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;
|
||
|
@@ -875,6 +909,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 2c70420..6a43d3e 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)
|
||
|
{
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|