diff options
author | Carlos Falgueras García <carlosfg@riseup.net> | 2016-01-05 08:03:32 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-01-08 07:25:08 -0500 |
commit | e6d8ecac9e68265aee9be711c5bd29406129666f (patch) | |
tree | a1e8d8a2c5bf0bc7b3c5bb89bbb9ac2e4305ece2 /net/netfilter | |
parent | eb075954e9fde114f57adc39a9ea6d379c13f81e (diff) |
netfilter: nf_tables: Add new attributes into nft_set to store user data.
User data is stored at after 'nft_set_ops' private data into 'data[]'
flexible array. The field 'udata' points to user data and 'udlen' stores
its length.
Add new flag NFTA_SET_USERDATA.
Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/nf_tables_api.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index f5c397158e29..2011977cd79d 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -2323,6 +2323,8 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = { | |||
2323 | [NFTA_SET_ID] = { .type = NLA_U32 }, | 2323 | [NFTA_SET_ID] = { .type = NLA_U32 }, |
2324 | [NFTA_SET_TIMEOUT] = { .type = NLA_U64 }, | 2324 | [NFTA_SET_TIMEOUT] = { .type = NLA_U64 }, |
2325 | [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 }, | 2325 | [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 }, |
2326 | [NFTA_SET_USERDATA] = { .type = NLA_BINARY, | ||
2327 | .len = NFT_USERDATA_MAXLEN }, | ||
2326 | }; | 2328 | }; |
2327 | 2329 | ||
2328 | static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = { | 2330 | static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = { |
@@ -2482,6 +2484,9 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, | |||
2482 | goto nla_put_failure; | 2484 | goto nla_put_failure; |
2483 | } | 2485 | } |
2484 | 2486 | ||
2487 | if (nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata)) | ||
2488 | goto nla_put_failure; | ||
2489 | |||
2485 | desc = nla_nest_start(skb, NFTA_SET_DESC); | 2490 | desc = nla_nest_start(skb, NFTA_SET_DESC); |
2486 | if (desc == NULL) | 2491 | if (desc == NULL) |
2487 | goto nla_put_failure; | 2492 | goto nla_put_failure; |
@@ -2691,6 +2696,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, | |||
2691 | u64 timeout; | 2696 | u64 timeout; |
2692 | u32 ktype, dtype, flags, policy, gc_int; | 2697 | u32 ktype, dtype, flags, policy, gc_int; |
2693 | struct nft_set_desc desc; | 2698 | struct nft_set_desc desc; |
2699 | unsigned char *udata; | ||
2700 | u16 udlen; | ||
2694 | int err; | 2701 | int err; |
2695 | 2702 | ||
2696 | if (nla[NFTA_SET_TABLE] == NULL || | 2703 | if (nla[NFTA_SET_TABLE] == NULL || |
@@ -2803,12 +2810,16 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, | |||
2803 | if (IS_ERR(ops)) | 2810 | if (IS_ERR(ops)) |
2804 | return PTR_ERR(ops); | 2811 | return PTR_ERR(ops); |
2805 | 2812 | ||
2813 | udlen = 0; | ||
2814 | if (nla[NFTA_SET_USERDATA]) | ||
2815 | udlen = nla_len(nla[NFTA_SET_USERDATA]); | ||
2816 | |||
2806 | size = 0; | 2817 | size = 0; |
2807 | if (ops->privsize != NULL) | 2818 | if (ops->privsize != NULL) |
2808 | size = ops->privsize(nla); | 2819 | size = ops->privsize(nla); |
2809 | 2820 | ||
2810 | err = -ENOMEM; | 2821 | err = -ENOMEM; |
2811 | set = kzalloc(sizeof(*set) + size, GFP_KERNEL); | 2822 | set = kzalloc(sizeof(*set) + size + udlen, GFP_KERNEL); |
2812 | if (set == NULL) | 2823 | if (set == NULL) |
2813 | goto err1; | 2824 | goto err1; |
2814 | 2825 | ||
@@ -2817,6 +2828,12 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, | |||
2817 | if (err < 0) | 2828 | if (err < 0) |
2818 | goto err2; | 2829 | goto err2; |
2819 | 2830 | ||
2831 | udata = NULL; | ||
2832 | if (udlen) { | ||
2833 | udata = set->data + size; | ||
2834 | nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen); | ||
2835 | } | ||
2836 | |||
2820 | INIT_LIST_HEAD(&set->bindings); | 2837 | INIT_LIST_HEAD(&set->bindings); |
2821 | write_pnet(&set->pnet, net); | 2838 | write_pnet(&set->pnet, net); |
2822 | set->ops = ops; | 2839 | set->ops = ops; |
@@ -2827,6 +2844,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, | |||
2827 | set->flags = flags; | 2844 | set->flags = flags; |
2828 | set->size = desc.size; | 2845 | set->size = desc.size; |
2829 | set->policy = policy; | 2846 | set->policy = policy; |
2847 | set->udlen = udlen; | ||
2848 | set->udata = udata; | ||
2830 | set->timeout = timeout; | 2849 | set->timeout = timeout; |
2831 | set->gc_int = gc_int; | 2850 | set->gc_int = gc_int; |
2832 | 2851 | ||