diff mbox series

[libnftnl,v2] set: Add support for NFTA_SET_SUBKEY attributes

Message ID de1e8744507f6590886a5cb7eef98f23775ee2fa.1574354321.git.sbrivio@redhat.com
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series [libnftnl,v2] set: Add support for NFTA_SET_SUBKEY attributes | expand

Commit Message

Stefano Brivio Nov. 21, 2019, 5:10 p.m. UTC
If the NFTNL_SET_SUBKEY flag is passed, send one NFTA_SET_SUBKEY
attribute for each subkey_len attribute in the set description.

Note that our internal representation, and nftables storage, for
these attributes, is 8-bit wide, but the kernel uses 32 bits. As
field length is expressed in bits, this is probably a good
compromise to keep the UAPI future-proof and memory footprint to
a minimum, for the moment being.

This is the libnftnl counterpart for nftables patch:
  src: Add support for and export NFT_SET_SUBKEY attributes

and it has a UAPI dependency on kernel patch:
  [PATCH nf-next 1/8] nf_tables: Support for subkeys, set with multiple ranged fields

v2:
 - fixed grammar in commit message
 - removed copy of array bytes in nftnl_set_nlmsg_build_subkey_payload(),
   we're simply passing values to htonl() (Phil Sutter)

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 include/libnftnl/set.h |  1 +
 include/set.h          |  2 ++
 src/set.c              | 27 +++++++++++++++++++++++++++
 3 files changed, 30 insertions(+)

Comments

Phil Sutter Nov. 21, 2019, 5:53 p.m. UTC | #1
On Thu, Nov 21, 2019 at 06:10:21PM +0100, Stefano Brivio wrote:
> If the NFTNL_SET_SUBKEY flag is passed, send one NFTA_SET_SUBKEY
> attribute for each subkey_len attribute in the set description.
> 
> Note that our internal representation, and nftables storage, for
> these attributes, is 8-bit wide, but the kernel uses 32 bits. As
> field length is expressed in bits, this is probably a good
> compromise to keep the UAPI future-proof and memory footprint to
> a minimum, for the moment being.
> 
> This is the libnftnl counterpart for nftables patch:
>   src: Add support for and export NFT_SET_SUBKEY attributes
> 
> and it has a UAPI dependency on kernel patch:
>   [PATCH nf-next 1/8] nf_tables: Support for subkeys, set with multiple ranged fields
> 
> v2:
>  - fixed grammar in commit message
>  - removed copy of array bytes in nftnl_set_nlmsg_build_subkey_payload(),
>    we're simply passing values to htonl() (Phil Sutter)
> 
> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>

Acked-by: Phil Sutter <phil@nwl.cc>
diff mbox series

Patch

diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index db3fa686d60a..0a5e02aaa74c 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -29,6 +29,7 @@  enum nftnl_set_attr {
 	NFTNL_SET_USERDATA,
 	NFTNL_SET_OBJ_TYPE,
 	NFTNL_SET_HANDLE,
+	NFTNL_SET_SUBKEY,
 	__NFTNL_SET_MAX
 };
 #define NFTNL_SET_MAX (__NFTNL_SET_MAX - 1)
diff --git a/include/set.h b/include/set.h
index 446acd24ca7c..41d5dba286bf 100644
--- a/include/set.h
+++ b/include/set.h
@@ -31,6 +31,8 @@  struct nftnl_set {
 	uint32_t		flags;
 	uint32_t		gc_interval;
 	uint64_t		timeout;
+
+	uint8_t			subkey_len[NFT_REG32_COUNT];
 };
 
 struct nftnl_set_list;
diff --git a/src/set.c b/src/set.c
index 78447c676f51..2306c10eebae 100644
--- a/src/set.c
+++ b/src/set.c
@@ -91,6 +91,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_SUBKEY:
 		break;
 	case NFTNL_SET_USERDATA:
 		xfree(s->user.data);
@@ -115,6 +116,7 @@  static uint32_t nftnl_set_validate[NFTNL_SET_MAX + 1] = {
 	[NFTNL_SET_DESC_SIZE]	= sizeof(uint32_t),
 	[NFTNL_SET_TIMEOUT]		= sizeof(uint64_t),
 	[NFTNL_SET_GC_INTERVAL]	= sizeof(uint32_t),
+	[NFTNL_SET_SUBKEY]		= sizeof(uint8_t) * NFT_REG32_COUNT,
 };
 
 EXPORT_SYMBOL(nftnl_set_set_data);
@@ -190,6 +192,9 @@  int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
 		memcpy(s->user.data, data, data_len);
 		s->user.len = data_len;
 		break;
+	case NFTNL_SET_SUBKEY:
+		memcpy(s->subkey_len, data, data_len);
+		break;
 	}
 	s->flags |= (1 << attr);
 	return 0;
@@ -361,6 +366,22 @@  nftnl_set_nlmsg_build_desc_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
 	mnl_attr_nest_end(nlh, nest);
 }
 
+static void
+nftnl_set_nlmsg_build_subkey_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
+{
+	struct nlattr *nest;
+	int i;
+
+	nest = mnl_attr_nest_start(nlh, NFTA_SET_SUBKEY);
+
+	for (i = 0; i < NFT_REG32_COUNT && s->subkey_len[i]; i++) {
+		mnl_attr_put_u32(nlh, NFTA_SET_SUBKEY_LEN,
+				 htonl(s->subkey_len[i]));
+	}
+
+	mnl_attr_nest_end(nlh, nest);
+}
+
 EXPORT_SYMBOL(nftnl_set_nlmsg_build_payload);
 void nftnl_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
 {
@@ -395,6 +416,8 @@  void nftnl_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
 		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);
+	if (s->flags & (1 << NFTNL_SET_SUBKEY))
+		nftnl_set_nlmsg_build_subkey_payload(nlh, s);
 }
 
 
@@ -439,6 +462,10 @@  static int nftnl_set_parse_attr_cb(const struct nlattr *attr, void *data)
 		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
 			abi_breakage();
 		break;
+	case NFTA_SET_SUBKEY:
+		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
+			abi_breakage();
+		break;
 	}
 
 	tb[type] = attr;