diff mbox

[4/4] libnftnl: examples: Modify the example to allow add TLV objects as user data.

Message ID 1451849900-18077-4-git-send-email-carlosfg@riseup.net
State Changes Requested
Delegated to: Pablo Neira
Headers show

Commit Message

Carlos Falgueras García Jan. 3, 2016, 7:38 p.m. UTC
Example usage:
	> nft add table mytable
	> exmample/nft-set-add ip mytable myset "5:my data 0" "5:my data 1"
	> example/nft-set-get ip json | jq #jq: https://stedolan.github.io/jq/
	{
	  "set": {
	    "name": "myset",
	    "table": "mytable",
	    "flags": 2,
	    "family": "ip",
	    "key_type": 0,
	    "key_len": 2,
	    "userdata_len": 48,
	    "userdata": [
	      {
		"type": 5,
		"len": 9,
		"val": "my data 0"
	      },
	      {
		"type": 5,
		"len": 9,
		"val": "my data 1"
	      }
	    ]
	  }
	}

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 examples/nft-set-add.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 49 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/examples/nft-set-add.c b/examples/nft-set-add.c
index e040aca..42ff3c8 100644
--- a/examples/nft-set-add.c
+++ b/examples/nft-set-add.c
@@ -28,8 +28,14 @@ 
 #include <libmnl/libmnl.h>
 #include <libnftnl/set.h>
 
+#define ATTRBUF_SIZE 256
+
+static bool parse_user_data(char *argv[], int argc,
+			    struct nftnl_attrbuf *attrbuf);
+
 static struct nftnl_set *setup_set(uint8_t family, const char *table,
-				 const char *name)
+				 const char *name, const char *udata,
+				 unsigned int udlen)
 {
 	struct nftnl_set *s = NULL;
 
@@ -44,6 +50,8 @@  static struct nftnl_set *setup_set(uint8_t family, const char *table,
 	nftnl_set_set_u32(s, NFTNL_SET_FAMILY, family);
 	nftnl_set_set_u32(s, NFTNL_SET_KEY_LEN, 2);
 	nftnl_set_set_u32(s, NFTNL_SET_ID, 1);
+	if (udata != NULL)
+		nftnl_set_set_data(s, NFTNL_SET_USERDATA, udata, udlen);
 	nftnl_set_set_u32(s, NFTNL_SET_FLAGS, NFT_SET_CONSTANT);
 
 	return s;
@@ -71,13 +79,17 @@  int main(int argc, char *argv[])
 	struct nftnl_set *s;
 	struct nlmsghdr *nlh;
 	struct mnl_nlmsg_batch *batch;
+	struct nftnl_attrbuf *attrbuf = NULL;
 	uint8_t family;
 	char buf[MNL_SOCKET_BUFFER_SIZE];
 	uint32_t seq = time(NULL);
 	int ret;
 
-	if (argc != 4) {
-		fprintf(stderr, "Usage: %s <family> <table> <setname>\n", argv[0]);
+	if (argc < 4) {
+		fprintf(stderr,
+			"Usage: %s <family> <table> <setname> [<type:user_data>[ <type:user_data>...]]\n",
+			argv[0]
+		);
 		exit(EXIT_FAILURE);
 	}
 
@@ -94,7 +106,21 @@  int main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
-	s = setup_set(family, argv[2], argv[3]);
+	if (argc >= 5) {
+		attrbuf = nftnl_attrbuf_alloc(ATTRBUF_SIZE);
+		if (!parse_user_data(argv, argc, attrbuf)) {
+			fprintf(stderr, "Error parsing user data\n");
+			free(attrbuf);
+			return EXIT_FAILURE;
+		}
+
+		s = setup_set(family, argv[2], argv[3],
+			      (char *)nftnl_attrbuf_data(attrbuf),
+			      nftnl_attrbuf_len(attrbuf)
+			     );
+	} else {
+		s = setup_set(family, argv[2], argv[3], NULL, 0);
+	}
 
 	nl = mnl_socket_open(NETLINK_NETFILTER);
 	if (nl == NULL) {
@@ -147,6 +173,25 @@  int main(int argc, char *argv[])
 	}
 
 	mnl_socket_close(nl);
+	if (attrbuf)
+		free(attrbuf);
 
 	return EXIT_SUCCESS;
 }
+
+static bool parse_user_data(char *argv[], int argc,
+			    struct nftnl_attrbuf *attrbuf)
+{
+	int i;
+	char *type, *value;
+
+	for (i = 4; i < argc; i++) {
+		type = strchr(argv[i], ':') - 1;
+		value = type + 2;
+		if (!nftnl_attr_put_check(attrbuf, ATTRBUF_SIZE, atoi(type),
+					  strlen(value), value))
+			return false;
+	}
+
+	return true;
+}