summaryrefslogtreecommitdiffstats
path: root/src/netlink.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2017-12-04 13:28:25 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-03-05 16:30:15 +0100
commitdb0697ce7f6020b525cee072e7c0c85512daabda (patch)
tree9458d01874a354f8bdacfae794d9e0b0d48ebf63 /src/netlink.c
parented183e43dbe5a896909470be172ad6ee45219f76 (diff)
src: support for flowtable listing
This patch allows you to dump existing flowtable. # nft list ruleset table ip x { flowtable x { hook ingress priority 10 devices = { eth0, tap0 } } } You can also list existing flowtables via: # nft list flowtables table ip x { flowtable x { hook ingress priority 10 devices = { eth0, tap0 } } } You need a Linux kernel >= 4.16-rc to test this new feature. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink.c')
-rw-r--r--src/netlink.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/netlink.c b/src/netlink.c
index 403f93ca..9fadccd0 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -23,6 +23,7 @@
#include <libnftnl/expr.h>
#include <libnftnl/object.h>
#include <libnftnl/set.h>
+#include <libnftnl/flowtable.h>
#include <libnftnl/udata.h>
#include <libnftnl/ruleset.h>
#include <libnftnl/common.h>
@@ -1542,6 +1543,70 @@ int netlink_reset_objs(struct netlink_ctx *ctx, const struct handle *h,
return err;
}
+static struct flowtable *
+netlink_delinearize_flowtable(struct netlink_ctx *ctx,
+ struct nftnl_flowtable *nlo)
+{
+ struct flowtable *flowtable;
+ const char **dev_array;
+ int len = 0, i;
+
+ flowtable = flowtable_alloc(&netlink_location);
+ flowtable->handle.family =
+ nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_FAMILY);
+ flowtable->handle.table =
+ xstrdup(nftnl_flowtable_get_str(nlo, NFTNL_FLOWTABLE_TABLE));
+ flowtable->handle.flowtable =
+ xstrdup(nftnl_flowtable_get_str(nlo, NFTNL_FLOWTABLE_NAME));
+ dev_array = nftnl_flowtable_get_array(nlo, NFTNL_FLOWTABLE_DEVICES);
+ while (dev_array[len] != '\0')
+ len++;
+
+ flowtable->dev_array = calloc(1, len * sizeof(char *));
+ for (i = 0; i < len; i++)
+ flowtable->dev_array[i] = xstrdup(dev_array[i]);
+
+ flowtable->dev_array_len = len;
+
+ flowtable->priority =
+ nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_PRIO);
+ flowtable->hooknum =
+ nftnl_flowtable_get_u32(nlo, NFTNL_FLOWTABLE_HOOKNUM);
+
+ return flowtable;
+}
+
+static int list_flowtable_cb(struct nftnl_flowtable *nls, void *arg)
+{
+ struct netlink_ctx *ctx = arg;
+ struct flowtable *flowtable;
+
+ flowtable = netlink_delinearize_flowtable(ctx, nls);
+ if (flowtable == NULL)
+ return -1;
+ list_add_tail(&flowtable->list, &ctx->list);
+ return 0;
+}
+
+int netlink_list_flowtables(struct netlink_ctx *ctx, const struct handle *h,
+ const struct location *loc)
+{
+ struct nftnl_flowtable_list *flowtable_cache;
+ int err;
+
+ flowtable_cache = mnl_nft_flowtable_dump(ctx, h->family, h->table);
+ if (flowtable_cache == NULL) {
+ if (errno == EINTR)
+ return -1;
+
+ return 0;
+ }
+
+ err = nftnl_flowtable_list_foreach(flowtable_cache, list_flowtable_cb, ctx);
+ nftnl_flowtable_list_free(flowtable_cache);
+ return err;
+}
+
int netlink_batch_send(struct netlink_ctx *ctx, struct list_head *err_list)
{
return mnl_batch_talk(ctx, err_list);