summaryrefslogtreecommitdiffstats
path: root/src/netlink.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-11-27 23:35:25 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2017-01-03 14:21:53 +0100
commit4756d92e517ae1f7d662c0ed083b54d8dc822e4a (patch)
tree5130faa44f2f3e72b257f4d30fd1752749109049 /src/netlink.c
parentd156fd17ee7ff9a2822d7714e1c8dfe7b6b18f55 (diff)
src: listing of stateful objects
This patch allows you to dump existing stateful objects, eg. # nft list ruleset table ip filter { counter test { packets 64 bytes 1268 } quota test { over 1 mbytes used 1268 bytes } chain input { type filter hook input priority 0; policy accept; quota name test drop counter name test } } # nft list quotas table ip filter { quota test { over 1 mbytes used 1268 bytes } } # nft list counters table ip filter { counter test { packets 64 bytes 1268 } } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink.c')
-rw-r--r--src/netlink.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/netlink.c b/src/netlink.c
index e37d3bf1..bbf675f9 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -1608,6 +1608,73 @@ out:
return err;
}
+static struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx,
+ struct nftnl_obj *nlo)
+{
+ struct obj *obj;
+ uint32_t type;
+
+ obj = obj_alloc(&netlink_location);
+ obj->handle.family = nftnl_obj_get_u32(nlo, NFTNL_OBJ_FAMILY);
+ obj->handle.table =
+ xstrdup(nftnl_obj_get_str(nlo, NFTNL_OBJ_TABLE));
+ obj->handle.obj =
+ xstrdup(nftnl_obj_get_str(nlo, NFTNL_OBJ_NAME));
+
+ type = nftnl_obj_get_u32(nlo, NFTNL_OBJ_TYPE);
+ switch (type) {
+ case NFT_OBJECT_COUNTER:
+ obj->counter.packets =
+ nftnl_obj_get_u64(nlo, NFTNL_OBJ_CTR_PKTS);
+ obj->counter.bytes =
+ nftnl_obj_get_u64(nlo, NFTNL_OBJ_CTR_BYTES);
+ break;
+ case NFT_OBJECT_QUOTA:
+ obj->quota.bytes =
+ nftnl_obj_get_u64(nlo, NFTNL_OBJ_QUOTA_BYTES);
+ obj->quota.used =
+ nftnl_obj_get_u64(nlo, NFTNL_OBJ_QUOTA_CONSUMED);
+ obj->quota.flags =
+ nftnl_obj_get_u32(nlo, NFTNL_OBJ_QUOTA_FLAGS);
+ }
+ obj->type = type;
+
+ return obj;
+}
+
+static int list_obj_cb(struct nftnl_obj *nls, void *arg)
+{
+ struct netlink_ctx *ctx = arg;
+ struct obj *obj;
+
+ obj = netlink_delinearize_obj(ctx, nls);
+ if (obj == NULL)
+ return -1;
+ list_add_tail(&obj->list, &ctx->list);
+ return 0;
+}
+
+int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h,
+ const struct location *loc)
+{
+ struct nftnl_obj_list *obj_cache;
+ int err;
+
+ obj_cache = mnl_nft_obj_dump(nf_sock, h->family, h->table);
+ if (obj_cache == NULL) {
+ if (errno == EINTR)
+ return -1;
+
+ return netlink_io_error(ctx, loc,
+ "Could not receive stateful object from kernel: %s",
+ strerror(errno));
+ }
+
+ err = nftnl_obj_list_foreach(obj_cache, list_obj_cb, ctx);
+ nftnl_obj_list_free(obj_cache);
+ return err;
+}
+
int netlink_batch_send(struct list_head *err_list)
{
return mnl_batch_talk(nf_sock, err_list);