summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-09-12 11:52:18 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2014-09-19 15:15:10 +0200
commit2e66fb09d6936d17ab8240188f511529fcae8c67 (patch)
tree9f9de55bc3e57d0aed474d02a5b0b0c58613c66c /src
parent51fbb415440517e47ac77a9f72fb6c1bc1c6e6b5 (diff)
src: add ruleset generation class
The generation object currently only contains the uint32_t that indicates the generation ID. I could have just add the API to return the uint32_t ID instead, but I think this API is easier to extend without adding new APIs. We can probably include meaningful statistics in the generation message in the future without much hassle. This patch also extends examples/nft-events.c. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/gen.c199
-rw-r--r--src/libnftnl.map14
3 files changed, 214 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d57ff96..65bc82a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,6 +7,7 @@ libnftnl_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnftnl.map \
libnftnl_la_SOURCES = utils.c \
common.c \
+ gen.c \
table.c \
chain.c \
rule.c \
diff --git a/src/gen.c b/src/gen.c
new file mode 100644
index 0000000..21d3a49
--- /dev/null
+++ b/src/gen.c
@@ -0,0 +1,199 @@
+/*
+ * (C) 2012-2014 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include "internal.h"
+
+#include <time.h>
+#include <endian.h>
+#include <stdint.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include <libmnl/libmnl.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nf_tables.h>
+
+#include <libnftnl/gen.h>
+
+struct nft_gen {
+ uint32_t id;
+
+ uint32_t flags;
+};
+
+struct nft_gen *nft_gen_alloc(void)
+{
+ return calloc(1, sizeof(struct nft_gen));
+}
+EXPORT_SYMBOL(nft_gen_alloc);
+
+void nft_gen_free(struct nft_gen *gen)
+{
+ xfree(gen);
+}
+EXPORT_SYMBOL(nft_gen_free);
+
+bool nft_gen_attr_is_set(const struct nft_gen *gen, uint16_t attr)
+{
+ return gen->flags & (1 << attr);
+}
+EXPORT_SYMBOL(nft_gen_attr_is_set);
+
+void nft_gen_attr_unset(struct nft_gen *gen, uint16_t attr)
+{
+ if (!(gen->flags & (1 << attr)))
+ return;
+
+ switch (attr) {
+ case NFT_GEN_ID:
+ break;
+ }
+ gen->flags &= ~(1 << attr);
+}
+EXPORT_SYMBOL(nft_gen_attr_unset);
+
+static uint32_t nft_gen_attr_validate[NFT_GEN_MAX + 1] = {
+ [NFT_GEN_ID] = sizeof(uint32_t),
+};
+
+void nft_gen_attr_set_data(struct nft_gen *gen, uint16_t attr,
+ const void *data, uint32_t data_len)
+{
+ if (attr > NFT_GEN_MAX)
+ return;
+
+ nft_assert_validate(data, nft_gen_attr_validate, attr, data_len);
+
+ switch (attr) {
+ case NFT_GEN_ID:
+ gen->id = *((uint32_t *)data);
+ break;
+ }
+ gen->flags |= (1 << attr);
+}
+EXPORT_SYMBOL(nft_gen_attr_set_data);
+
+void nft_gen_attr_set(struct nft_gen *gen, uint16_t attr, const void *data)
+{
+ nft_gen_attr_set_data(gen, attr, data, nft_gen_attr_validate[attr]);
+}
+EXPORT_SYMBOL(nft_gen_attr_set);
+
+void nft_gen_attr_set_u32(struct nft_gen *gen, uint16_t attr, uint32_t val)
+{
+ nft_gen_attr_set_data(gen, attr, &val, sizeof(uint32_t));
+}
+EXPORT_SYMBOL(nft_gen_attr_set_u32);
+
+const void *nft_gen_attr_get_data(struct nft_gen *gen, uint16_t attr,
+ uint32_t *data_len)
+{
+ if (!(gen->flags & (1 << attr)))
+ return NULL;
+
+ switch(attr) {
+ case NFT_GEN_ID:
+ return &gen->id;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(nft_gen_attr_get_data);
+
+const void *nft_gen_attr_get(struct nft_gen *gen, uint16_t attr)
+{
+ uint32_t data_len;
+ return nft_gen_attr_get_data(gen, attr, &data_len);
+}
+EXPORT_SYMBOL(nft_gen_attr_get);
+
+uint32_t nft_gen_attr_get_u32(struct nft_gen *gen, uint16_t attr)
+{
+ const void *ret = nft_gen_attr_get(gen, attr);
+ return ret == NULL ? 0 : *((uint32_t *)ret);
+}
+EXPORT_SYMBOL(nft_gen_attr_get_u32);
+
+static int nft_gen_parse_attr_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_valid(attr, NFTA_GEN_MAX) < 0)
+ return MNL_CB_OK;
+
+ switch(type) {
+ case NFTA_GEN_ID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+ abi_breakage();
+ break;
+ }
+
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
+int nft_gen_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_gen *gen)
+{
+ struct nlattr *tb[NFTA_GEN_MAX + 1] = {};
+ struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
+
+ if (mnl_attr_parse(nlh, sizeof(*nfg), nft_gen_parse_attr_cb, tb) < 0)
+ return -1;
+
+ if (tb[NFTA_GEN_ID]) {
+ gen->id = ntohl(mnl_attr_get_u32(tb[NFTA_GEN_ID]));
+ gen->flags |= (1 << NFT_GEN_ID);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(nft_gen_nlmsg_parse);
+
+static int nft_gen_snprintf_default(char *buf, size_t size, struct nft_gen *gen)
+{
+ return snprintf(buf, size, "ruleset generation ID %u", gen->id);
+}
+
+int nft_gen_snprintf(char *buf, size_t size, struct nft_gen *gen,
+ uint32_t type, uint32_t flags)
+{
+ int ret, len = size, offset = 0;
+
+ ret = nft_event_header_snprintf(buf + offset, len, type, flags);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ switch(type) {
+ case NFT_OUTPUT_DEFAULT:
+ ret = nft_gen_snprintf_default(buf + offset, len, gen);
+ break;
+ default:
+ return -1;
+ }
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ ret = nft_event_footer_snprintf(buf + offset, len, type, flags);
+ SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+ return offset;
+}
+EXPORT_SYMBOL(nft_gen_snprintf);
+
+static inline int nft_gen_do_snprintf(char *buf, size_t size, void *gen,
+ uint32_t type, uint32_t flags)
+{
+ return nft_gen_snprintf(buf, size, gen, type, flags);
+}
+
+int nft_gen_fprintf(FILE *fp, struct nft_gen *gen, uint32_t type,
+ uint32_t flags)
+{
+ return nft_fprintf(fp, gen, type, flags, nft_gen_do_snprintf);
+}
+EXPORT_SYMBOL(nft_gen_fprintf);
diff --git a/src/libnftnl.map b/src/libnftnl.map
index d8dcf8e..be7b998 100644
--- a/src/libnftnl.map
+++ b/src/libnftnl.map
@@ -212,4 +212,18 @@ LIBNFTNL_1.2 {
nft_batch_is_supported;
nft_batch_begin;
nft_batch_end;
+
+ nft_gen_alloc;
+ nft_gen_free;
+ nft_gen_attr_is_set;
+ nft_gen_attr_unset;
+ nft_gen_attr_set_data;
+ nft_gen_attr_set;
+ nft_gen_attr_set_u32;
+ nft_gen_attr_get_data;
+ nft_gen_attr_get;
+ nft_gen_attr_get_u32;
+ nft_gen_nlmsg_parse;
+ nft_gen_snprintf;
+ nft_gen_fprintf;
} LIBNFTNL_1.1;