aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/nf_log_arp.c4
-rw-r--r--net/ipv4/netfilter/nf_log_ipv4.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c5
-rw-r--r--net/ipv6/netfilter/nf_log_ipv6.c4
-rw-r--r--net/netfilter/Kconfig1
-rw-r--r--net/netfilter/nf_tables_api.c199
-rw-r--r--net/netfilter/nf_tables_core.c18
-rw-r--r--net/netfilter/nft_hash.c183
-rw-r--r--net/netfilter/nft_log.c2
-rw-r--r--net/netfilter/nft_lookup.c6
-rw-r--r--net/netfilter/nft_meta.c2
-rw-r--r--net/netfilter/nft_rbtree.c123
-rw-r--r--net/netlink/af_netlink.c2
13 files changed, 332 insertions, 221 deletions
diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
index d059182c1466..e7ad950cf9ef 100644
--- a/net/ipv4/netfilter/nf_log_arp.c
+++ b/net/ipv4/netfilter/nf_log_arp.c
@@ -10,8 +10,10 @@
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 15
16#include <linux/kernel.h>
15#include <linux/module.h> 17#include <linux/module.h>
16#include <linux/spinlock.h> 18#include <linux/spinlock.h>
17#include <linux/skbuff.h> 19#include <linux/skbuff.h>
@@ -27,7 +29,7 @@ static struct nf_loginfo default_loginfo = {
27 .type = NF_LOG_TYPE_LOG, 29 .type = NF_LOG_TYPE_LOG,
28 .u = { 30 .u = {
29 .log = { 31 .log = {
30 .level = 5, 32 .level = LOGLEVEL_NOTICE,
31 .logflags = NF_LOG_MASK, 33 .logflags = NF_LOG_MASK,
32 }, 34 },
33 }, 35 },
diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c
index 75101980eeee..076aadda0473 100644
--- a/net/ipv4/netfilter/nf_log_ipv4.c
+++ b/net/ipv4/netfilter/nf_log_ipv4.c
@@ -5,8 +5,10 @@
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 10
11#include <linux/kernel.h>
10#include <linux/module.h> 12#include <linux/module.h>
11#include <linux/spinlock.h> 13#include <linux/spinlock.h>
12#include <linux/skbuff.h> 14#include <linux/skbuff.h>
@@ -26,7 +28,7 @@ static struct nf_loginfo default_loginfo = {
26 .type = NF_LOG_TYPE_LOG, 28 .type = NF_LOG_TYPE_LOG,
27 .u = { 29 .u = {
28 .log = { 30 .log = {
29 .level = 5, 31 .level = LOGLEVEL_NOTICE,
30 .logflags = NF_LOG_MASK, 32 .logflags = NF_LOG_MASK,
31 }, 33 },
32 }, 34 },
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index bb00c6f2a885..83f59dc3cccc 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -9,7 +9,10 @@
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/kernel.h>
13#include <linux/capability.h> 16#include <linux/capability.h>
14#include <linux/in.h> 17#include <linux/in.h>
15#include <linux/skbuff.h> 18#include <linux/skbuff.h>
@@ -234,7 +237,7 @@ static struct nf_loginfo trace_loginfo = {
234 .type = NF_LOG_TYPE_LOG, 237 .type = NF_LOG_TYPE_LOG,
235 .u = { 238 .u = {
236 .log = { 239 .log = {
237 .level = 4, 240 .level = LOGLEVEL_WARNING,
238 .logflags = NF_LOG_MASK, 241 .logflags = NF_LOG_MASK,
239 }, 242 },
240 }, 243 },
diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c
index ddf07e6f59d7..8dd869642f45 100644
--- a/net/ipv6/netfilter/nf_log_ipv6.c
+++ b/net/ipv6/netfilter/nf_log_ipv6.c
@@ -5,8 +5,10 @@
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 10
11#include <linux/kernel.h>
10#include <linux/module.h> 12#include <linux/module.h>
11#include <linux/spinlock.h> 13#include <linux/spinlock.h>
12#include <linux/skbuff.h> 14#include <linux/skbuff.h>
@@ -27,7 +29,7 @@ static struct nf_loginfo default_loginfo = {
27 .type = NF_LOG_TYPE_LOG, 29 .type = NF_LOG_TYPE_LOG,
28 .u = { 30 .u = {
29 .log = { 31 .log = {
30 .level = 5, 32 .level = LOGLEVEL_NOTICE,
31 .logflags = NF_LOG_MASK, 33 .logflags = NF_LOG_MASK,
32 }, 34 },
33 }, 35 },
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 971cd7526f4b..f70e34a68f70 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -522,7 +522,6 @@ config NFT_NAT
522 typical Network Address Translation (NAT) packet transformations. 522 typical Network Address Translation (NAT) packet transformations.
523 523
524config NFT_QUEUE 524config NFT_QUEUE
525 depends on NETFILTER_XTABLES
526 depends on NETFILTER_NETLINK_QUEUE 525 depends on NETFILTER_NETLINK_QUEUE
527 tristate "Netfilter nf_tables queue module" 526 tristate "Netfilter nf_tables queue module"
528 help 527 help
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 363a39a6c286..5604c2df05d1 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -198,36 +198,31 @@ static int nft_delchain(struct nft_ctx *ctx)
198static inline bool 198static inline bool
199nft_rule_is_active(struct net *net, const struct nft_rule *rule) 199nft_rule_is_active(struct net *net, const struct nft_rule *rule)
200{ 200{
201 return (rule->genmask & (1 << net->nft.gencursor)) == 0; 201 return (rule->genmask & nft_genmask_cur(net)) == 0;
202}
203
204static inline int gencursor_next(struct net *net)
205{
206 return net->nft.gencursor+1 == 1 ? 1 : 0;
207} 202}
208 203
209static inline int 204static inline int
210nft_rule_is_active_next(struct net *net, const struct nft_rule *rule) 205nft_rule_is_active_next(struct net *net, const struct nft_rule *rule)
211{ 206{
212 return (rule->genmask & (1 << gencursor_next(net))) == 0; 207 return (rule->genmask & nft_genmask_next(net)) == 0;
213} 208}
214 209
215static inline void 210static inline void
216nft_rule_activate_next(struct net *net, struct nft_rule *rule) 211nft_rule_activate_next(struct net *net, struct nft_rule *rule)
217{ 212{
218 /* Now inactive, will be active in the future */ 213 /* Now inactive, will be active in the future */
219 rule->genmask = (1 << net->nft.gencursor); 214 rule->genmask = nft_genmask_cur(net);
220} 215}
221 216
222static inline void 217static inline void
223nft_rule_deactivate_next(struct net *net, struct nft_rule *rule) 218nft_rule_deactivate_next(struct net *net, struct nft_rule *rule)
224{ 219{
225 rule->genmask = (1 << gencursor_next(net)); 220 rule->genmask = nft_genmask_next(net);
226} 221}
227 222
228static inline void nft_rule_clear(struct net *net, struct nft_rule *rule) 223static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
229{ 224{
230 rule->genmask &= ~(1 << gencursor_next(net)); 225 rule->genmask &= ~nft_genmask_next(net);
231} 226}
232 227
233static int 228static int
@@ -1354,6 +1349,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
1354 rcu_assign_pointer(basechain->stats, stats); 1349 rcu_assign_pointer(basechain->stats, stats);
1355 } 1350 }
1356 1351
1352 write_pnet(&basechain->pnet, net);
1357 basechain->type = type; 1353 basechain->type = type;
1358 chain = &basechain->chain; 1354 chain = &basechain->chain;
1359 1355
@@ -1381,7 +1377,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
1381 1377
1382 INIT_LIST_HEAD(&chain->rules); 1378 INIT_LIST_HEAD(&chain->rules);
1383 chain->handle = nf_tables_alloc_handle(table); 1379 chain->handle = nf_tables_alloc_handle(table);
1384 chain->net = net;
1385 chain->table = table; 1380 chain->table = table;
1386 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN); 1381 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
1387 1382
@@ -2695,6 +2690,7 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2695 goto err2; 2690 goto err2;
2696 2691
2697 INIT_LIST_HEAD(&set->bindings); 2692 INIT_LIST_HEAD(&set->bindings);
2693 write_pnet(&set->pnet, net);
2698 set->ops = ops; 2694 set->ops = ops;
2699 set->ktype = ktype; 2695 set->ktype = ktype;
2700 set->klen = desc.klen; 2696 set->klen = desc.klen;
@@ -2771,10 +2767,11 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
2771 const struct nft_set_iter *iter, 2767 const struct nft_set_iter *iter,
2772 const struct nft_set_elem *elem) 2768 const struct nft_set_elem *elem)
2773{ 2769{
2770 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
2774 enum nft_registers dreg; 2771 enum nft_registers dreg;
2775 2772
2776 dreg = nft_type_to_reg(set->dtype); 2773 dreg = nft_type_to_reg(set->dtype);
2777 return nft_validate_data_load(ctx, dreg, &elem->data, 2774 return nft_validate_data_load(ctx, dreg, nft_set_ext_data(ext),
2778 set->dtype == NFT_DATA_VERDICT ? 2775 set->dtype == NFT_DATA_VERDICT ?
2779 NFT_DATA_VERDICT : NFT_DATA_VALUE); 2776 NFT_DATA_VERDICT : NFT_DATA_VALUE);
2780} 2777}
@@ -2827,6 +2824,22 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
2827 nf_tables_set_destroy(ctx, set); 2824 nf_tables_set_destroy(ctx, set);
2828} 2825}
2829 2826
2827const struct nft_set_ext_type nft_set_ext_types[] = {
2828 [NFT_SET_EXT_KEY] = {
2829 .len = sizeof(struct nft_data),
2830 .align = __alignof__(struct nft_data),
2831 },
2832 [NFT_SET_EXT_DATA] = {
2833 .len = sizeof(struct nft_data),
2834 .align = __alignof__(struct nft_data),
2835 },
2836 [NFT_SET_EXT_FLAGS] = {
2837 .len = sizeof(u8),
2838 .align = __alignof__(u8),
2839 },
2840};
2841EXPORT_SYMBOL_GPL(nft_set_ext_types);
2842
2830/* 2843/*
2831 * Set elements 2844 * Set elements
2832 */ 2845 */
@@ -2873,6 +2886,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
2873 const struct nft_set *set, 2886 const struct nft_set *set,
2874 const struct nft_set_elem *elem) 2887 const struct nft_set_elem *elem)
2875{ 2888{
2889 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
2876 unsigned char *b = skb_tail_pointer(skb); 2890 unsigned char *b = skb_tail_pointer(skb);
2877 struct nlattr *nest; 2891 struct nlattr *nest;
2878 2892
@@ -2880,20 +2894,20 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
2880 if (nest == NULL) 2894 if (nest == NULL)
2881 goto nla_put_failure; 2895 goto nla_put_failure;
2882 2896
2883 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, &elem->key, NFT_DATA_VALUE, 2897 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, nft_set_ext_key(ext),
2884 set->klen) < 0) 2898 NFT_DATA_VALUE, set->klen) < 0)
2885 goto nla_put_failure; 2899 goto nla_put_failure;
2886 2900
2887 if (set->flags & NFT_SET_MAP && 2901 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
2888 !(elem->flags & NFT_SET_ELEM_INTERVAL_END) && 2902 nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
2889 nft_data_dump(skb, NFTA_SET_ELEM_DATA, &elem->data,
2890 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE, 2903 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
2891 set->dlen) < 0) 2904 set->dlen) < 0)
2892 goto nla_put_failure; 2905 goto nla_put_failure;
2893 2906
2894 if (elem->flags != 0) 2907 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
2895 if (nla_put_be32(skb, NFTA_SET_ELEM_FLAGS, htonl(elem->flags))) 2908 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
2896 goto nla_put_failure; 2909 htonl(*nft_set_ext_flags(ext))))
2910 goto nla_put_failure;
2897 2911
2898 nla_nest_end(skb, nest); 2912 nla_nest_end(skb, nest);
2899 return 0; 2913 return 0;
@@ -3114,15 +3128,54 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3114 return trans; 3128 return trans;
3115} 3129}
3116 3130
3131static void *nft_set_elem_init(const struct nft_set *set,
3132 const struct nft_set_ext_tmpl *tmpl,
3133 const struct nft_data *key,
3134 const struct nft_data *data,
3135 gfp_t gfp)
3136{
3137 struct nft_set_ext *ext;
3138 void *elem;
3139
3140 elem = kzalloc(set->ops->elemsize + tmpl->len, gfp);
3141 if (elem == NULL)
3142 return NULL;
3143
3144 ext = nft_set_elem_ext(set, elem);
3145 nft_set_ext_init(ext, tmpl);
3146
3147 memcpy(nft_set_ext_key(ext), key, set->klen);
3148 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3149 memcpy(nft_set_ext_data(ext), data, set->dlen);
3150
3151 return elem;
3152}
3153
3154void nft_set_elem_destroy(const struct nft_set *set, void *elem)
3155{
3156 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3157
3158 nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
3159 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3160 nft_data_uninit(nft_set_ext_data(ext), set->dtype);
3161
3162 kfree(elem);
3163}
3164EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
3165
3117static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, 3166static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3118 const struct nlattr *attr) 3167 const struct nlattr *attr)
3119{ 3168{
3120 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1]; 3169 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3121 struct nft_data_desc d1, d2; 3170 struct nft_data_desc d1, d2;
3171 struct nft_set_ext_tmpl tmpl;
3172 struct nft_set_ext *ext;
3122 struct nft_set_elem elem; 3173 struct nft_set_elem elem;
3123 struct nft_set_binding *binding; 3174 struct nft_set_binding *binding;
3175 struct nft_data data;
3124 enum nft_registers dreg; 3176 enum nft_registers dreg;
3125 struct nft_trans *trans; 3177 struct nft_trans *trans;
3178 u32 flags;
3126 int err; 3179 int err;
3127 3180
3128 if (set->size && set->nelems == set->size) 3181 if (set->size && set->nelems == set->size)
@@ -3136,22 +3189,26 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3136 if (nla[NFTA_SET_ELEM_KEY] == NULL) 3189 if (nla[NFTA_SET_ELEM_KEY] == NULL)
3137 return -EINVAL; 3190 return -EINVAL;
3138 3191
3139 elem.flags = 0; 3192 nft_set_ext_prepare(&tmpl);
3193
3194 flags = 0;
3140 if (nla[NFTA_SET_ELEM_FLAGS] != NULL) { 3195 if (nla[NFTA_SET_ELEM_FLAGS] != NULL) {
3141 elem.flags = ntohl(nla_get_be32(nla[NFTA_SET_ELEM_FLAGS])); 3196 flags = ntohl(nla_get_be32(nla[NFTA_SET_ELEM_FLAGS]));
3142 if (elem.flags & ~NFT_SET_ELEM_INTERVAL_END) 3197 if (flags & ~NFT_SET_ELEM_INTERVAL_END)
3143 return -EINVAL; 3198 return -EINVAL;
3144 if (!(set->flags & NFT_SET_INTERVAL) && 3199 if (!(set->flags & NFT_SET_INTERVAL) &&
3145 elem.flags & NFT_SET_ELEM_INTERVAL_END) 3200 flags & NFT_SET_ELEM_INTERVAL_END)
3146 return -EINVAL; 3201 return -EINVAL;
3202 if (flags != 0)
3203 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
3147 } 3204 }
3148 3205
3149 if (set->flags & NFT_SET_MAP) { 3206 if (set->flags & NFT_SET_MAP) {
3150 if (nla[NFTA_SET_ELEM_DATA] == NULL && 3207 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
3151 !(elem.flags & NFT_SET_ELEM_INTERVAL_END)) 3208 !(flags & NFT_SET_ELEM_INTERVAL_END))
3152 return -EINVAL; 3209 return -EINVAL;
3153 if (nla[NFTA_SET_ELEM_DATA] != NULL && 3210 if (nla[NFTA_SET_ELEM_DATA] != NULL &&
3154 elem.flags & NFT_SET_ELEM_INTERVAL_END) 3211 flags & NFT_SET_ELEM_INTERVAL_END)
3155 return -EINVAL; 3212 return -EINVAL;
3156 } else { 3213 } else {
3157 if (nla[NFTA_SET_ELEM_DATA] != NULL) 3214 if (nla[NFTA_SET_ELEM_DATA] != NULL)
@@ -3165,12 +3222,10 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3165 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen) 3222 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
3166 goto err2; 3223 goto err2;
3167 3224
3168 err = -EEXIST; 3225 nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY);
3169 if (set->ops->get(set, &elem) == 0)
3170 goto err2;
3171 3226
3172 if (nla[NFTA_SET_ELEM_DATA] != NULL) { 3227 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
3173 err = nft_data_init(ctx, &elem.data, &d2, nla[NFTA_SET_ELEM_DATA]); 3228 err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]);
3174 if (err < 0) 3229 if (err < 0)
3175 goto err2; 3230 goto err2;
3176 3231
@@ -3187,29 +3242,43 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3187 }; 3242 };
3188 3243
3189 err = nft_validate_data_load(&bind_ctx, dreg, 3244 err = nft_validate_data_load(&bind_ctx, dreg,
3190 &elem.data, d2.type); 3245 &data, d2.type);
3191 if (err < 0) 3246 if (err < 0)
3192 goto err3; 3247 goto err3;
3193 } 3248 }
3249
3250 nft_set_ext_add(&tmpl, NFT_SET_EXT_DATA);
3194 } 3251 }
3195 3252
3253 err = -ENOMEM;
3254 elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data, GFP_KERNEL);
3255 if (elem.priv == NULL)
3256 goto err3;
3257
3258 ext = nft_set_elem_ext(set, elem.priv);
3259 if (flags)
3260 *nft_set_ext_flags(ext) = flags;
3261
3196 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set); 3262 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
3197 if (trans == NULL) 3263 if (trans == NULL)
3198 goto err3; 3264 goto err4;
3199 3265
3266 ext->genmask = nft_genmask_cur(ctx->net);
3200 err = set->ops->insert(set, &elem); 3267 err = set->ops->insert(set, &elem);
3201 if (err < 0) 3268 if (err < 0)
3202 goto err4; 3269 goto err5;
3203 3270
3204 nft_trans_elem(trans) = elem; 3271 nft_trans_elem(trans) = elem;
3205 list_add_tail(&trans->list, &ctx->net->nft.commit_list); 3272 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
3206 return 0; 3273 return 0;
3207 3274
3208err4: 3275err5:
3209 kfree(trans); 3276 kfree(trans);
3277err4:
3278 kfree(elem.priv);
3210err3: 3279err3:
3211 if (nla[NFTA_SET_ELEM_DATA] != NULL) 3280 if (nla[NFTA_SET_ELEM_DATA] != NULL)
3212 nft_data_uninit(&elem.data, d2.type); 3281 nft_data_uninit(&data, d2.type);
3213err2: 3282err2:
3214 nft_data_uninit(&elem.key, d1.type); 3283 nft_data_uninit(&elem.key, d1.type);
3215err1: 3284err1:
@@ -3282,19 +3351,24 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
3282 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) 3351 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
3283 goto err2; 3352 goto err2;
3284 3353
3285 err = set->ops->get(set, &elem);
3286 if (err < 0)
3287 goto err2;
3288
3289 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set); 3354 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
3290 if (trans == NULL) { 3355 if (trans == NULL) {
3291 err = -ENOMEM; 3356 err = -ENOMEM;
3292 goto err2; 3357 goto err2;
3293 } 3358 }
3294 3359
3360 elem.priv = set->ops->deactivate(set, &elem);
3361 if (elem.priv == NULL) {
3362 err = -ENOENT;
3363 goto err3;
3364 }
3365
3295 nft_trans_elem(trans) = elem; 3366 nft_trans_elem(trans) = elem;
3296 list_add_tail(&trans->list, &ctx->net->nft.commit_list); 3367 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
3297 return 0; 3368 return 0;
3369
3370err3:
3371 kfree(trans);
3298err2: 3372err2:
3299 nft_data_uninit(&elem.key, desc.type); 3373 nft_data_uninit(&elem.key, desc.type);
3300err1: 3374err1:
@@ -3532,6 +3606,10 @@ static void nf_tables_commit_release(struct nft_trans *trans)
3532 case NFT_MSG_DELSET: 3606 case NFT_MSG_DELSET:
3533 nft_set_destroy(nft_trans_set(trans)); 3607 nft_set_destroy(nft_trans_set(trans));
3534 break; 3608 break;
3609 case NFT_MSG_DELSETELEM:
3610 nft_set_elem_destroy(nft_trans_elem_set(trans),
3611 nft_trans_elem(trans).priv);
3612 break;
3535 } 3613 }
3536 kfree(trans); 3614 kfree(trans);
3537} 3615}
@@ -3546,7 +3624,7 @@ static int nf_tables_commit(struct sk_buff *skb)
3546 while (++net->nft.base_seq == 0); 3624 while (++net->nft.base_seq == 0);
3547 3625
3548 /* A new generation has just started */ 3626 /* A new generation has just started */
3549 net->nft.gencursor = gencursor_next(net); 3627 net->nft.gencursor = nft_gencursor_next(net);
3550 3628
3551 /* Make sure all packets have left the previous generation before 3629 /* Make sure all packets have left the previous generation before
3552 * purging old rules. 3630 * purging old rules.
@@ -3617,24 +3695,21 @@ static int nf_tables_commit(struct sk_buff *skb)
3617 NFT_MSG_DELSET, GFP_KERNEL); 3695 NFT_MSG_DELSET, GFP_KERNEL);
3618 break; 3696 break;
3619 case NFT_MSG_NEWSETELEM: 3697 case NFT_MSG_NEWSETELEM:
3620 nf_tables_setelem_notify(&trans->ctx, 3698 te = (struct nft_trans_elem *)trans->data;
3621 nft_trans_elem_set(trans), 3699
3622 &nft_trans_elem(trans), 3700 te->set->ops->activate(te->set, &te->elem);
3701 nf_tables_setelem_notify(&trans->ctx, te->set,
3702 &te->elem,
3623 NFT_MSG_NEWSETELEM, 0); 3703 NFT_MSG_NEWSETELEM, 0);
3624 nft_trans_destroy(trans); 3704 nft_trans_destroy(trans);
3625 break; 3705 break;
3626 case NFT_MSG_DELSETELEM: 3706 case NFT_MSG_DELSETELEM:
3627 te = (struct nft_trans_elem *)trans->data; 3707 te = (struct nft_trans_elem *)trans->data;
3708
3628 nf_tables_setelem_notify(&trans->ctx, te->set, 3709 nf_tables_setelem_notify(&trans->ctx, te->set,
3629 &te->elem, 3710 &te->elem,
3630 NFT_MSG_DELSETELEM, 0); 3711 NFT_MSG_DELSETELEM, 0);
3631 te->set->ops->get(te->set, &te->elem);
3632 nft_data_uninit(&te->elem.key, NFT_DATA_VALUE);
3633 if (te->set->flags & NFT_SET_MAP &&
3634 !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END))
3635 nft_data_uninit(&te->elem.data, te->set->dtype);
3636 te->set->ops->remove(te->set, &te->elem); 3712 te->set->ops->remove(te->set, &te->elem);
3637 nft_trans_destroy(trans);
3638 break; 3713 break;
3639 } 3714 }
3640 } 3715 }
@@ -3666,6 +3741,10 @@ static void nf_tables_abort_release(struct nft_trans *trans)
3666 case NFT_MSG_NEWSET: 3741 case NFT_MSG_NEWSET:
3667 nft_set_destroy(nft_trans_set(trans)); 3742 nft_set_destroy(nft_trans_set(trans));
3668 break; 3743 break;
3744 case NFT_MSG_NEWSETELEM:
3745 nft_set_elem_destroy(nft_trans_elem_set(trans),
3746 nft_trans_elem(trans).priv);
3747 break;
3669 } 3748 }
3670 kfree(trans); 3749 kfree(trans);
3671} 3750}
@@ -3736,16 +3815,15 @@ static int nf_tables_abort(struct sk_buff *skb)
3736 case NFT_MSG_NEWSETELEM: 3815 case NFT_MSG_NEWSETELEM:
3737 nft_trans_elem_set(trans)->nelems--; 3816 nft_trans_elem_set(trans)->nelems--;
3738 te = (struct nft_trans_elem *)trans->data; 3817 te = (struct nft_trans_elem *)trans->data;
3739 te->set->ops->get(te->set, &te->elem); 3818
3740 nft_data_uninit(&te->elem.key, NFT_DATA_VALUE);
3741 if (te->set->flags & NFT_SET_MAP &&
3742 !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END))
3743 nft_data_uninit(&te->elem.data, te->set->dtype);
3744 te->set->ops->remove(te->set, &te->elem); 3819 te->set->ops->remove(te->set, &te->elem);
3745 nft_trans_destroy(trans);
3746 break; 3820 break;
3747 case NFT_MSG_DELSETELEM: 3821 case NFT_MSG_DELSETELEM:
3822 te = (struct nft_trans_elem *)trans->data;
3823
3748 nft_trans_elem_set(trans)->nelems++; 3824 nft_trans_elem_set(trans)->nelems++;
3825 te->set->ops->activate(te->set, &te->elem);
3826
3749 nft_trans_destroy(trans); 3827 nft_trans_destroy(trans);
3750 break; 3828 break;
3751 } 3829 }
@@ -3820,13 +3898,18 @@ static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
3820 const struct nft_set_iter *iter, 3898 const struct nft_set_iter *iter,
3821 const struct nft_set_elem *elem) 3899 const struct nft_set_elem *elem)
3822{ 3900{
3823 if (elem->flags & NFT_SET_ELEM_INTERVAL_END) 3901 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
3902 const struct nft_data *data;
3903
3904 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
3905 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
3824 return 0; 3906 return 0;
3825 3907
3826 switch (elem->data.verdict) { 3908 data = nft_set_ext_data(ext);
3909 switch (data->verdict) {
3827 case NFT_JUMP: 3910 case NFT_JUMP:
3828 case NFT_GOTO: 3911 case NFT_GOTO:
3829 return nf_tables_check_loops(ctx, elem->data.chain); 3912 return nf_tables_check_loops(ctx, data->chain);
3830 default: 3913 default:
3831 return 0; 3914 return 0;
3832 } 3915 }
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 77165bf023f3..ef4dfcbaf149 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -8,6 +8,7 @@
8 * Development of this code funded by Astaro AG (http://www.astaro.com/) 8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 */ 9 */
10 10
11#include <linux/kernel.h>
11#include <linux/module.h> 12#include <linux/module.h>
12#include <linux/init.h> 13#include <linux/init.h>
13#include <linux/list.h> 14#include <linux/list.h>
@@ -37,7 +38,7 @@ static struct nf_loginfo trace_loginfo = {
37 .type = NF_LOG_TYPE_LOG, 38 .type = NF_LOG_TYPE_LOG,
38 .u = { 39 .u = {
39 .log = { 40 .log = {
40 .level = 4, 41 .level = LOGLEVEL_WARNING,
41 .logflags = NF_LOG_MASK, 42 .logflags = NF_LOG_MASK,
42 }, 43 },
43 }, 44 },
@@ -49,10 +50,10 @@ static void __nft_trace_packet(const struct nft_pktinfo *pkt,
49{ 50{
50 struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); 51 struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
51 52
52 nf_log_packet(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in, 53 nf_log_trace(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in,
53 pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ", 54 pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ",
54 chain->table->name, chain->name, comments[type], 55 chain->table->name, chain->name, comments[type],
55 rulenum); 56 rulenum);
56} 57}
57 58
58static inline void nft_trace_packet(const struct nft_pktinfo *pkt, 59static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
@@ -112,6 +113,7 @@ unsigned int
112nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops) 113nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
113{ 114{
114 const struct nft_chain *chain = ops->priv, *basechain = chain; 115 const struct nft_chain *chain = ops->priv, *basechain = chain;
116 const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet);
115 const struct nft_rule *rule; 117 const struct nft_rule *rule;
116 const struct nft_expr *expr, *last; 118 const struct nft_expr *expr, *last;
117 struct nft_data data[NFT_REG_MAX + 1]; 119 struct nft_data data[NFT_REG_MAX + 1];
@@ -119,11 +121,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
119 struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; 121 struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
120 struct nft_stats *stats; 122 struct nft_stats *stats;
121 int rulenum; 123 int rulenum;
122 /* 124 unsigned int gencursor = nft_genmask_cur(net);
123 * Cache cursor to avoid problems in case that the cursor is updated
124 * while traversing the ruleset.
125 */
126 unsigned int gencursor = ACCESS_ONCE(chain->net->nft.gencursor);
127 125
128do_chain: 126do_chain:
129 rulenum = 0; 127 rulenum = 0;
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index f9ce2195fd63..c7e1a9d7d46f 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -23,104 +23,130 @@
23/* We target a hash table size of 4, element hint is 75% of final size */ 23/* We target a hash table size of 4, element hint is 75% of final size */
24#define NFT_HASH_ELEMENT_HINT 3 24#define NFT_HASH_ELEMENT_HINT 3
25 25
26struct nft_hash {
27 struct rhashtable ht;
28};
29
26struct nft_hash_elem { 30struct nft_hash_elem {
27 struct rhash_head node; 31 struct rhash_head node;
28 struct nft_data key; 32 struct nft_set_ext ext;
29 struct nft_data data[]; 33};
34
35struct nft_hash_cmp_arg {
36 const struct nft_set *set;
37 const struct nft_data *key;
38 u8 genmask;
30}; 39};
31 40
32static const struct rhashtable_params nft_hash_params; 41static const struct rhashtable_params nft_hash_params;
33 42
34static bool nft_hash_lookup(const struct nft_set *set, 43static inline u32 nft_hash_key(const void *data, u32 len, u32 seed)
35 const struct nft_data *key,
36 struct nft_data *data)
37{ 44{
38 struct rhashtable *priv = nft_set_priv(set); 45 const struct nft_hash_cmp_arg *arg = data;
39 const struct nft_hash_elem *he;
40
41 he = rhashtable_lookup_fast(priv, key, nft_hash_params);
42 if (he && set->flags & NFT_SET_MAP)
43 nft_data_copy(data, he->data);
44 46
45 return !!he; 47 return jhash(arg->key, len, seed);
46} 48}
47 49
48static int nft_hash_insert(const struct nft_set *set, 50static inline u32 nft_hash_obj(const void *data, u32 len, u32 seed)
49 const struct nft_set_elem *elem)
50{ 51{
51 struct rhashtable *priv = nft_set_priv(set); 52 const struct nft_hash_elem *he = data;
52 struct nft_hash_elem *he;
53 unsigned int size;
54 int err;
55 53
56 if (elem->flags != 0) 54 return jhash(nft_set_ext_key(&he->ext), len, seed);
57 return -EINVAL; 55}
58 56
59 size = sizeof(*he); 57static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
60 if (set->flags & NFT_SET_MAP) 58 const void *ptr)
61 size += sizeof(he->data[0]); 59{
60 const struct nft_hash_cmp_arg *x = arg->key;
61 const struct nft_hash_elem *he = ptr;
62 62
63 he = kzalloc(size, GFP_KERNEL); 63 if (nft_data_cmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
64 if (he == NULL) 64 return 1;
65 return -ENOMEM; 65 if (!nft_set_elem_active(&he->ext, x->genmask))
66 return 1;
67 return 0;
68}
66 69
67 nft_data_copy(&he->key, &elem->key); 70static bool nft_hash_lookup(const struct nft_set *set,
68 if (set->flags & NFT_SET_MAP) 71 const struct nft_data *key,
69 nft_data_copy(he->data, &elem->data); 72 const struct nft_set_ext **ext)
73{
74 struct nft_hash *priv = nft_set_priv(set);
75 const struct nft_hash_elem *he;
76 struct nft_hash_cmp_arg arg = {
77 .genmask = nft_genmask_cur(read_pnet(&set->pnet)),
78 .set = set,
79 .key = key,
80 };
70 81
71 err = rhashtable_insert_fast(priv, &he->node, nft_hash_params); 82 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
72 if (err) 83 if (he != NULL)
73 kfree(he); 84 *ext = &he->ext;
74 85
75 return err; 86 return !!he;
76} 87}
77 88
78static void nft_hash_elem_destroy(const struct nft_set *set, 89static int nft_hash_insert(const struct nft_set *set,
79 struct nft_hash_elem *he) 90 const struct nft_set_elem *elem)
80{ 91{
81 nft_data_uninit(&he->key, NFT_DATA_VALUE); 92 struct nft_hash *priv = nft_set_priv(set);
82 if (set->flags & NFT_SET_MAP) 93 struct nft_hash_elem *he = elem->priv;
83 nft_data_uninit(he->data, set->dtype); 94 struct nft_hash_cmp_arg arg = {
84 kfree(he); 95 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
96 .set = set,
97 .key = &elem->key,
98 };
99
100 return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
101 nft_hash_params);
85} 102}
86 103
87static void nft_hash_remove(const struct nft_set *set, 104static void nft_hash_activate(const struct nft_set *set,
88 const struct nft_set_elem *elem) 105 const struct nft_set_elem *elem)
89{ 106{
90 struct rhashtable *priv = nft_set_priv(set); 107 struct nft_hash_elem *he = elem->priv;
91 108
92 rhashtable_remove_fast(priv, elem->cookie, nft_hash_params); 109 nft_set_elem_change_active(set, &he->ext);
93 synchronize_rcu();
94 kfree(elem->cookie);
95} 110}
96 111
97static int nft_hash_get(const struct nft_set *set, struct nft_set_elem *elem) 112static void *nft_hash_deactivate(const struct nft_set *set,
113 const struct nft_set_elem *elem)
98{ 114{
99 struct rhashtable *priv = nft_set_priv(set); 115 struct nft_hash *priv = nft_set_priv(set);
100 struct nft_hash_elem *he; 116 struct nft_hash_elem *he;
117 struct nft_hash_cmp_arg arg = {
118 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
119 .set = set,
120 .key = &elem->key,
121 };
101 122
102 he = rhashtable_lookup_fast(priv, &elem->key, nft_hash_params); 123 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
103 if (!he) 124 if (he != NULL)
104 return -ENOENT; 125 nft_set_elem_change_active(set, &he->ext);
105 126
106 elem->cookie = he; 127 return he;
107 elem->flags = 0; 128}
108 if (set->flags & NFT_SET_MAP)
109 nft_data_copy(&elem->data, he->data);
110 129
111 return 0; 130static void nft_hash_remove(const struct nft_set *set,
131 const struct nft_set_elem *elem)
132{
133 struct nft_hash *priv = nft_set_priv(set);
134 struct nft_hash_elem *he = elem->priv;
135
136 rhashtable_remove_fast(&priv->ht, &he->node, nft_hash_params);
112} 137}
113 138
114static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set, 139static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
115 struct nft_set_iter *iter) 140 struct nft_set_iter *iter)
116{ 141{
117 struct rhashtable *priv = nft_set_priv(set); 142 struct nft_hash *priv = nft_set_priv(set);
118 const struct nft_hash_elem *he; 143 struct nft_hash_elem *he;
119 struct rhashtable_iter hti; 144 struct rhashtable_iter hti;
120 struct nft_set_elem elem; 145 struct nft_set_elem elem;
146 u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
121 int err; 147 int err;
122 148
123 err = rhashtable_walk_init(priv, &hti); 149 err = rhashtable_walk_init(&priv->ht, &hti);
124 iter->err = err; 150 iter->err = err;
125 if (err) 151 if (err)
126 return; 152 return;
@@ -144,11 +170,10 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
144 170
145 if (iter->count < iter->skip) 171 if (iter->count < iter->skip)
146 goto cont; 172 goto cont;
173 if (!nft_set_elem_active(&he->ext, genmask))
174 goto cont;
147 175
148 memcpy(&elem.key, &he->key, sizeof(elem.key)); 176 elem.priv = he;
149 if (set->flags & NFT_SET_MAP)
150 memcpy(&elem.data, he->data, sizeof(elem.data));
151 elem.flags = 0;
152 177
153 iter->err = iter->fn(ctx, set, iter, &elem); 178 iter->err = iter->fn(ctx, set, iter, &elem);
154 if (iter->err < 0) 179 if (iter->err < 0)
@@ -165,37 +190,40 @@ out:
165 190
166static unsigned int nft_hash_privsize(const struct nlattr * const nla[]) 191static unsigned int nft_hash_privsize(const struct nlattr * const nla[])
167{ 192{
168 return sizeof(struct rhashtable); 193 return sizeof(struct nft_hash);
169} 194}
170 195
171static const struct rhashtable_params nft_hash_params = { 196static const struct rhashtable_params nft_hash_params = {
172 .head_offset = offsetof(struct nft_hash_elem, node), 197 .head_offset = offsetof(struct nft_hash_elem, node),
173 .key_offset = offsetof(struct nft_hash_elem, key), 198 .hashfn = nft_hash_key,
174 .hashfn = jhash, 199 .obj_hashfn = nft_hash_obj,
175 .automatic_shrinking = true, 200 .obj_cmpfn = nft_hash_cmp,
201 .automatic_shrinking = true,
176}; 202};
177 203
178static int nft_hash_init(const struct nft_set *set, 204static int nft_hash_init(const struct nft_set *set,
179 const struct nft_set_desc *desc, 205 const struct nft_set_desc *desc,
180 const struct nlattr * const tb[]) 206 const struct nlattr * const tb[])
181{ 207{
182 struct rhashtable *priv = nft_set_priv(set); 208 struct nft_hash *priv = nft_set_priv(set);
183 struct rhashtable_params params = nft_hash_params; 209 struct rhashtable_params params = nft_hash_params;
184 210
185 params.nelem_hint = desc->size ?: NFT_HASH_ELEMENT_HINT; 211 params.nelem_hint = desc->size ?: NFT_HASH_ELEMENT_HINT;
186 params.key_len = set->klen; 212 params.key_len = set->klen;
187 213
188 return rhashtable_init(priv, &params); 214 return rhashtable_init(&priv->ht, &params);
189} 215}
190 216
191static void nft_free_element(void *ptr, void *arg) 217static void nft_hash_elem_destroy(void *ptr, void *arg)
192{ 218{
193 nft_hash_elem_destroy((const struct nft_set *)arg, ptr); 219 nft_set_elem_destroy((const struct nft_set *)arg, ptr);
194} 220}
195 221
196static void nft_hash_destroy(const struct nft_set *set) 222static void nft_hash_destroy(const struct nft_set *set)
197{ 223{
198 rhashtable_free_and_destroy(nft_set_priv(set), nft_free_element, 224 struct nft_hash *priv = nft_set_priv(set);
225
226 rhashtable_free_and_destroy(&priv->ht, nft_hash_elem_destroy,
199 (void *)set); 227 (void *)set);
200} 228}
201 229
@@ -205,11 +233,8 @@ static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
205 unsigned int esize; 233 unsigned int esize;
206 234
207 esize = sizeof(struct nft_hash_elem); 235 esize = sizeof(struct nft_hash_elem);
208 if (features & NFT_SET_MAP)
209 esize += FIELD_SIZEOF(struct nft_hash_elem, data[0]);
210
211 if (desc->size) { 236 if (desc->size) {
212 est->size = sizeof(struct rhashtable) + 237 est->size = sizeof(struct nft_hash) +
213 roundup_pow_of_two(desc->size * 4 / 3) * 238 roundup_pow_of_two(desc->size * 4 / 3) *
214 sizeof(struct nft_hash_elem *) + 239 sizeof(struct nft_hash_elem *) +
215 desc->size * esize; 240 desc->size * esize;
@@ -229,11 +254,13 @@ static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
229 254
230static struct nft_set_ops nft_hash_ops __read_mostly = { 255static struct nft_set_ops nft_hash_ops __read_mostly = {
231 .privsize = nft_hash_privsize, 256 .privsize = nft_hash_privsize,
257 .elemsize = offsetof(struct nft_hash_elem, ext),
232 .estimate = nft_hash_estimate, 258 .estimate = nft_hash_estimate,
233 .init = nft_hash_init, 259 .init = nft_hash_init,
234 .destroy = nft_hash_destroy, 260 .destroy = nft_hash_destroy,
235 .get = nft_hash_get,
236 .insert = nft_hash_insert, 261 .insert = nft_hash_insert,
262 .activate = nft_hash_activate,
263 .deactivate = nft_hash_deactivate,
237 .remove = nft_hash_remove, 264 .remove = nft_hash_remove,
238 .lookup = nft_hash_lookup, 265 .lookup = nft_hash_lookup,
239 .walk = nft_hash_walk, 266 .walk = nft_hash_walk,
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index bde05f28cf14..e18af9db2f04 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -78,7 +78,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
78 li->u.log.level = 78 li->u.log.level =
79 ntohl(nla_get_be32(tb[NFTA_LOG_LEVEL])); 79 ntohl(nla_get_be32(tb[NFTA_LOG_LEVEL]));
80 } else { 80 } else {
81 li->u.log.level = 4; 81 li->u.log.level = LOGLEVEL_WARNING;
82 } 82 }
83 if (tb[NFTA_LOG_FLAGS] != NULL) { 83 if (tb[NFTA_LOG_FLAGS] != NULL) {
84 li->u.log.logflags = 84 li->u.log.logflags =
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 9615b8b9fb37..a5f30b8760ea 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -31,9 +31,13 @@ static void nft_lookup_eval(const struct nft_expr *expr,
31{ 31{
32 const struct nft_lookup *priv = nft_expr_priv(expr); 32 const struct nft_lookup *priv = nft_expr_priv(expr);
33 const struct nft_set *set = priv->set; 33 const struct nft_set *set = priv->set;
34 const struct nft_set_ext *ext;
34 35
35 if (set->ops->lookup(set, &data[priv->sreg], &data[priv->dreg])) 36 if (set->ops->lookup(set, &data[priv->sreg], &ext)) {
37 if (set->flags & NFT_SET_MAP)
38 nft_data_copy(&data[priv->dreg], nft_set_ext_data(ext));
36 return; 39 return;
40 }
37 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 41 data[NFT_REG_VERDICT].verdict = NFT_BREAK;
38} 42}
39 43
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index abe68119a76c..5197874372ec 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -153,7 +153,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
153 } 153 }
154 break; 154 break;
155 case NFT_META_CPU: 155 case NFT_META_CPU:
156 dest->data[0] = smp_processor_id(); 156 dest->data[0] = raw_smp_processor_id();
157 break; 157 break;
158 case NFT_META_IIFGROUP: 158 case NFT_META_IIFGROUP:
159 if (in == NULL) 159 if (in == NULL)
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c
index 2c75361077f7..42d0ca45fb9e 100644
--- a/net/netfilter/nft_rbtree.c
+++ b/net/netfilter/nft_rbtree.c
@@ -26,18 +26,18 @@ struct nft_rbtree {
26 26
27struct nft_rbtree_elem { 27struct nft_rbtree_elem {
28 struct rb_node node; 28 struct rb_node node;
29 u16 flags; 29 struct nft_set_ext ext;
30 struct nft_data key;
31 struct nft_data data[];
32}; 30};
33 31
32
34static bool nft_rbtree_lookup(const struct nft_set *set, 33static bool nft_rbtree_lookup(const struct nft_set *set,
35 const struct nft_data *key, 34 const struct nft_data *key,
36 struct nft_data *data) 35 const struct nft_set_ext **ext)
37{ 36{
38 const struct nft_rbtree *priv = nft_set_priv(set); 37 const struct nft_rbtree *priv = nft_set_priv(set);
39 const struct nft_rbtree_elem *rbe, *interval = NULL; 38 const struct nft_rbtree_elem *rbe, *interval = NULL;
40 const struct rb_node *parent; 39 const struct rb_node *parent;
40 u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
41 int d; 41 int d;
42 42
43 spin_lock_bh(&nft_rbtree_lock); 43 spin_lock_bh(&nft_rbtree_lock);
@@ -45,7 +45,7 @@ static bool nft_rbtree_lookup(const struct nft_set *set,
45 while (parent != NULL) { 45 while (parent != NULL) {
46 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 46 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
47 47
48 d = nft_data_cmp(&rbe->key, key, set->klen); 48 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), key, set->klen);
49 if (d < 0) { 49 if (d < 0) {
50 parent = parent->rb_left; 50 parent = parent->rb_left;
51 interval = rbe; 51 interval = rbe;
@@ -53,12 +53,17 @@ static bool nft_rbtree_lookup(const struct nft_set *set,
53 parent = parent->rb_right; 53 parent = parent->rb_right;
54 else { 54 else {
55found: 55found:
56 if (rbe->flags & NFT_SET_ELEM_INTERVAL_END) 56 if (!nft_set_elem_active(&rbe->ext, genmask)) {
57 parent = parent->rb_left;
58 continue;
59 }
60 if (nft_set_ext_exists(&rbe->ext, NFT_SET_EXT_FLAGS) &&
61 *nft_set_ext_flags(&rbe->ext) &
62 NFT_SET_ELEM_INTERVAL_END)
57 goto out; 63 goto out;
58 if (set->flags & NFT_SET_MAP)
59 nft_data_copy(data, rbe->data);
60
61 spin_unlock_bh(&nft_rbtree_lock); 64 spin_unlock_bh(&nft_rbtree_lock);
65
66 *ext = &rbe->ext;
62 return true; 67 return true;
63 } 68 }
64 } 69 }
@@ -72,23 +77,13 @@ out:
72 return false; 77 return false;
73} 78}
74 79
75static void nft_rbtree_elem_destroy(const struct nft_set *set,
76 struct nft_rbtree_elem *rbe)
77{
78 nft_data_uninit(&rbe->key, NFT_DATA_VALUE);
79 if (set->flags & NFT_SET_MAP &&
80 !(rbe->flags & NFT_SET_ELEM_INTERVAL_END))
81 nft_data_uninit(rbe->data, set->dtype);
82
83 kfree(rbe);
84}
85
86static int __nft_rbtree_insert(const struct nft_set *set, 80static int __nft_rbtree_insert(const struct nft_set *set,
87 struct nft_rbtree_elem *new) 81 struct nft_rbtree_elem *new)
88{ 82{
89 struct nft_rbtree *priv = nft_set_priv(set); 83 struct nft_rbtree *priv = nft_set_priv(set);
90 struct nft_rbtree_elem *rbe; 84 struct nft_rbtree_elem *rbe;
91 struct rb_node *parent, **p; 85 struct rb_node *parent, **p;
86 u8 genmask = nft_genmask_next(read_pnet(&set->pnet));
92 int d; 87 int d;
93 88
94 parent = NULL; 89 parent = NULL;
@@ -96,13 +91,18 @@ static int __nft_rbtree_insert(const struct nft_set *set,
96 while (*p != NULL) { 91 while (*p != NULL) {
97 parent = *p; 92 parent = *p;
98 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 93 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
99 d = nft_data_cmp(&rbe->key, &new->key, set->klen); 94 d = nft_data_cmp(nft_set_ext_key(&rbe->ext),
95 nft_set_ext_key(&new->ext),
96 set->klen);
100 if (d < 0) 97 if (d < 0)
101 p = &parent->rb_left; 98 p = &parent->rb_left;
102 else if (d > 0) 99 else if (d > 0)
103 p = &parent->rb_right; 100 p = &parent->rb_right;
104 else 101 else {
105 return -EEXIST; 102 if (nft_set_elem_active(&rbe->ext, genmask))
103 return -EEXIST;
104 p = &parent->rb_left;
105 }
106 } 106 }
107 rb_link_node(&new->node, parent, p); 107 rb_link_node(&new->node, parent, p);
108 rb_insert_color(&new->node, &priv->root); 108 rb_insert_color(&new->node, &priv->root);
@@ -112,31 +112,13 @@ static int __nft_rbtree_insert(const struct nft_set *set,
112static int nft_rbtree_insert(const struct nft_set *set, 112static int nft_rbtree_insert(const struct nft_set *set,
113 const struct nft_set_elem *elem) 113 const struct nft_set_elem *elem)
114{ 114{
115 struct nft_rbtree_elem *rbe; 115 struct nft_rbtree_elem *rbe = elem->priv;
116 unsigned int size;
117 int err; 116 int err;
118 117
119 size = sizeof(*rbe);
120 if (set->flags & NFT_SET_MAP &&
121 !(elem->flags & NFT_SET_ELEM_INTERVAL_END))
122 size += sizeof(rbe->data[0]);
123
124 rbe = kzalloc(size, GFP_KERNEL);
125 if (rbe == NULL)
126 return -ENOMEM;
127
128 rbe->flags = elem->flags;
129 nft_data_copy(&rbe->key, &elem->key);
130 if (set->flags & NFT_SET_MAP &&
131 !(rbe->flags & NFT_SET_ELEM_INTERVAL_END))
132 nft_data_copy(rbe->data, &elem->data);
133
134 spin_lock_bh(&nft_rbtree_lock); 118 spin_lock_bh(&nft_rbtree_lock);
135 err = __nft_rbtree_insert(set, rbe); 119 err = __nft_rbtree_insert(set, rbe);
136 if (err < 0)
137 kfree(rbe);
138
139 spin_unlock_bh(&nft_rbtree_lock); 120 spin_unlock_bh(&nft_rbtree_lock);
121
140 return err; 122 return err;
141} 123}
142 124
@@ -144,39 +126,49 @@ static void nft_rbtree_remove(const struct nft_set *set,
144 const struct nft_set_elem *elem) 126 const struct nft_set_elem *elem)
145{ 127{
146 struct nft_rbtree *priv = nft_set_priv(set); 128 struct nft_rbtree *priv = nft_set_priv(set);
147 struct nft_rbtree_elem *rbe = elem->cookie; 129 struct nft_rbtree_elem *rbe = elem->priv;
148 130
149 spin_lock_bh(&nft_rbtree_lock); 131 spin_lock_bh(&nft_rbtree_lock);
150 rb_erase(&rbe->node, &priv->root); 132 rb_erase(&rbe->node, &priv->root);
151 spin_unlock_bh(&nft_rbtree_lock); 133 spin_unlock_bh(&nft_rbtree_lock);
152 kfree(rbe);
153} 134}
154 135
155static int nft_rbtree_get(const struct nft_set *set, struct nft_set_elem *elem) 136static void nft_rbtree_activate(const struct nft_set *set,
137 const struct nft_set_elem *elem)
138{
139 struct nft_rbtree_elem *rbe = elem->priv;
140
141 nft_set_elem_change_active(set, &rbe->ext);
142}
143
144static void *nft_rbtree_deactivate(const struct nft_set *set,
145 const struct nft_set_elem *elem)
156{ 146{
157 const struct nft_rbtree *priv = nft_set_priv(set); 147 const struct nft_rbtree *priv = nft_set_priv(set);
158 const struct rb_node *parent = priv->root.rb_node; 148 const struct rb_node *parent = priv->root.rb_node;
159 struct nft_rbtree_elem *rbe; 149 struct nft_rbtree_elem *rbe;
150 u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
160 int d; 151 int d;
161 152
162 while (parent != NULL) { 153 while (parent != NULL) {
163 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 154 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
164 155
165 d = nft_data_cmp(&rbe->key, &elem->key, set->klen); 156 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), &elem->key,
157 set->klen);
166 if (d < 0) 158 if (d < 0)
167 parent = parent->rb_left; 159 parent = parent->rb_left;
168 else if (d > 0) 160 else if (d > 0)
169 parent = parent->rb_right; 161 parent = parent->rb_right;
170 else { 162 else {
171 elem->cookie = rbe; 163 if (!nft_set_elem_active(&rbe->ext, genmask)) {
172 if (set->flags & NFT_SET_MAP && 164 parent = parent->rb_left;
173 !(rbe->flags & NFT_SET_ELEM_INTERVAL_END)) 165 continue;
174 nft_data_copy(&elem->data, rbe->data); 166 }
175 elem->flags = rbe->flags; 167 nft_set_elem_change_active(set, &rbe->ext);
176 return 0; 168 return rbe;
177 } 169 }
178 } 170 }
179 return -ENOENT; 171 return NULL;
180} 172}
181 173
182static void nft_rbtree_walk(const struct nft_ctx *ctx, 174static void nft_rbtree_walk(const struct nft_ctx *ctx,
@@ -184,21 +176,21 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
184 struct nft_set_iter *iter) 176 struct nft_set_iter *iter)
185{ 177{
186 const struct nft_rbtree *priv = nft_set_priv(set); 178 const struct nft_rbtree *priv = nft_set_priv(set);
187 const struct nft_rbtree_elem *rbe; 179 struct nft_rbtree_elem *rbe;
188 struct nft_set_elem elem; 180 struct nft_set_elem elem;
189 struct rb_node *node; 181 struct rb_node *node;
182 u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
190 183
191 spin_lock_bh(&nft_rbtree_lock); 184 spin_lock_bh(&nft_rbtree_lock);
192 for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { 185 for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
186 rbe = rb_entry(node, struct nft_rbtree_elem, node);
187
193 if (iter->count < iter->skip) 188 if (iter->count < iter->skip)
194 goto cont; 189 goto cont;
190 if (!nft_set_elem_active(&rbe->ext, genmask))
191 goto cont;
195 192
196 rbe = rb_entry(node, struct nft_rbtree_elem, node); 193 elem.priv = rbe;
197 nft_data_copy(&elem.key, &rbe->key);
198 if (set->flags & NFT_SET_MAP &&
199 !(rbe->flags & NFT_SET_ELEM_INTERVAL_END))
200 nft_data_copy(&elem.data, rbe->data);
201 elem.flags = rbe->flags;
202 194
203 iter->err = iter->fn(ctx, set, iter, &elem); 195 iter->err = iter->fn(ctx, set, iter, &elem);
204 if (iter->err < 0) { 196 if (iter->err < 0) {
@@ -235,7 +227,7 @@ static void nft_rbtree_destroy(const struct nft_set *set)
235 while ((node = priv->root.rb_node) != NULL) { 227 while ((node = priv->root.rb_node) != NULL) {
236 rb_erase(node, &priv->root); 228 rb_erase(node, &priv->root);
237 rbe = rb_entry(node, struct nft_rbtree_elem, node); 229 rbe = rb_entry(node, struct nft_rbtree_elem, node);
238 nft_rbtree_elem_destroy(set, rbe); 230 nft_set_elem_destroy(set, rbe);
239 } 231 }
240} 232}
241 233
@@ -245,9 +237,6 @@ static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features,
245 unsigned int nsize; 237 unsigned int nsize;
246 238
247 nsize = sizeof(struct nft_rbtree_elem); 239 nsize = sizeof(struct nft_rbtree_elem);
248 if (features & NFT_SET_MAP)
249 nsize += FIELD_SIZEOF(struct nft_rbtree_elem, data[0]);
250
251 if (desc->size) 240 if (desc->size)
252 est->size = sizeof(struct nft_rbtree) + desc->size * nsize; 241 est->size = sizeof(struct nft_rbtree) + desc->size * nsize;
253 else 242 else
@@ -260,12 +249,14 @@ static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features,
260 249
261static struct nft_set_ops nft_rbtree_ops __read_mostly = { 250static struct nft_set_ops nft_rbtree_ops __read_mostly = {
262 .privsize = nft_rbtree_privsize, 251 .privsize = nft_rbtree_privsize,
252 .elemsize = offsetof(struct nft_rbtree_elem, ext),
263 .estimate = nft_rbtree_estimate, 253 .estimate = nft_rbtree_estimate,
264 .init = nft_rbtree_init, 254 .init = nft_rbtree_init,
265 .destroy = nft_rbtree_destroy, 255 .destroy = nft_rbtree_destroy,
266 .insert = nft_rbtree_insert, 256 .insert = nft_rbtree_insert,
267 .remove = nft_rbtree_remove, 257 .remove = nft_rbtree_remove,
268 .get = nft_rbtree_get, 258 .deactivate = nft_rbtree_deactivate,
259 .activate = nft_rbtree_activate,
269 .lookup = nft_rbtree_lookup, 260 .lookup = nft_rbtree_lookup,
270 .walk = nft_rbtree_walk, 261 .walk = nft_rbtree_walk,
271 .features = NFT_SET_INTERVAL | NFT_SET_MAP, 262 .features = NFT_SET_INTERVAL | NFT_SET_MAP,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 4caa809dbbe0..19909d0786a2 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -3127,7 +3127,7 @@ static struct pernet_operations __net_initdata netlink_net_ops = {
3127 .exit = netlink_net_exit, 3127 .exit = netlink_net_exit,
3128}; 3128};
3129 3129
3130static inline u32 netlink_hash(const void *data, u32 seed) 3130static inline u32 netlink_hash(const void *data, u32 len, u32 seed)
3131{ 3131{
3132 const struct netlink_sock *nlk = data; 3132 const struct netlink_sock *nlk = data;
3133 struct netlink_compare_arg arg; 3133 struct netlink_compare_arg arg;