Skip to contentSkip to conversation

src: add flag to add event wrapping in output functions

PATCH Superseded Arturo Borrero Gonzalez 2 participants 4 messages Apr 15, 2014 netfilter

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 src: add flag to add event wrapping in output functions

This patch uses the flag option of each output function to print an event wrapper string in each object.

In order to use this functionality, the caller must pass a flag with either NFT_OUTPUT_FLAG_EVENTNEW or NFT_OUTPUT_FLAG_EVENTDEL activated.

---
 include/libnftnl/common.h |    5 +++
 src/chain.c               |   37 ++++++++++++++++++++++---
 src/internal.h            |    2 +
 src/rule.c                |   43 ++++++++++++++++++++++++++---
 src/ruleset.c             |   66 ++++++++++++++++++++++++++++++++++++++++-----
 src/set.c                 |   42 +++++++++++++++++++++++++----
 src/set_elem.c            |   37 ++++++++++++++++++++++---
 src/table.c               |   36 +++++++++++++++++++++----
 src/utils.c               |   45 +++++++++++++++++++++++++++++++
 9 files changed, 280 insertions(+), 33 deletions(-)
include/libnftnl/common.h +5 -0
index f0c20f0..f105c9a 100644
@@ -15,6 +15,11 @@ enum nft_output_type {
 	NFT_OUTPUT_JSON,
 };
 
