From: Pablo Neira Ayuso <pablo@netfilter.org>
To: "Carlos Falgueras García" <carlosfg@riseup.net>
Cc: netfilter-devel@vger.kernel.org, kaber@trash.net
Subject: Re: [PATCH 1/3 v2] libnftnl: Implement new buffer of TLV objects.
Date: Wed, 2 Mar 2016 19:32:07 +0100 [thread overview]
Message-ID: <20160302183207.GA1351@salvia> (raw)
In-Reply-To: <1456763140-15121-1-git-send-email-carlosfg@riseup.net>
On Mon, Feb 29, 2016 at 05:25:38PM +0100, Carlos Falgueras García wrote:
> These functions allow to create a buffer (nftnl_attrbuf) of TLV objects
> (nftnl_attr). It is inspired by libmnl/src/attr.c. It can be used to store
> several variable length user data into an object.
>
> Example usage:
> ```
> struct nftnl_attrbuf *attrbuf;
> struct nftnl_attr *attr;
> const char str[] = "Hello World!";
>
> attrbuf = nftnl_attrbuf_alloc(ATTRBUF_SIZE);
> if (!nftnl_attr_put_check(attrbuf, NFTNL_ATTR_TYPE_COMMENT,
> strlen(str), str)
> ) {
Please, mind your coding style.
if (!nftnl_attr_put(attrbuf, NFTNL_ATTR_TYPE_COMMENT, strlen(str), str) {
BTW, NFTNL_ATTR_TYPE_COMMENT doesn't exist in this tree.
> fprintf(stderr, "Can't put attribute \"%s\"", str);
On this snippet, on error you should:
perror("Can't put attribute \"%s\"", str);
exit(EXIT_FAILURE);
> }
>
> nftnl_attr_for_each(attr, attrbuf) {
> printf("%s\n", (char *)nftnl_attr_get_value(attr));
> }
>
> nftnl_attr_free(attrbuf);
> ```
>
> Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
> ---
> include/Makefile.am | 1 +
> include/attr.h | 40 +++++++++++++
> include/libnftnl/Makefile.am | 1 +
> include/libnftnl/attr.h | 53 +++++++++++++++++
> src/Makefile.am | 1 +
> src/attr.c | 132 +++++++++++++++++++++++++++++++++++++++++++
> src/libnftnl.map | 16 ++++++
> 7 files changed, 244 insertions(+)
> create mode 100644 include/attr.h
> create mode 100644 include/libnftnl/attr.h
> create mode 100644 src/attr.c
>
> diff --git a/include/Makefile.am b/include/Makefile.am
> index be9eb9b..785ec15 100644
> --- a/include/Makefile.am
> +++ b/include/Makefile.am
> @@ -12,4 +12,5 @@ noinst_HEADERS = internal.h \
> expr.h \
> json.h \
> set_elem.h \
> + attr.h \
> utils.h
> diff --git a/include/attr.h b/include/attr.h
> new file mode 100644
> index 0000000..2a29fa0
> --- /dev/null
> +++ b/include/attr.h
> @@ -0,0 +1,40 @@
> +#ifndef _LIBNFTNL_ATTR_INTERNAL_H_
> +#define _LIBNFTNL_ATTR_INTERNAL_H_
> +
> +#include <stdint.h>
> +#include <stddef.h>
> +
> +/*
> + * TLV structures:
> + * nftnl_attr
> + * <-------- HEADER --------> <------ PAYLOAD ------>
> + * +------------+-------------+- - - - - - - - - - - -+
> + * | type | len | value |
> + * | (1 byte) | (1 byte) | |
> + * +--------------------------+- - - - - - - - - - - -+
> + * <-- sizeof(nftnl_attr) --> <-- nftnl_attr->len -->
> + */
> +struct __attribute__((__packed__)) nftnl_attr {
> + uint8_t type;
> + uint8_t len;
> + unsigned char value[];
> +};
struct nftnl_attr {
...
} __attribute__((__packed__));
> +/*
> + * +-------------------------------------------++
> + * | data[] ||
> + * | || ||
> + * | \/ \/
> + * +-------+-------+- - - - -+-------+-------+ ... +-------+- - - - - - -+
> + * | size | end | padding | TLV | TLV | | TLV | Empty |
> + * +-------+-------+- - - - -+-------+-------+ ... +-------+- - - - - - -+
> + * |<- nftnl_attrbuf_get_len() ->|
> + * |<-------- nftnl_attrbuf_get_size() ------->|
> + */
> +struct nftnl_attrbuf {
> + size_t size;
> + char *end;
> + char data[] __attribute__((aligned(64)));
No need for this aligned for a control structure.
> +};
> +
> +#endif
> diff --git a/include/libnftnl/Makefile.am b/include/libnftnl/Makefile.am
> index 84f01b6..a3a6fb3 100644
> --- a/include/libnftnl/Makefile.am
> +++ b/include/libnftnl/Makefile.am
> @@ -7,4 +7,5 @@ pkginclude_HEADERS = batch.h \
> set.h \
> ruleset.h \
> common.h \
> + attr.h \
> gen.h
> diff --git a/include/libnftnl/attr.h b/include/libnftnl/attr.h
> new file mode 100644
> index 0000000..cc3689e
> --- /dev/null
> +++ b/include/libnftnl/attr.h
> @@ -0,0 +1,53 @@
> +#ifndef _LIBNFTNL_ATTR_H_
> +#define _LIBNFTNL_ATTR_H_
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +
> +/*
> + * nftnl attributes API
> + */
> +struct nftnl_attr;
Could you rename this to:
struct nftnl_udata;
since this will be used for rule and set udata areas.
> +struct nftnl_attrbuf;
struct nftnl_udata_buf;
> +/* nftnl_attrbuf */
> +struct nftnl_attrbuf *nftnl_attrbuf_alloc(size_t data_size);
> +void nftnl_attrbuf_free(struct nftnl_attrbuf *attrbuf);
> +size_t nftnl_attrbuf_get_len(const struct nftnl_attrbuf *attrbuf);
> +size_t nftnl_attrbuf_get_size(const struct nftnl_attrbuf *attrbuf);
> +void *nftnl_attrbuf_get_data(const struct nftnl_attrbuf *attrbuf);
> +void nftnl_attrbuf_copy_data(struct nftnl_attrbuf *attrbuf,
> + const void *data, size_t len);
> +struct nftnl_attr *nftnl_attrbuf_get_start(const struct nftnl_attrbuf *attrbuf);
> +struct nftnl_attr *nftnl_attrbuf_get_end(const struct nftnl_attrbuf *attrbuf);
> +
> +/* TLV attribute getters */
> +uint8_t nftnl_attr_get_type(const struct nftnl_attr *attr);
> +uint8_t nftnl_attr_get_len(const struct nftnl_attr *attr);
> +void *nftnl_attr_get_value(const struct nftnl_attr *attr);
> +
> +/* TLV attribute putters */
> +struct nftnl_attr *nftnl_attr_put(struct nftnl_attrbuf *attrbuf,
> + uint8_t type, uint8_t len, const void *value);
Please, remove tis nftnl_attr_put() and rename nftnl_attr_put_check to
become nftnl_attr_put().
> +struct nftnl_attr *nftnl_attr_put_check(struct nftnl_attrbuf *attrbuf,
> + uint8_t type, size_t len,
> + const void *value);
> +
> +/* TLV iterators */
> +struct nftnl_attr *nftnl_attr_next(const struct nftnl_attr *attr);
> +
> +#define nftnl_attr_for_each(attr, attrbuf) \
> + for ((attr) = nftnl_attrbuf_get_start(attrbuf); \
> + (char *)(nftnl_attrbuf_get_end(attrbuf)) > (char *)(attr); \
> + (attr) = nftnl_attr_next(attr))
> +
> +/* TLV callback-based attribute parsers */
> +#define NFTNL_CB_ERROR -1
> +#define NFTNL_CB_STOP 0
> +#define NFTNL_CB_OK 1
> +
> +typedef int (*nftnl_attr_cb_t)(const struct nftnl_attr *attr, void *data);
> +int nftnl_attr_parse(const struct nftnl_attrbuf *attrbuf, nftnl_attr_cb_t cb,
> + void *data);
> +
> +#endif /* _LIBNFTNL_ATTR_H_ */
> diff --git a/src/Makefile.am b/src/Makefile.am
> index a27e292..621dd69 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -19,6 +19,7 @@ libnftnl_la_SOURCES = utils.c \
> ruleset.c \
> mxml.c \
> jansson.c \
> + attr.c \
> expr.c \
> expr_ops.c \
> expr/bitwise.c \
> diff --git a/src/attr.c b/src/attr.c
> new file mode 100644
> index 0000000..82c63aa
> --- /dev/null
> +++ b/src/attr.c
> @@ -0,0 +1,132 @@
> +#include <libnftnl/attr.h>
> +#include <attr.h>
> +#include <utils.h>
> +
> +#include <stdlib.h>
> +#include <stdint.h>
> +
> +
> +struct nftnl_attrbuf *nftnl_attrbuf_alloc(size_t data_size)
> +{
> + struct nftnl_attrbuf *attrbuf;
> +
> + attrbuf = (struct nftnl_attrbuf *)
> + malloc(sizeof(struct nftnl_attrbuf) + data_size);
> + attrbuf->size = data_size;
> + attrbuf->end = attrbuf->data;
> +
> + return attrbuf;
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_alloc);
> +
> +void nftnl_attrbuf_free(struct nftnl_attrbuf *attrbuf)
> +{
> + attrbuf->size = 0;
> + attrbuf->end = NULL;
> + free((void *)attrbuf);
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_free);
> +
> +size_t nftnl_attrbuf_get_len(const struct nftnl_attrbuf *attrbuf)
> +{
> + return (size_t)(attrbuf->end - attrbuf->data);
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_get_len);
> +
> +size_t nftnl_attrbuf_get_size(const struct nftnl_attrbuf *attrbuf)
> +{
> + return attrbuf->size;
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_get_size);
> +
> +struct nftnl_attr *nftnl_attrbuf_get_start(const struct nftnl_attrbuf *attrbuf)
> +{
> + return (struct nftnl_attr *)attrbuf->data;
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_get_start);
> +
> +struct nftnl_attr *nftnl_attrbuf_get_end(const struct nftnl_attrbuf *attrbuf)
> +{
> + return (struct nftnl_attr *)attrbuf->end;
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_get_end);
> +
> +void *nftnl_attrbuf_get_data(const struct nftnl_attrbuf *attrbuf)
> +{
> + return (void *)attrbuf->data;
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_get_data);
> +
> +void nftnl_attrbuf_copy_data(struct nftnl_attrbuf *attrbuf,
> + const void *data, size_t len)
> +{
> + memcpy(attrbuf->data, data, len <= attrbuf->size ? len : attrbuf->size);
> + attrbuf->end = attrbuf->data + len;
> +}
> +EXPORT_SYMBOL(nftnl_attrbuf_copy_data);
> +
> +uint8_t nftnl_attr_get_type(const struct nftnl_attr *attr)
> +{
> + return attr->type;
> +}
> +EXPORT_SYMBOL(nftnl_attr_get_type);
> +
> +uint8_t nftnl_attr_get_len(const struct nftnl_attr *attr)
> +{
> + return attr->len;
> +}
> +EXPORT_SYMBOL(nftnl_attr_get_len);
> +
> +void *nftnl_attr_get_value(const struct nftnl_attr *attr)
> +{
> + return (void *)attr->value;
> +}
> +EXPORT_SYMBOL(nftnl_attr_get_value);
> +
> +struct nftnl_attr *nftnl_attr_put(struct nftnl_attrbuf *attrbuf,
> + uint8_t type, uint8_t len, const void *value)
> +{
> + struct nftnl_attr *attr = (struct nftnl_attr *)attrbuf->end;
> +
> + attr->len = len;
> + attr->type = type;
> + memcpy(attr->value, value, len);
> +
> + attrbuf->end = (char *)nftnl_attr_next(attr);
> +
> + return attr;
> +}
> +EXPORT_SYMBOL(nftnl_attr_put);
> +
> +struct nftnl_attr *nftnl_attr_put_check(struct nftnl_attrbuf *attrbuf,
> + uint8_t type, size_t len,
> + const void *value)
> +{
> + /* Check if there is enough space */
> + if (attrbuf->size < len + sizeof(struct nftnl_attr))
> + return NULL;
> +
> + return nftnl_attr_put(attrbuf, type, len, value);
> +}
> +EXPORT_SYMBOL(nftnl_attr_put_check);
> +
> +struct nftnl_attr *nftnl_attr_next(const struct nftnl_attr *attr)
> +{
> + return (struct nftnl_attr *)&attr->value[attr->len];
> +}
> +EXPORT_SYMBOL(nftnl_attr_next);
> +
> +int nftnl_attr_parse(const struct nftnl_attrbuf *attrbuf, nftnl_attr_cb_t cb,
> + void *data)
> +{
> + int ret = NFTNL_CB_OK;
> + const struct nftnl_attr *attr;
> +
> + nftnl_attr_for_each(attr, attrbuf) {
> + ret = cb(attr, data);
> + if (ret <= NFTNL_CB_STOP)
> + return ret;
> + }
> + return ret;
> +}
> +EXPORT_SYMBOL(nftnl_attr_parse);
> diff --git a/src/libnftnl.map b/src/libnftnl.map
> index 2e193b7..65bd37e 100644
> --- a/src/libnftnl.map
> +++ b/src/libnftnl.map
> @@ -336,6 +336,22 @@ global:
> nftnl_set_snprintf;
> nftnl_set_fprintf;
>
> + nftnl_attrbuf_alloc;
> + nftnl_attrbuf_free;
> + nftnl_attrbuf_get_len;
> + nftnl_attrbuf_get_size;
> + nftnl_attrbuf_get_data;
> + nftnl_attrbuf_copy_data;
> + nftnl_attrbuf_get_start;
> + nftnl_attrbuf_get_end;
> + nftnl_attr_get_type;
> + nftnl_attr_get_len;
> + nftnl_attr_get_value;
> + nftnl_attr_put;
> + nftnl_attr_put_check;
> + nftnl_attr_next;
> + nftnl_attr_parse;
Are you sure we need to export all these? Please only export those
functions that we really need at this stage for nft.
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
next prev parent reply other threads:[~2016-03-02 18:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-29 16:25 [PATCH 1/3 v2] libnftnl: Implement new buffer of TLV objects Carlos Falgueras García
2016-02-29 16:25 ` [PATCH 2/3 v2] libnftnl: rule: Change the "userdata" attribute to use new TLV buffer Carlos Falgueras García
2016-03-02 18:41 ` Pablo Neira Ayuso
2016-03-08 9:58 ` Carlos Falgueras García
2016-03-08 10:12 ` Pablo Neira Ayuso
2016-02-29 16:25 ` [PATCH 3/3 v2] nftables: rule: Change the field "rule->comment" for an nftnl_attrbuf Carlos Falgueras García
2016-03-02 18:37 ` Pablo Neira Ayuso
2016-03-08 9:58 ` Carlos Falgueras García
2016-03-08 10:13 ` Pablo Neira Ayuso
2016-03-02 18:32 ` Pablo Neira Ayuso [this message]
2016-03-08 9:57 ` [PATCH 1/3 v2] libnftnl: Implement new buffer of TLV objects Carlos Falgueras García
2016-03-08 10:10 ` 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=20160302183207.GA1351@salvia \
--to=pablo@netfilter.org \
--cc=carlosfg@riseup.net \
--cc=kaber@trash.net \
--cc=netfilter-devel@vger.kernel.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).