netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Carlos Falgueras García" <carlosfg@riseup.net>
To: netfilter-devel@vger.kernel.org
Cc: pablo@netfilter.org, kaber@trash.net
Subject: [PATCH 2/4] libnftnl: set: Add new attribute into 'set' to store an arbitrary length user data.
Date: Sun,  3 Jan 2016 20:38:18 +0100	[thread overview]
Message-ID: <1451849900-18077-2-git-send-email-carlosfg@riseup.net> (raw)
In-Reply-To: <1451849900-18077-1-git-send-email-carlosfg@riseup.net>

The new structure 'user' holds a pointer to user data and its length. The
kernel must have the flag NFTA_SET_USERDATA to support this feature.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 include/libnftnl/set.h              |  2 ++
 include/linux/netfilter/nf_tables.h |  2 ++
 include/set.h                       |  4 +++
 src/set.c                           | 50 +++++++++++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+)

diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 11243f5..7a5a512 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -22,6 +22,7 @@ enum nftnl_set_attr {
 	NFTNL_SET_DESC_SIZE,
 	NFTNL_SET_TIMEOUT,
 	NFTNL_SET_GC_INTERVAL,
+	NFTNL_SET_USERDATA,
 	__NFTNL_SET_MAX
 };
 #define NFTNL_SET_MAX (__NFTNL_SET_MAX - 1)
@@ -158,6 +159,7 @@ enum {
 	NFT_SET_ATTR_DESC_SIZE,
 	NFT_SET_ATTR_TIMEOUT,
 	NFT_SET_ATTR_GC_INTERVAL,
+	NFT_SET_ATTR_USERDATA,
 	__NFT_SET_ATTR_MAX
 };
 #define NFT_SET_ATTR_MAX (__NFT_SET_ATTR_MAX - 1)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index f77693b..9beddc5 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -291,6 +291,7 @@ enum nft_set_desc_attributes {
  * @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
  * @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
  * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
+ * @NFTA_SET_USERDATA: user data (NLA_BINARY)
  */
 enum nft_set_attributes {
 	NFTA_SET_UNSPEC,
@@ -306,6 +307,7 @@ enum nft_set_attributes {
 	NFTA_SET_ID,
 	NFTA_SET_TIMEOUT,
 	NFTA_SET_GC_INTERVAL,
+	NFTA_SET_USERDATA,
 	__NFTA_SET_MAX
 };
 #define NFTA_SET_MAX		(__NFTA_SET_MAX - 1)
diff --git a/include/set.h b/include/set.h
index c3b96f2..85bd389 100644
--- a/include/set.h
+++ b/include/set.h
@@ -14,6 +14,10 @@ struct nftnl_set {
 	uint32_t		key_len;
 	uint32_t		data_type;
 	uint32_t		data_len;
+	struct {
+		void		*data;
+		uint32_t	len;
+	} user;
 	uint32_t		id;
 	enum nft_set_policies	policy;
 	struct {
diff --git a/src/set.c b/src/set.c
index 8369f7f..315bced 100644
--- a/src/set.c
+++ b/src/set.c
@@ -19,6 +19,7 @@
 #include <netinet/in.h>
 #include <limits.h>
 #include <errno.h>
+#include <ctype.h>
 
 #include <libmnl/libmnl.h>
 #include <linux/netfilter/nfnetlink.h>
@@ -91,6 +92,7 @@ void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
 	case NFTNL_SET_DESC_SIZE:
 	case NFTNL_SET_TIMEOUT:
 	case NFTNL_SET_GC_INTERVAL:
+	case NFTNL_SET_USERDATA:
 		break;
 	default:
 		return;
@@ -167,6 +169,10 @@ void nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
 	case NFTNL_SET_GC_INTERVAL:
 		s->gc_interval = *((uint32_t *)data);
 		break;
+	case NFTNL_SET_USERDATA:
+		s->user.data = (void *)data;
+		s->user.len  = data_len;
+		break;
 	}
 	s->flags |= (1 << attr);
 }
@@ -240,6 +246,9 @@ const void *nftnl_set_get_data(struct nftnl_set *s, uint16_t attr,
 	case NFTNL_SET_GC_INTERVAL:
 		*data_len = sizeof(uint32_t);
 		return &s->gc_interval;
+	case NFTNL_SET_USERDATA:
+		*data_len = s->user.len;
+		return s->user.data;
 	}
 	return NULL;
 }
