From: Stefano Brivio <sbrivio@redhat.com>
To: Pablo Neira Ayuso <pablo@netfilter.org>, netfilter-devel@vger.kernel.org
Cc: "Florian Westphal" <fw@strlen.de>,
"Kadlecsik József" <kadlec@blackhole.kfki.hu>,
"Eric Garver" <eric@garver.life>, "Phil Sutter" <phil@nwl.cc>
Subject: [PATCH libnftnl v4 2/3] set: Add support for NFTA_SET_DESC_CONCAT attributes
Date: Thu, 30 Jan 2020 01:16:33 +0100 [thread overview]
Message-ID: <ed240166fb60f087865cc94245ae5d46dd29286d.1580342940.git.sbrivio@redhat.com> (raw)
In-Reply-To: <cover.1580342940.git.sbrivio@redhat.com>
If NFTNL_SET_DESC_CONCAT data is passed, pass that to the kernel
as NFTA_SET_DESC_CONCAT attributes: it describes the length of
single concatenated fields, in bytes.
Similarly, parse NFTA_SET_DESC_CONCAT attributes if received
from the kernel.
This is the libnftnl counterpart for nftables patch:
src: Add support for NFTNL_SET_DESC_CONCAT
v4:
- move NFTNL_SET_DESC_CONCAT to the end of enum nftnl_set_attr
to avoid ABI breakage (Pablo Neira Ayuso)
v3:
- use NFTNL_SET_DESC_CONCAT and NFTA_SET_DESC_CONCAT instead of a
stand-alone NFTA_SET_SUBKEY attribute (Pablo Neira Ayuso)
- pass field length in bytes instead of bits, fields would get
unnecessarily big otherwise
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 | 111 ++++++++++++++++++++++++++++++++++-------
3 files changed, 95 insertions(+), 19 deletions(-)
diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index db3fa686d60a..bbbf58ded99a 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_DESC_CONCAT,
__NFTNL_SET_MAX
};
#define NFTNL_SET_MAX (__NFTNL_SET_MAX - 1)
diff --git a/include/set.h b/include/set.h
index 446acd24ca7c..895ffdb48bdb 100644
--- a/include/set.h
+++ b/include/set.h
@@ -25,6 +25,8 @@ struct nftnl_set {
enum nft_set_policies policy;
struct {
uint32_t size;
+ uint8_t field_len[NFT_REG32_COUNT];
+ uint8_t field_count;
} desc;
struct list_head element_list;
diff --git a/src/set.c b/src/set.c
index 78447c676f51..651dcfa56022 100644
--- a/src/set.c
+++ b/src/set.c
@@ -89,6 +89,7 @@ void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
case NFTNL_SET_ID:
case NFTNL_SET_POLICY:
case NFTNL_SET_DESC_SIZE:
+ case NFTNL_SET_DESC_CONCAT:
case NFTNL_SET_TIMEOUT:
case NFTNL_SET_GC_INTERVAL:
break;
@@ -174,6 +175,10 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
case NFTNL_SET_DESC_SIZE:
memcpy(&s->desc.size, data, sizeof(s->desc.size));
break;
+ case NFTNL_SET_DESC_CONCAT:
+ memcpy(&s->desc.field_len, data, data_len);
+ while (s->desc.field_len[++s->desc.field_count]);
+ break;
case NFTNL_SET_TIMEOUT:
memcpy(&s->timeout, data, sizeof(s->timeout));
break;
@@ -266,6 +271,9 @@ const void *nftnl_set_get_data(const struct nftnl_set *s, uint16_t attr,
case NFTNL_SET_DESC_SIZE:
*data_len = sizeof(uint32_t);
return &s->desc.size;
+ case NFTNL_SET_DESC_CONCAT:
+ *data_len = s->desc.field_count;
+ return s->desc.field_len;
case NFTNL_SET_TIMEOUT:
*data_len = sizeof(uint64_t);
return &s->timeout;
@@ -351,13 +359,42 @@ err:
return NULL;
}
+static void nftnl_set_nlmsg_build_desc_size_payload(struct nlmsghdr *nlh,
+ struct nftnl_set *s)
+{
+ mnl_attr_put_u32(nlh, NFTA_SET_DESC_SIZE, htonl(s->desc.size));
+}
+
+static void nftnl_set_nlmsg_build_desc_concat_payload(struct nlmsghdr *nlh,
+ struct nftnl_set *s)
+{
+ struct nlattr *nest;
+ int i;
+
+ nest = mnl_attr_nest_start(nlh, NFTA_SET_DESC_CONCAT);
+ for (i = 0; i < NFT_REG32_COUNT && i < s->desc.field_count; i++) {
+ struct nlattr *nest_elem;
+
+ nest_elem = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
+ mnl_attr_put_u32(nlh, NFTA_SET_FIELD_LEN,
+ htonl(s->desc.field_len[i]));
+ mnl_attr_nest_end(nlh, nest_elem);
+ }
+ mnl_attr_nest_end(nlh, nest);
+}
+
static void
nftnl_set_nlmsg_build_desc_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
{
struct nlattr *nest;
nest = mnl_attr_nest_start(nlh, NFTA_SET_DESC);
- mnl_attr_put_u32(nlh, NFTA_SET_DESC_SIZE, htonl(s->desc.size));
+
+ if (s->flags & (1 << NFTNL_SET_DESC_SIZE))
+ nftnl_set_nlmsg_build_desc_size_payload(nlh, s);
+ if (s->flags & (1 << NFTNL_SET_DESC_CONCAT))
+ nftnl_set_nlmsg_build_desc_concat_payload(nlh, s);
+
mnl_attr_nest_end(nlh, nest);
}
@@ -387,7 +424,7 @@ void nftnl_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
mnl_attr_put_u32(nlh, NFTA_SET_ID, htonl(s->id));
if (s->flags & (1 << NFTNL_SET_POLICY))
mnl_attr_put_u32(nlh, NFTA_SET_POLICY, htonl(s->policy));
- if (s->flags & (1 << NFTNL_SET_DESC_SIZE))
+ if (s->flags & (1 << NFTNL_SET_DESC_SIZE | 1 << NFTNL_SET_DESC_CONCAT))
nftnl_set_nlmsg_build_desc_payload(nlh, s);
if (s->flags & (1 << NFTNL_SET_TIMEOUT))
mnl_attr_put_u64(nlh, NFTA_SET_TIMEOUT, htobe64(s->timeout));
@@ -445,39 +482,75 @@ static int nftnl_set_parse_attr_cb(const struct nlattr *attr, void *data)
return MNL_CB_OK;
}
-static int nftnl_set_desc_parse_attr_cb(const struct nlattr *attr, void *data)
+static int
+nftnl_set_desc_concat_field_parse_attr_cb(const struct nlattr *attr, void *data)
+{
+ int type = mnl_attr_get_type(attr);
+ struct nftnl_set *s = data;
+
+ if (type != NFTA_SET_FIELD_LEN)
+ return MNL_CB_OK;
+
+ if (mnl_attr_validate(attr, MNL_TYPE_U32))
+ return MNL_CB_ERROR;
+
+ s->desc.field_len[s->desc.field_count] = ntohl(mnl_attr_get_u32(attr));
+ s->desc.field_count++;
+
+ return MNL_CB_OK;
+}
+
+static int
+nftnl_set_desc_concat_parse_attr_cb(const struct nlattr *attr, void *data)
{
- const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
+ struct nftnl_set *s = data;
+
+ if (type != NFTA_LIST_ELEM)
+ return MNL_CB_OK;
+
+ return mnl_attr_parse_nested(attr,
+ nftnl_set_desc_concat_field_parse_attr_cb,
+ s);
+}
+
+static int nftnl_set_desc_parse_attr_cb(const struct nlattr *attr, void *data)
+{
+ int type = mnl_attr_get_type(attr), err;
+ struct nftnl_set *s = data;
if (mnl_attr_type_valid(attr, NFTA_SET_DESC_MAX) < 0)
return MNL_CB_OK;
switch (type) {
case NFTA_SET_DESC_SIZE:
- if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
abi_breakage();
+ break;
+ }
+
+ s->desc.size = ntohl(mnl_attr_get_u32(attr));
+ s->flags |= (1 << NFTNL_SET_DESC_SIZE);
+ break;
+ case NFTA_SET_DESC_CONCAT:
+ err = mnl_attr_parse_nested(attr,
+ nftnl_set_desc_concat_parse_attr_cb,
+ s);
+ if (err != MNL_CB_OK)
+ abi_breakage();
+
+ s->flags |= (1 << NFTNL_SET_DESC_CONCAT);
+ break;
+ default:
break;
}
- tb[type] = attr;
return MNL_CB_OK;
}
-static int nftnl_set_desc_parse(struct nftnl_set *s,
- const struct nlattr *attr)
+static int nftnl_set_desc_parse(struct nftnl_set *s, const struct nlattr *attr)
{
- struct nlattr *tb[NFTA_SET_DESC_MAX + 1] = {};
-
- if (mnl_attr_parse_nested(attr, nftnl_set_desc_parse_attr_cb, tb) < 0)
- return -1;
-
- if (tb[NFTA_SET_DESC_SIZE]) {
- s->desc.size = ntohl(mnl_attr_get_u32(tb[NFTA_SET_DESC_SIZE]));
- s->flags |= (1 << NFTNL_SET_DESC_SIZE);
- }
-
- return 0;
+ return mnl_attr_parse_nested(attr, nftnl_set_desc_parse_attr_cb, s);
}
EXPORT_SYMBOL(nftnl_set_nlmsg_parse);
--
2.24.1
next prev parent reply other threads:[~2020-01-30 0:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-30 0:16 [PATCH libnftnl v4 0/3] Attributes for concatenated ranges Stefano Brivio
2020-01-30 0:16 ` [PATCH libnftnl v4 1/3] include: resync nf_tables.h cache copy Stefano Brivio
2020-01-30 0:16 ` Stefano Brivio [this message]
2020-01-30 0:16 ` [PATCH libnftnl v4 3/3] set_elem: Introduce support for NFTNL_SET_ELEM_KEY_END Stefano Brivio
2020-02-05 15:01 ` [PATCH libnftnl v4 0/3] Attributes for concatenated ranges 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=ed240166fb60f087865cc94245ae5d46dd29286d.1580342940.git.sbrivio@redhat.com \
--to=sbrivio@redhat.com \
--cc=eric@garver.life \
--cc=fw@strlen.de \
--cc=kadlec@blackhole.kfki.hu \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
--cc=phil@nwl.cc \
/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).