+enum {
+	NFT_OUTPUT_FLAG_EVENTNEW	= 0,
+	NFT_OUTPUT_FLAG_EVENTDEL,
+};
+
 enum nft_parse_type {
 	NFT_PARSE_NONE		= 0,
 	NFT_PARSE_XML,
src/chain.c +32 -5
index 472203e..87558a1 100644
@@ -924,17 +924,44 @@ static int nft_chain_snprintf_default(char *buf, size_t size,
 int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
 		       uint32_t type, uint32_t flags)
 {
+	int ret, len = size, offset = 0;
+
+	if (flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTNEW,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	} else if (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTDEL,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
 	switch(type) {
 	case NFT_OUTPUT_DEFAULT:
-		return nft_chain_snprintf_default(buf, size, c);
+		ret = nft_chain_snprintf_default(buf+offset, len, c);
+		break;
 	case NFT_OUTPUT_XML:
-		return nft_chain_snprintf_xml(buf, size, c);
+		ret = nft_chain_snprintf_xml(buf+offset, len, c);
+		break;
 	case NFT_OUTPUT_JSON:
-		return nft_chain_snprintf_json(buf, size, c);
-	default:
+		ret = nft_chain_snprintf_json(buf+offset, len, c);
 		break;
+	default:
+		return -1;
 	}
-	return -1;
+
+	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	if ((flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) ||
+	    (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL))) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_closetag(type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
+	return offset;
 }
 EXPORT_SYMBOL(nft_chain_snprintf);
 
src/internal.h +2 -0
index ba994c8..8979bb7 100644
@@ -136,6 +136,8 @@ int nft_get_value(enum nft_type type, void *val, void *out);
 
 #include <stdio.h>
 int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags, int (*snprintf_cb)(char *buf, size_t bufsiz, void *obj, uint32_t type, uint32_t flags));
+const char *nft_event_opentag(uint32_t event, uint32_t format);
+const char *nft_event_closetag(uint32_t format);
 
 void xfree(const void *ptr);
 
src/rule.c +38 -5

55 lines not on this page · raw message

src/ruleset.c +58 -8

138 lines not on this page · raw message

src/set.c +37 -5

54 lines not on this page · raw message

src/set_elem.c +32 -5
index a747ba6..9181a10 100644
@@ -591,17 +591,44 @@ static int nft_set_elem_snprintf_xml(char *buf, size_t size,
 int nft_set_elem_snprintf(char *buf, size_t size, struct nft_set_elem *e,
 			   uint32_t type, uint32_t flags)
 {
+	int ret, len = size, offset = 0;
+
+	if (flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTNEW,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	} else if (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTDEL,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
 	switch(type) {
 	case NFT_OUTPUT_DEFAULT:
-		return nft_set_elem_snprintf_default(buf, size, e);
+		ret = nft_set_elem_snprintf_default(buf+offset, len, e);
+		break;
 	case NFT_OUTPUT_XML:
-		return nft_set_elem_snprintf_xml(buf, size, e, flags);
+		ret = nft_set_elem_snprintf_xml(buf+offset, len, e, flags);
+		break;
 	case NFT_OUTPUT_JSON:
-		return nft_set_elem_snprintf_json(buf, size, e, flags);
-	default:
+		ret = nft_set_elem_snprintf_json(buf+offset, len, e, flags);
 		break;
+	default:
+		return -1;
 	}
-	return -1;
+
+	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	if ((flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) ||
+	    (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL))) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_closetag(type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
+	return offset;
 }
 EXPORT_SYMBOL(nft_set_elem_snprintf);
 
src/table.c +31 -5
index 44e9a7b..82ca84d 100644
@@ -441,17 +441,43 @@ static int nft_table_snprintf_default(char *buf, size_t size, struct nft_table *
 int nft_table_snprintf(char *buf, size_t size, struct nft_table *t,
 		       uint32_t type, uint32_t flags)
 {
+	int ret, len = size, offset = 0;
+
+	if (flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTNEW,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	} else if (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTDEL,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
 	switch(type) {
 	case NFT_OUTPUT_DEFAULT:
-		return nft_table_snprintf_default(buf, size, t);
+		ret = nft_table_snprintf_default(buf+offset, len, t);
+		break;
 	case NFT_OUTPUT_XML:
-		return nft_table_snprintf_xml(buf, size, t);
+		ret = nft_table_snprintf_xml(buf+offset, len, t);
+		break;
 	case NFT_OUTPUT_JSON:
-		return nft_table_snprintf_json(buf, size, t);
-	default:
+		ret = nft_table_snprintf_json(buf+offset, len, t);
 		break;
+	default:
+		return -1;
 	}
-	return -1;
+	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	if ((flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) ||
+	    (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL))) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_closetag(type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
+	return offset;
 }
 EXPORT_SYMBOL(nft_table_snprintf);
 
src/utils.c +45 -0

51 lines not on this page · raw message

#1 lore raw

PATCH 2/2 examples: nft-events: use new events wrappers

Let's use the new event wrappers in the events example.

---
 examples/nft-events.c |   45 +++++++++++++++++++++++++++++++--------------
 1 file changed, 31 insertions(+), 14 deletions(-)
examples/nft-events.c +31 -14
index 989f4bd..6177f95 100644
@@ -22,11 +22,31 @@
 #include <libnftnl/chain.h>
 #include <libnftnl/rule.h>
 #include <libnftnl/set.h>
+#include <libnftnl/common.h>
+
+static uint32_t event2flag(uint32_t event)
+{
+	switch (event) {
+	case NFT_MSG_NEWTABLE:
+	case NFT_MSG_NEWCHAIN:
+	case NFT_MSG_NEWRULE:
+	case NFT_MSG_NEWSET:
+	case NFT_MSG_NEWSETELEM:
+		return (1 << NFT_OUTPUT_FLAG_EVENTNEW);
+	case NFT_MSG_DELTABLE:
+	case NFT_MSG_DELCHAIN:
+	case NFT_MSG_DELRULE:
+	case NFT_MSG_DELSET:
+	case NFT_MSG_DELSETELEM:
+		return (1 << NFT_OUTPUT_FLAG_EVENTDEL);
+	}
+
+	return 0;
+}
 
 static int table_cb(const struct nlmsghdr *nlh, int type)
 {
 	struct nft_table *t;
-	char buf[4096];
 
 	t = nft_table_alloc();
 	if (t == NULL) {
@@ -39,8 +59,8 @@ static int table_cb(const struct nlmsghdr *nlh, int type)
 		goto err_free;
 	}
 
-	nft_table_snprintf(buf, sizeof(buf), t, NFT_OUTPUT_DEFAULT, 0);
-	printf("[%s]\t%s\n", type == NFT_MSG_NEWTABLE ? "NEW" : "DEL", buf);
+	nft_table_fprintf(stdout, t, NFT_OUTPUT_DEFAULT, event2flag(type));
+	fprintf(stdout, "\n");
 
 err_free:
 	nft_table_free(t);
@@ -51,7 +71,6 @@ err:
 static int rule_cb(const struct nlmsghdr *nlh, int type)
 {
 	struct nft_rule *t;
-	char buf[4096];
 
 	t = nft_rule_alloc();
 	if (t == NULL) {
@@ -64,8 +83,8 @@ static int rule_cb(const struct nlmsghdr *nlh, int type)
 		goto err_free;
 	}
 
-	nft_rule_snprintf(buf, sizeof(buf), t, NFT_OUTPUT_DEFAULT, 0);
-	printf("[%s]\t%s\n", type == NFT_MSG_NEWRULE ? "NEW" : "DEL", buf);
+	nft_rule_fprintf(stdout, t, NFT_OUTPUT_DEFAULT, event2flag(type));
+	fprintf(stdout, "\n");
 
 err_free:
 	nft_rule_free(t);
@@ -76,7 +95,6 @@ err:
 static int chain_cb(const struct nlmsghdr *nlh, int type)
 {
 	struct nft_chain *t;
-	char buf[4096];
 
 	t = nft_chain_alloc();
 	if (t == NULL) {
@@ -89,8 +107,8 @@ static int chain_cb(const struct nlmsghdr *nlh, int type)
 		goto err_free;
 	}
 
-	nft_chain_snprintf(buf, sizeof(buf), t, NFT_OUTPUT_DEFAULT, 0);
-	printf("[%s]\t%s\n", type == NFT_MSG_NEWCHAIN ? "NEW" : "DEL", buf);
+	nft_chain_fprintf(stdout, t, NFT_OUTPUT_DEFAULT, event2flag(type));
+	fprintf(stdout, "\n");
 
 err_free:
 	nft_chain_free(t);
@@ -114,8 +132,8 @@ static int set_cb(const struct nlmsghdr *nlh, int type)
 		goto err_free;
 	}
 
-	nft_set_snprintf(buf, sizeof(buf), t, NFT_OUTPUT_DEFAULT, 0);
-	printf("[%s]\t%s\n", type == NFT_MSG_NEWSET ? "NEW" : "DEL", buf);
+	nft_set_fprintf(stdout, t, NFT_OUTPUT_DEFAULT, event2flag(type));
+	fprintf(stdout, "\n");
 
 err_free:
 	nft_set_free(t);
@@ -127,7 +145,6 @@ static int setelem_cb(const struct nlmsghdr *nlh, int type)
 {
 
 	struct nft_set *s;
-	char buf[4096];
 
 	s = nft_set_alloc();
 	if (s == NULL) {
@@ -140,8 +157,8 @@ static int setelem_cb(const struct nlmsghdr *nlh, int type)
 		goto err_free;
 	}
 
-	nft_set_snprintf(buf, sizeof(buf), s, NFT_OUTPUT_DEFAULT, 0);
-	printf("[%s]\t%s\n", type == NFT_MSG_NEWSETELEM ? "NEW" : "DEL", buf);
+	nft_set_fprintf(stdout, s, NFT_OUTPUT_DEFAULT, event2flag(type));
+	fprintf(stdout, "\n");
 
 err_free:
 	nft_set_free(s);
#2 lore raw
In reply to Arturo Borrero Gonzalez
Quoted 24 lines · Arturo Borrero Gonzalez

This patch uses the flag option of each output function to print an event wrapper string in each object.

In order to use this functionality, the caller must pass a flag with either NFT_OUTPUT_FLAG_EVENTNEW or NFT_OUTPUT_FLAG_EVENTDEL activated.

---
 include/libnftnl/common.h |    5 +++
 src/chain.c               |   37 ++++++++++++++++++++++---
 src/internal.h            |    2 +
 src/rule.c                |   43 ++++++++++++++++++++++++++---
 src/ruleset.c             |   66 ++++++++++++++++++++++++++++++++++++++++-----
 src/set.c                 |   42 +++++++++++++++++++++++++----
 src/set_elem.c            |   37 ++++++++++++++++++++++---
 src/table.c               |   36 +++++++++++++++++++++----
 src/utils.c               |   45 +++++++++++++++++++++++++++++++
 9 files changed, 280 insertions(+), 33 deletions(-)
include/libnftnl/common.h +0 -0
index f0c20f0..f105c9a 100644

include/libnftnl/common.h enum nft_output_type { · line 21

Quoted 7 lines
include/libnftnl/common.h +4 -0
@@ -15,6 +15,11 @@ enum nft_output_type {
 	NFT_OUTPUT_JSON,
 };
 
+enum {
+	NFT_OUTPUT_FLAG_EVENTNEW	= 0,
+	NFT_OUTPUT_FLAG_EVENTDEL,
+};

Please, change this to:

enum nft_output_flags {
        NFT_OF_EVENT_NEW        = (1 << 0),
        NFT_OF_EVENT_DEL        = (1 << 1),
};

So people don't need to use (1 << NFT_OUTPUT_FLAG_EVENTNEW) to pass the flag to nft_*_snprintf from their applications.

Quoted 9 lines
include/libnftnl/common.h +1 -0
+
 enum nft_parse_type {
 	NFT_PARSE_NONE		= 0,
 	NFT_PARSE_XML,
src/chain.c +0 -0
index 472203e..87558a1 100644

src/chain.c static int nft_chain_snprintf_default(char *buf, size_t size, · line 930

Quoted 7 lines
src/chain.c +4 -0
@@ -924,17 +924,44 @@ static int nft_chain_snprintf_default(char *buf, size_t size,
 int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
 		       uint32_t type, uint32_t flags)
 {
+	int ret, len = size, offset = 0;
+
+	if (flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) {
+		ret = snprintf(buf+offset, len, "%s",

Use this instead "%9s ".

So you can use [NEW] and [DELETE] tags and the plain text event output gets aligned (and you don't need to trim DELETE to DEL anymore).

#3 lore raw
In reply to Arturo Borrero Gonzalez
Quoted 22 lines · Arturo Borrero Gonzalez
src/chain.c +14 -0
index 472203e..87558a1 100644
@@ -924,17 +924,44 @@ static int nft_chain_snprintf_default(char *buf, size_t size,
 int nft_chain_snprintf(char *buf, size_t size, struct nft_chain *c,
 		       uint32_t type, uint32_t flags)
 {
+	int ret, len = size, offset = 0;
+
+	if (flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTNEW,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	} else if (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTDEL,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+

[...]

src/chain.c

Quoted 13 lines
src/chain.c +13 -0
+	if (flags & (1 << NFT_OUTPUT_FLAG_EVENTNEW)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTNEW,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		noevent_flags &= ~(1 << NFT_OUTPUT_FLAG_EVENTNEW);
+	} else if (flags & (1 << NFT_OUTPUT_FLAG_EVENTDEL)) {
+		ret = snprintf(buf+offset, len, "%s",
+			       nft_event_opentag(NFT_OUTPUT_FLAG_EVENTDEL,
+						 type));
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		noevent_flags &= ~(1 << NFT_OUTPUT_FLAG_EVENTDEL);
+	}

This code looks very similar, you can encapsulate it in one function to add the heading and the trailer.

Regarding the noevent_flags thing, which is the only different, you can do:

        unsigned int inner_flags &= ~NFT_OF_EVENT_ANY;

And use inner_flags to when you have nested calls (ie. like in ruleset.c).

The NFT_OF_EVENT_ANY mask should be something like:

enum ... {
NFT_OF_EVENT_ANY = (NFT_OF_EVENT_NEW | NFT_OF_EVENT_DEL)
};

Thanks.