@@ -348,6 +357,8 @@ void nftnl_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
 		mnl_attr_put_u64(nlh, NFTA_SET_TIMEOUT, htobe64(s->timeout));
 	if (s->flags & (1 << NFTNL_SET_GC_INTERVAL))
 		mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, htonl(s->gc_interval));
+	if (s->flags & (1 << NFTNL_SET_USERDATA))
+		mnl_attr_put(nlh, NFTA_SET_USERDATA, s->user.len, s->user.data);
 }
 EXPORT_SYMBOL_ALIAS(nftnl_set_nlmsg_build_payload, nft_set_nlmsg_build_payload);
 
@@ -376,6 +387,10 @@ static int nftnl_set_parse_attr_cb(const struct nlattr *attr, void *data)
 		if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
 			abi_breakage();
 		break;
+	case NFTA_SET_USERDATA:
+		if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
+			abi_breakage();
+		break;
 	case NFTA_SET_TIMEOUT:
 		if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0)
 			abi_breakage();
@@ -480,6 +495,20 @@ int nftnl_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s)
 		s->gc_interval = ntohl(mnl_attr_get_u32(tb[NFTA_SET_GC_INTERVAL]));
 		s->flags |= (1 << NFTNL_SET_GC_INTERVAL);
 	}
+	if (tb[NFTA_SET_USERDATA]) {
+		const void *udata =
+			mnl_attr_get_payload(tb[NFTA_SET_USERDATA]);
+
+		if (s->user.data)
+			xfree(s->user.data);
+
+		s->user.len  = mnl_attr_get_payload_len(tb[NFTA_SET_USERDATA]);
+		s->user.data = malloc(s->user.len);
+		if (s->user.data == NULL)
+			return -1;
+		memcpy(s->user.data, udata, s->user.len);
+		s->flags |= (1 << NFTNL_SET_USERDATA);
+	}
 	if (tb[NFTA_SET_DESC])
 		ret = nftnl_set_desc_parse(s, tb[NFTA_SET_DESC]);
 
@@ -775,6 +804,7 @@ static int nftnl_set_snprintf_json(char *buf, size_t size, struct nftnl_set *s,
 				  uint32_t type, uint32_t flags)
 {
 	int len = size, offset = 0, ret;
+	int i;
 	struct nftnl_set_elem *elem;
 
 	ret = snprintf(buf, len, "{\"set\":{");
@@ -826,6 +856,26 @@ static int nftnl_set_snprintf_json(char *buf, size_t size, struct nftnl_set *s,
 		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 	}
 
+	if (s->flags & (1 << NFTNL_SET_USERDATA)) {
+		ret = snprintf(buf + offset, len, ",\"userdata_len\":%u",
+			       s->user.len);
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		ret = snprintf(buf + offset, len, ",\"userdata\":\"");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		char *c = s->user.data;
+
+		for (i = 0; i < s->user.len; i++) {
+			ret = snprintf(buf + offset, len, "%c",
+				       isprint(c[i]) ? c[i] : ' ');
+			SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		}
+
+		ret = snprintf(buf + offset, len, "\"");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
 	if (s->flags & (1 << NFTNL_SET_DESC_SIZE)) {
 		ret = snprintf(buf + offset, len, ",\"desc_size\":%u",
 			       s->desc.size);
-- 
2.6.4

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2016-01-03 19:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-03 19:38 [PATCH 1/4] nf: netfilter: nf_tables_api: Add new attributes into nft_set to store user data Carlos Falgueras García
2016-01-03 19:38 ` Carlos Falgueras García [this message]
2016-01-03 19:38 ` [PATCH 3/4] libnftnl: set: Implement new buffer of TLV objects Carlos Falgueras García
2016-01-04 12:06   ` Patrick McHardy
2016-01-03 19:38 ` [PATCH 4/4] libnftnl: examples: Modify the example to allow add TLV objects as user data Carlos Falgueras García
2016-01-04 12:32 ` [PATCH 1/4] nf: netfilter: nf_tables_api: Add new attributes into nft_set to store " Patrick McHardy
2016-01-05 10:34 ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1451849900-18077-2-git-send-email-carlosfg@riseup.net \
    --to=carlosfg@riseup.net \
    --cc=kaber@trash.net \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).