diff mbox

[1/2,libnftnl] set: Add new attribute into 'set' to store user data

Message ID 20160627170523.6560-1-carlosfg@riseup.net
State Accepted
Delegated to: Pablo Neira
Headers show

Commit Message

Carlos Falgueras García June 27, 2016, 5:05 p.m. UTC
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 |  1 +
 include/set.h          |  4 ++++
 src/set.c              | 29 +++++++++++++++++++++++++++++
 3 files changed, 34 insertions(+)

Comments

Pablo Neira Ayuso July 1, 2016, 2:24 p.m. UTC | #1
On Mon, Jun 27, 2016 at 07:05:22PM +0200, Carlos Falgueras García wrote:
> 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.

Applied, thanks.
--
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
diff mbox

Patch

diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 3d50d56..5266b6f 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)
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 7b333ed..ebb4329 100644
--- a/src/set.c
+++ b/src/set.c
@@ -87,6 +87,9 @@  void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
 	case NFTNL_SET_TIMEOUT:
 	case NFTNL_SET_GC_INTERVAL:
 		break;
+	case NFTNL_SET_USERDATA:
+		xfree(s->user.data);
+		break;
 	default:
 		return;
 	}
@@ -164,6 +167,16 @@  int 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:
+		if (s->flags & (1 << NFTNL_SET_USERDATA))
+			xfree(s->user.data);
+
+		s->user.data = malloc(data_len);
+		if (!s->user.data)
+			return -1;
+		memcpy(s->user.data, data, data_len);
+		s->user.len = data_len;
+		break;
 	}
 	s->flags |= (1 << attr);
 	return 0;
@@ -238,6 +251,9 @@  const void *nftnl_set_get_data(const 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;
 }
@@ -352,6 +368,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);
 
@@ -380,6 +398,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();
@@ -490,6 +512,13 @@  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]) {
+		ret = nftnl_set_set_data(s, NFTNL_SET_USERDATA,
+			mnl_attr_get_payload(tb[NFTA_SET_USERDATA]),
+			mnl_attr_get_payload_len(tb[NFTA_SET_USERDATA]));
+		if (ret < 0)
+			return ret;
+	}
 	if (tb[NFTA_SET_DESC]) {
 		ret = nftnl_set_desc_parse(s, tb[NFTA_SET_DESC]);
 		if (ret < 0)