diff options
author | Carlos Falgueras García <carlosfg@riseup.net> | 2016-06-27 19:05:22 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-07-01 16:23:53 +0200 |
commit | 352a74d4e93e3db7380197720eb1003365a5781d (patch) | |
tree | cc73d385310a63ee83592b8b8d7b15907026dc40 /src | |
parent | 5ad0e626492e835fff65369c93d1e571013129e9 (diff) |
set: Add new attribute into 'set' to store user data
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/set.c | 29 |
1 files changed, 29 insertions, 0 deletions
@@ -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) |