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
next prev parent 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).