]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
set: Add new attribute into 'set' to store user data
authorCarlos Falgueras García <carlosfg@riseup.net>
Mon, 27 Jun 2016 17:05:22 +0000 (19:05 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 1 Jul 2016 14:23:53 +0000 (16:23 +0200)
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>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/libnftnl/set.h
include/set.h
src/set.c

index 3d50d56c040fa9af013d316dad89c365ba1b9b4a..5266b6f42c095475294cc2566c9519d3d740dc8b 100644 (file)
@@ -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)
index c3b96f2160e32d7ae26b692cc4ba769aa586ade5..85bd389a3bd87f144c83d9262339fcc513040cd8 100644 (file)
@@ -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 {
index 47e0c45da5f231fed499affb7c3d815106bb99ea..9315bf0deca0626dcb95edaa63272355063933fa 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -87,6 +87,9 @@ void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
        case NFTNL_SET_TIMEOUT:
        case NFTNL_SET_GC_INTERVAL:
                break;
+       case NFTNL_SET_USERDATA:
+               xfree(s->user.data);
+               break;
        default:
                return;
        }
@@ -164,6 +167,16 @@ int 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:
+               if (s->flags & (1 << NFTNL_SET_USERDATA))
+                       xfree(s->user.data);
+
+               s->user.data = malloc(data_len);
+               if (!s->user.data)
+                       return -1;
+               memcpy(s->user.data, data, data_len);
+               s->user.len = data_len;
+               break;
        }
        s->flags |= (1 << attr);
        return 0;
@@ -238,6 +251,9 @@ const void *nftnl_set_get_data(const 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;
 }
@@ -352,6 +368,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);
 
@@ -380,6 +398,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();
@@ -490,6 +512,13 @@ 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]) {
+               ret = nftnl_set_set_data(s, NFTNL_SET_USERDATA,
+                       mnl_attr_get_payload(tb[NFTA_SET_USERDATA]),
+                       mnl_attr_get_payload_len(tb[NFTA_SET_USERDATA]));
+               if (ret < 0)
+                       return ret;
+       }
        if (tb[NFTA_SET_DESC]) {
                ret = nftnl_set_desc_parse(s, tb[NFTA_SET_DESC]);
                if (ret < 0)