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 <carlo...@riseup.net>
---
 include/libnftnl/set.h |  1 +
 include/set.h          |  4 ++++
 src/set.c              | 29 +++++++++++++++++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 3d50d56..5266b6f 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)
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 7b333ed..ebb4329 100644
--- 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)
-- 
2.8.3

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to