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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.