hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/net/netfilter/nf_tables_api.c
....@@ -21,15 +21,20 @@
2121 #include <net/netfilter/nf_tables.h>
2222 #include <net/netfilter/nf_tables_offload.h>
2323 #include <net/net_namespace.h>
24
+#include <net/netns/generic.h>
2425 #include <net/sock.h>
2526
2627 #define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-"))
28
+
29
+unsigned int nf_tables_net_id __read_mostly;
2730
2831 static LIST_HEAD(nf_tables_expressions);
2932 static LIST_HEAD(nf_tables_objects);
3033 static LIST_HEAD(nf_tables_flowtables);
3134 static LIST_HEAD(nf_tables_destroy_list);
35
+static LIST_HEAD(nf_tables_gc_list);
3236 static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
37
+static DEFINE_SPINLOCK(nf_tables_gc_list_lock);
3338 static u64 table_handle;
3439
3540 enum {
....@@ -103,7 +108,9 @@
103108
104109 static void nft_validate_state_update(struct net *net, u8 new_validate_state)
105110 {
106
- switch (net->nft.validate_state) {
111
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
112
+
113
+ switch (nft_net->validate_state) {
107114 case NFT_VALIDATE_SKIP:
108115 WARN_ON_ONCE(new_validate_state == NFT_VALIDATE_DO);
109116 break;
....@@ -114,10 +121,13 @@
114121 return;
115122 }
116123
117
- net->nft.validate_state = new_validate_state;
124
+ nft_net->validate_state = new_validate_state;
118125 }
119126 static void nf_tables_trans_destroy_work(struct work_struct *w);
120127 static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
128
+
129
+static void nft_trans_gc_work(struct work_struct *work);
130
+static DECLARE_WORK(trans_gc_work, nft_trans_gc_work);
121131
122132 static void nft_ctx_init(struct nft_ctx *ctx,
123133 struct net *net,
....@@ -150,6 +160,7 @@
150160 return NULL;
151161
152162 INIT_LIST_HEAD(&trans->list);
163
+ INIT_LIST_HEAD(&trans->binding_list);
153164 trans->msg_type = msg_type;
154165 trans->ctx = *ctx;
155166
....@@ -162,32 +173,107 @@
162173 return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL);
163174 }
164175
165
-static void nft_trans_destroy(struct nft_trans *trans)
176
+static void nft_trans_list_del(struct nft_trans *trans)
166177 {
167178 list_del(&trans->list);
179
+ list_del(&trans->binding_list);
180
+}
181
+
182
+static void nft_trans_destroy(struct nft_trans *trans)
183
+{
184
+ nft_trans_list_del(trans);
168185 kfree(trans);
169186 }
170187
171
-static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
188
+static void __nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set,
189
+ bool bind)
172190 {
191
+ struct nftables_pernet *nft_net;
173192 struct net *net = ctx->net;
174193 struct nft_trans *trans;
175194
176195 if (!nft_set_is_anonymous(set))
177196 return;
178197
179
- list_for_each_entry_reverse(trans, &net->nft.commit_list, list) {
198
+ nft_net = net_generic(net, nf_tables_net_id);
199
+ list_for_each_entry_reverse(trans, &nft_net->commit_list, list) {
180200 switch (trans->msg_type) {
181201 case NFT_MSG_NEWSET:
182202 if (nft_trans_set(trans) == set)
183
- nft_trans_set_bound(trans) = true;
203
+ nft_trans_set_bound(trans) = bind;
184204 break;
185205 case NFT_MSG_NEWSETELEM:
186206 if (nft_trans_elem_set(trans) == set)
187
- nft_trans_elem_set_bound(trans) = true;
207
+ nft_trans_elem_set_bound(trans) = bind;
188208 break;
189209 }
190210 }
211
+}
212
+
213
+static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
214
+{
215
+ return __nft_set_trans_bind(ctx, set, true);
216
+}
217
+
218
+static void nft_set_trans_unbind(const struct nft_ctx *ctx, struct nft_set *set)
219
+{
220
+ return __nft_set_trans_bind(ctx, set, false);
221
+}
222
+
223
+static void __nft_chain_trans_bind(const struct nft_ctx *ctx,
224
+ struct nft_chain *chain, bool bind)
225
+{
226
+ struct nftables_pernet *nft_net;
227
+ struct net *net = ctx->net;
228
+ struct nft_trans *trans;
229
+
230
+ if (!nft_chain_binding(chain))
231
+ return;
232
+
233
+ nft_net = net_generic(net, nf_tables_net_id);
234
+ list_for_each_entry_reverse(trans, &nft_net->commit_list, list) {
235
+ switch (trans->msg_type) {
236
+ case NFT_MSG_NEWCHAIN:
237
+ if (nft_trans_chain(trans) == chain)
238
+ nft_trans_chain_bound(trans) = bind;
239
+ break;
240
+ case NFT_MSG_NEWRULE:
241
+ if (trans->ctx.chain == chain)
242
+ nft_trans_rule_bound(trans) = bind;
243
+ break;
244
+ }
245
+ }
246
+}
247
+
248
+static void nft_chain_trans_bind(const struct nft_ctx *ctx,
249
+ struct nft_chain *chain)
250
+{
251
+ __nft_chain_trans_bind(ctx, chain, true);
252
+}
253
+
254
+int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain)
255
+{
256
+ if (!nft_chain_binding(chain))
257
+ return 0;
258
+
259
+ if (nft_chain_binding(ctx->chain))
260
+ return -EOPNOTSUPP;
261
+
262
+ if (chain->bound)
263
+ return -EBUSY;
264
+
265
+ if (!nft_use_inc(&chain->use))
266
+ return -EMFILE;
267
+
268
+ chain->bound = true;
269
+ nft_chain_trans_bind(ctx, chain);
270
+
271
+ return 0;
272
+}
273
+
274
+void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain)
275
+{
276
+ __nft_chain_trans_bind(ctx, chain, false);
191277 }
192278
193279 static int nft_netdev_register_hooks(struct net *net,
....@@ -217,12 +303,18 @@
217303 }
218304
219305 static void nft_netdev_unregister_hooks(struct net *net,
220
- struct list_head *hook_list)
306
+ struct list_head *hook_list,
307
+ bool release_netdev)
221308 {
222
- struct nft_hook *hook;
309
+ struct nft_hook *hook, *next;
223310
224
- list_for_each_entry(hook, hook_list, list)
311
+ list_for_each_entry_safe(hook, next, hook_list, list) {
225312 nf_unregister_net_hook(net, &hook->ops);
313
+ if (release_netdev) {
314
+ list_del(&hook->list);
315
+ kfree_rcu(hook, rcu);
316
+ }
317
+ }
226318 }
227319
228320 static int nf_tables_register_hook(struct net *net,
....@@ -248,9 +340,10 @@
248340 return nf_register_net_hook(net, &basechain->ops);
249341 }
250342
251
-static void nf_tables_unregister_hook(struct net *net,
252
- const struct nft_table *table,
253
- struct nft_chain *chain)
343
+static void __nf_tables_unregister_hook(struct net *net,
344
+ const struct nft_table *table,
345
+ struct nft_chain *chain,
346
+ bool release_netdev)
254347 {
255348 struct nft_base_chain *basechain;
256349 const struct nf_hook_ops *ops;
....@@ -265,9 +358,38 @@
265358 return basechain->type->ops_unregister(net, ops);
266359
267360 if (nft_base_chain_netdev(table->family, basechain->ops.hooknum))
268
- nft_netdev_unregister_hooks(net, &basechain->hook_list);
361
+ nft_netdev_unregister_hooks(net, &basechain->hook_list,
362
+ release_netdev);
269363 else
270364 nf_unregister_net_hook(net, &basechain->ops);
365
+}
366
+
367
+static void nf_tables_unregister_hook(struct net *net,
368
+ const struct nft_table *table,
369
+ struct nft_chain *chain)
370
+{
371
+ return __nf_tables_unregister_hook(net, table, chain, false);
372
+}
373
+
374
+static void nft_trans_commit_list_add_tail(struct net *net, struct nft_trans *trans)
375
+{
376
+ struct nftables_pernet *nft_net;
377
+
378
+ nft_net = net_generic(net, nf_tables_net_id);
379
+
380
+ switch (trans->msg_type) {
381
+ case NFT_MSG_NEWSET:
382
+ if (nft_set_is_anonymous(nft_trans_set(trans)))
383
+ list_add_tail(&trans->binding_list, &nft_net->binding_list);
384
+ break;
385
+ case NFT_MSG_NEWCHAIN:
386
+ if (!nft_trans_chain_update(trans) &&
387
+ nft_chain_binding(nft_trans_chain(trans)))
388
+ list_add_tail(&trans->binding_list, &nft_net->binding_list);
389
+ break;
390
+ }
391
+
392
+ list_add_tail(&trans->list, &nft_net->commit_list);
271393 }
272394
273395 static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
....@@ -281,7 +403,7 @@
281403 if (msg_type == NFT_MSG_NEWTABLE)
282404 nft_activate_next(ctx->net, ctx->table);
283405
284
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
406
+ nft_trans_commit_list_add_tail(ctx->net, trans);
285407 return 0;
286408 }
287409
....@@ -313,8 +435,9 @@
313435 ntohl(nla_get_be32(ctx->nla[NFTA_CHAIN_ID]));
314436 }
315437 }
438
+ nft_trans_chain(trans) = ctx->chain;
439
+ nft_trans_commit_list_add_tail(ctx->net, trans);
316440
317
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
318441 return trans;
319442 }
320443
....@@ -326,14 +449,13 @@
326449 if (IS_ERR(trans))
327450 return PTR_ERR(trans);
328451
329
- ctx->table->use--;
452
+ nft_use_dec(&ctx->table->use);
330453 nft_deactivate_next(ctx->net, ctx->chain);
331454
332455 return 0;
333456 }
334457
335
-static void nft_rule_expr_activate(const struct nft_ctx *ctx,
336
- struct nft_rule *rule)
458
+void nft_rule_expr_activate(const struct nft_ctx *ctx, struct nft_rule *rule)
337459 {
338460 struct nft_expr *expr;
339461
....@@ -346,9 +468,8 @@
346468 }
347469 }
348470
349
-static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
350
- struct nft_rule *rule,
351
- enum nft_trans_phase phase)
471
+void nft_rule_expr_deactivate(const struct nft_ctx *ctx, struct nft_rule *rule,
472
+ enum nft_trans_phase phase)
352473 {
353474 struct nft_expr *expr;
354475
....@@ -367,7 +488,7 @@
367488 /* You cannot delete the same rule twice */
368489 if (nft_is_active_next(ctx->net, rule)) {
369490 nft_deactivate_next(ctx->net, rule);
370
- ctx->chain->use--;
491
+ nft_use_dec(&ctx->chain->use);
371492 return 0;
372493 }
373494 return -ENOENT;
....@@ -387,7 +508,7 @@
387508 ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
388509 }
389510 nft_trans_rule(trans) = rule;
390
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
511
+ nft_trans_commit_list_add_tail(ctx->net, trans);
391512
392513 return trans;
393514 }
....@@ -453,9 +574,30 @@
453574 nft_activate_next(ctx->net, set);
454575 }
455576 nft_trans_set(trans) = set;
456
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
577
+ nft_trans_commit_list_add_tail(ctx->net, trans);
457578
458579 return 0;
580
+}
581
+
582
+static int nft_mapelem_deactivate(const struct nft_ctx *ctx,
583
+ struct nft_set *set,
584
+ const struct nft_set_iter *iter,
585
+ struct nft_set_elem *elem)
586
+{
587
+ nft_setelem_data_deactivate(ctx->net, set, elem);
588
+
589
+ return 0;
590
+}
591
+
592
+static void nft_map_deactivate(const struct nft_ctx *ctx, struct nft_set *set)
593
+{
594
+ struct nft_set_iter iter = {
595
+ .genmask = nft_genmask_next(ctx->net),
596
+ .fn = nft_mapelem_deactivate,
597
+ };
598
+
599
+ set->ops->walk(ctx, set, &iter);
600
+ WARN_ON_ONCE(iter.err);
459601 }
460602
461603 static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
....@@ -466,8 +608,11 @@
466608 if (err < 0)
467609 return err;
468610
611
+ if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
612
+ nft_map_deactivate(ctx, set);
613
+
469614 nft_deactivate_next(ctx->net, set);
470
- ctx->table->use--;
615
+ nft_use_dec(&ctx->table->use);
471616
472617 return err;
473618 }
....@@ -485,7 +630,7 @@
485630 nft_activate_next(ctx->net, obj);
486631
487632 nft_trans_obj(trans) = obj;
488
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
633
+ nft_trans_commit_list_add_tail(ctx->net, trans);
489634
490635 return 0;
491636 }
....@@ -499,7 +644,7 @@
499644 return err;
500645
501646 nft_deactivate_next(ctx->net, obj);
502
- ctx->table->use--;
647
+ nft_use_dec(&ctx->table->use);
503648
504649 return err;
505650 }
....@@ -519,7 +664,7 @@
519664
520665 INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
521666 nft_trans_flowtable(trans) = flowtable;
522
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
667
+ nft_trans_commit_list_add_tail(ctx->net, trans);
523668
524669 return 0;
525670 }
....@@ -534,7 +679,7 @@
534679 return err;
535680
536681 nft_deactivate_next(ctx->net, flowtable);
537
- ctx->table->use--;
682
+ nft_use_dec(&ctx->table->use);
538683
539684 return err;
540685 }
....@@ -547,13 +692,15 @@
547692 const struct nlattr *nla,
548693 u8 family, u8 genmask)
549694 {
695
+ struct nftables_pernet *nft_net;
550696 struct nft_table *table;
551697
552698 if (nla == NULL)
553699 return ERR_PTR(-EINVAL);
554700
555
- list_for_each_entry_rcu(table, &net->nft.tables, list,
556
- lockdep_is_held(&net->nft.commit_mutex)) {
701
+ nft_net = net_generic(net, nf_tables_net_id);
702
+ list_for_each_entry_rcu(table, &nft_net->tables, list,
703
+ lockdep_is_held(&nft_net->commit_mutex)) {
557704 if (!nla_strcmp(nla, table->name) &&
558705 table->family == family &&
559706 nft_active_genmask(table, genmask))
....@@ -567,9 +714,11 @@
567714 const struct nlattr *nla,
568715 u8 genmask)
569716 {
717
+ struct nftables_pernet *nft_net;
570718 struct nft_table *table;
571719
572
- list_for_each_entry(table, &net->nft.tables, list) {
720
+ nft_net = net_generic(net, nf_tables_net_id);
721
+ list_for_each_entry(table, &nft_net->tables, list) {
573722 if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
574723 nft_active_genmask(table, genmask))
575724 return table;
....@@ -621,6 +770,7 @@
621770 static int nft_request_module(struct net *net, const char *fmt, ...)
622771 {
623772 char module_name[MODULE_NAME_LEN];
773
+ struct nftables_pernet *nft_net;
624774 struct nft_module_request *req;
625775 va_list args;
626776 int ret;
....@@ -631,7 +781,8 @@
631781 if (ret >= MODULE_NAME_LEN)
632782 return 0;
633783
634
- list_for_each_entry(req, &net->nft.module_list, list) {
784
+ nft_net = net_generic(net, nf_tables_net_id);
785
+ list_for_each_entry(req, &nft_net->module_list, list) {
635786 if (!strcmp(req->module, module_name)) {
636787 if (req->done)
637788 return 0;
....@@ -647,7 +798,7 @@
647798
648799 req->done = false;
649800 strlcpy(req->module, module_name, MODULE_NAME_LEN);
650
- list_add_tail(&req->list, &net->nft.module_list);
801
+ list_add_tail(&req->list, &nft_net->module_list);
651802
652803 return -EAGAIN;
653804 }
....@@ -685,7 +836,9 @@
685836
686837 static __be16 nft_base_seq(const struct net *net)
687838 {
688
- return htons(net->nft.base_seq & 0xffff);
839
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
840
+
841
+ return htons(nft_net->base_seq & 0xffff);
689842 }
690843
691844 static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
....@@ -743,6 +896,7 @@
743896
744897 static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
745898 {
899
+ struct nftables_pernet *nft_net;
746900 struct sk_buff *skb;
747901 int err;
748902
....@@ -761,7 +915,8 @@
761915 goto err;
762916 }
763917
764
- nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
918
+ nft_net = net_generic(ctx->net, nf_tables_net_id);
919
+ nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
765920 return;
766921 err:
767922 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
....@@ -771,15 +926,17 @@
771926 struct netlink_callback *cb)
772927 {
773928 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
929
+ struct nftables_pernet *nft_net;
774930 const struct nft_table *table;
775931 unsigned int idx = 0, s_idx = cb->args[0];
776932 struct net *net = sock_net(skb->sk);
777933 int family = nfmsg->nfgen_family;
778934
779935 rcu_read_lock();
780
- cb->seq = net->nft.base_seq;
936
+ nft_net = net_generic(net, nf_tables_net_id);
937
+ cb->seq = nft_net->base_seq;
781938
782
- list_for_each_entry_rcu(table, &net->nft.tables, list) {
939
+ list_for_each_entry_rcu(table, &nft_net->tables, list) {
783940 if (family != NFPROTO_UNSPEC && family != table->family)
784941 continue;
785942
....@@ -954,7 +1111,7 @@
9541111 goto err;
9551112
9561113 nft_trans_table_update(trans) = true;
957
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
1114
+ nft_trans_commit_list_add_tail(ctx->net, trans);
9581115 return 0;
9591116 err:
9601117 nft_trans_destroy(trans);
....@@ -1017,6 +1174,7 @@
10171174 const struct nlattr * const nla[],
10181175 struct netlink_ext_ack *extack)
10191176 {
1177
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
10201178 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
10211179 u8 genmask = nft_genmask_next(net);
10221180 int family = nfmsg->nfgen_family;
....@@ -1026,7 +1184,7 @@
10261184 u32 flags = 0;
10271185 int err;
10281186
1029
- lockdep_assert_held(&net->nft.commit_mutex);
1187
+ lockdep_assert_held(&nft_net->commit_mutex);
10301188 attr = nla[NFTA_TABLE_NAME];
10311189 table = nft_table_lookup(net, attr, family, genmask);
10321190 if (IS_ERR(table)) {
....@@ -1084,7 +1242,7 @@
10841242 if (err < 0)
10851243 goto err_trans;
10861244
1087
- list_add_tail_rcu(&table->list, &net->nft.tables);
1245
+ list_add_tail_rcu(&table->list, &nft_net->tables);
10881246 return 0;
10891247 err_trans:
10901248 rhltable_destroy(&table->chains_ht);
....@@ -1110,7 +1268,7 @@
11101268 if (!nft_is_active_next(ctx->net, chain))
11111269 continue;
11121270
1113
- if (nft_chain_is_bound(chain))
1271
+ if (nft_chain_binding(chain))
11141272 continue;
11151273
11161274 ctx->chain = chain;
....@@ -1124,8 +1282,7 @@
11241282 if (!nft_is_active_next(ctx->net, set))
11251283 continue;
11261284
1127
- if (nft_set_is_anonymous(set) &&
1128
- !list_empty(&set->bindings))
1285
+ if (nft_set_is_anonymous(set))
11291286 continue;
11301287
11311288 err = nft_delset(ctx, set);
....@@ -1155,7 +1312,7 @@
11551312 if (!nft_is_active_next(ctx->net, chain))
11561313 continue;
11571314
1158
- if (nft_chain_is_bound(chain))
1315
+ if (nft_chain_binding(chain))
11591316 continue;
11601317
11611318 ctx->chain = chain;
....@@ -1172,11 +1329,12 @@
11721329
11731330 static int nft_flush(struct nft_ctx *ctx, int family)
11741331 {
1332
+ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
11751333 struct nft_table *table, *nt;
11761334 const struct nlattr * const *nla = ctx->nla;
11771335 int err = 0;
11781336
1179
- list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) {
1337
+ list_for_each_entry_safe(table, nt, &nft_net->tables, list) {
11801338 if (family != AF_UNSPEC && table->family != family)
11811339 continue;
11821340
....@@ -1291,7 +1449,9 @@
12911449 static bool lockdep_commit_lock_is_held(const struct net *net)
12921450 {
12931451 #ifdef CONFIG_PROVE_LOCKING
1294
- return lockdep_is_held(&net->nft.commit_mutex);
1452
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
1453
+
1454
+ return lockdep_is_held(&nft_net->commit_mutex);
12951455 #else
12961456 return true;
12971457 #endif
....@@ -1494,6 +1654,7 @@
14941654
14951655 static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
14961656 {
1657
+ struct nftables_pernet *nft_net;
14971658 struct sk_buff *skb;
14981659 int err;
14991660
....@@ -1513,7 +1674,8 @@
15131674 goto err;
15141675 }
15151676
1516
- nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
1677
+ nft_net = net_generic(ctx->net, nf_tables_net_id);
1678
+ nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
15171679 return;
15181680 err:
15191681 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
....@@ -1528,11 +1690,13 @@
15281690 unsigned int idx = 0, s_idx = cb->args[0];
15291691 struct net *net = sock_net(skb->sk);
15301692 int family = nfmsg->nfgen_family;
1693
+ struct nftables_pernet *nft_net;
15311694
15321695 rcu_read_lock();
1533
- cb->seq = net->nft.base_seq;
1696
+ nft_net = net_generic(net, nf_tables_net_id);
1697
+ cb->seq = nft_net->base_seq;
15341698
1535
- list_for_each_entry_rcu(table, &net->nft.tables, list) {
1699
+ list_for_each_entry_rcu(table, &nft_net->tables, list) {
15361700 if (family != NFPROTO_UNSPEC && family != table->family)
15371701 continue;
15381702
....@@ -1847,11 +2011,12 @@
18472011 struct nft_chain_hook *hook, u8 family,
18482012 bool autoload)
18492013 {
2014
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
18502015 struct nlattr *ha[NFTA_HOOK_MAX + 1];
18512016 const struct nft_chain_type *type;
18522017 int err;
18532018
1854
- lockdep_assert_held(&net->nft.commit_mutex);
2019
+ lockdep_assert_held(&nft_net->commit_mutex);
18552020 lockdep_nfnl_nft_mutex_not_held();
18562021
18572022 err = nla_parse_nested_deprecated(ha, NFTA_HOOK_MAX,
....@@ -1981,7 +2146,7 @@
19812146 return 0;
19822147 }
19832148
1984
-static int nft_chain_add(struct nft_table *table, struct nft_chain *chain)
2149
+int nft_chain_add(struct nft_table *table, struct nft_chain *chain)
19852150 {
19862151 int err;
19872152
....@@ -2009,9 +2174,6 @@
20092174 struct nft_chain *chain;
20102175 struct nft_rule **rules;
20112176 int err;
2012
-
2013
- if (table->use == UINT_MAX)
2014
- return -EOVERFLOW;
20152177
20162178 if (nla[NFTA_CHAIN_HOOK]) {
20172179 struct nft_stats __percpu *stats = NULL;
....@@ -2108,6 +2270,11 @@
21082270 if (err < 0)
21092271 goto err_destroy_chain;
21102272
2273
+ if (!nft_use_inc(&table->use)) {
2274
+ err = -EMFILE;
2275
+ goto err_use;
2276
+ }
2277
+
21112278 trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
21122279 if (IS_ERR(trans)) {
21132280 err = PTR_ERR(trans);
....@@ -2124,10 +2291,11 @@
21242291 goto err_unregister_hook;
21252292 }
21262293
2127
- table->use++;
2128
-
21292294 return 0;
2295
+
21302296 err_unregister_hook:
2297
+ nft_use_dec_restore(&table->use);
2298
+err_use:
21312299 nf_tables_unregister_hook(net, table, chain);
21322300 err_destroy_chain:
21332301 nf_tables_chain_destroy(ctx);
....@@ -2244,6 +2412,7 @@
22442412
22452413 if (nla[NFTA_CHAIN_HANDLE] &&
22462414 nla[NFTA_CHAIN_NAME]) {
2415
+ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
22472416 struct nft_trans *tmp;
22482417 char *name;
22492418
....@@ -2253,7 +2422,7 @@
22532422 goto err;
22542423
22552424 err = -EEXIST;
2256
- list_for_each_entry(tmp, &ctx->net->nft.commit_list, list) {
2425
+ list_for_each_entry(tmp, &nft_net->commit_list, list) {
22572426 if (tmp->msg_type == NFT_MSG_NEWCHAIN &&
22582427 tmp->ctx.table == table &&
22592428 nft_trans_chain_update(tmp) &&
....@@ -2267,7 +2436,7 @@
22672436
22682437 nft_trans_chain_name(trans) = name;
22692438 }
2270
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
2439
+ nft_trans_commit_list_add_tail(ctx->net, trans);
22712440
22722441 return 0;
22732442 err:
....@@ -2278,17 +2447,19 @@
22782447
22792448 static struct nft_chain *nft_chain_lookup_byid(const struct net *net,
22802449 const struct nft_table *table,
2281
- const struct nlattr *nla)
2450
+ const struct nlattr *nla, u8 genmask)
22822451 {
2452
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
22832453 u32 id = ntohl(nla_get_be32(nla));
22842454 struct nft_trans *trans;
22852455
2286
- list_for_each_entry(trans, &net->nft.commit_list, list) {
2456
+ list_for_each_entry(trans, &nft_net->commit_list, list) {
22872457 struct nft_chain *chain = trans->ctx.chain;
22882458
22892459 if (trans->msg_type == NFT_MSG_NEWCHAIN &&
22902460 chain->table == table &&
2291
- id == nft_trans_chain_id(trans))
2461
+ id == nft_trans_chain_id(trans) &&
2462
+ nft_active_genmask(chain, genmask))
22922463 return chain;
22932464 }
22942465 return ERR_PTR(-ENOENT);
....@@ -2299,6 +2470,7 @@
22992470 const struct nlattr * const nla[],
23002471 struct netlink_ext_ack *extack)
23012472 {
2473
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
23022474 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
23032475 u8 genmask = nft_genmask_next(net);
23042476 int family = nfmsg->nfgen_family;
....@@ -2310,7 +2482,7 @@
23102482 u64 handle = 0;
23112483 u32 flags = 0;
23122484
2313
- lockdep_assert_held(&net->nft.commit_mutex);
2485
+ lockdep_assert_held(&nft_net->commit_mutex);
23142486
23152487 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask);
23162488 if (IS_ERR(table)) {
....@@ -2426,6 +2598,9 @@
24262598 NL_SET_BAD_ATTR(extack, attr);
24272599 return PTR_ERR(chain);
24282600 }
2601
+
2602
+ if (nft_chain_binding(chain))
2603
+ return -EOPNOTSUPP;
24292604
24302605 if (nlh->nlmsg_flags & NLM_F_NONREC &&
24312606 chain->use > 0)
....@@ -2848,6 +3023,7 @@
28483023 static void nf_tables_rule_notify(const struct nft_ctx *ctx,
28493024 const struct nft_rule *rule, int event)
28503025 {
3026
+ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
28513027 struct sk_buff *skb;
28523028 int err;
28533029
....@@ -2867,7 +3043,7 @@
28673043 goto err;
28683044 }
28693045
2870
- nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
3046
+ nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
28713047 return;
28723048 err:
28733049 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
....@@ -2925,11 +3101,13 @@
29253101 unsigned int idx = 0;
29263102 struct net *net = sock_net(skb->sk);
29273103 int family = nfmsg->nfgen_family;
3104
+ struct nftables_pernet *nft_net;
29283105
29293106 rcu_read_lock();
2930
- cb->seq = net->nft.base_seq;
3107
+ nft_net = net_generic(net, nf_tables_net_id);
3108
+ cb->seq = nft_net->base_seq;
29313109
2932
- list_for_each_entry_rcu(table, &net->nft.tables, list) {
3110
+ list_for_each_entry_rcu(table, &nft_net->tables, list) {
29333111 if (family != NFPROTO_UNSPEC && family != table->family)
29343112 continue;
29353113
....@@ -3076,8 +3254,7 @@
30763254 return err;
30773255 }
30783256
3079
-static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
3080
- struct nft_rule *rule)
3257
+void nf_tables_rule_destroy(const struct nft_ctx *ctx, struct nft_rule *rule)
30813258 {
30823259 struct nft_expr *expr, *next;
30833260
....@@ -3094,7 +3271,7 @@
30943271 kfree(rule);
30953272 }
30963273
3097
-void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
3274
+static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
30983275 {
30993276 nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
31003277 nf_tables_rule_destroy(ctx, rule);
....@@ -3145,6 +3322,8 @@
31453322 err = nft_chain_validate(&ctx, chain);
31463323 if (err < 0)
31473324 return err;
3325
+
3326
+ cond_resched();
31483327 }
31493328
31503329 return 0;
....@@ -3161,6 +3340,7 @@
31613340 const struct nlattr * const nla[],
31623341 struct netlink_ext_ack *extack)
31633342 {
3343
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
31643344 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
31653345 u8 genmask = nft_genmask_next(net);
31663346 struct nft_expr_info *info = NULL;
....@@ -3178,7 +3358,7 @@
31783358 int err, rem;
31793359 u64 handle, pos_handle;
31803360
3181
- lockdep_assert_held(&net->nft.commit_mutex);
3361
+ lockdep_assert_held(&nft_net->commit_mutex);
31823362
31833363 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask);
31843364 if (IS_ERR(table)) {
....@@ -3193,11 +3373,10 @@
31933373 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
31943374 return PTR_ERR(chain);
31953375 }
3196
- if (nft_chain_is_bound(chain))
3197
- return -EOPNOTSUPP;
31983376
31993377 } else if (nla[NFTA_RULE_CHAIN_ID]) {
3200
- chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID]);
3378
+ chain = nft_chain_lookup_byid(net, table, nla[NFTA_RULE_CHAIN_ID],
3379
+ genmask);
32013380 if (IS_ERR(chain)) {
32023381 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN_ID]);
32033382 return PTR_ERR(chain);
....@@ -3205,6 +3384,9 @@
32053384 } else {
32063385 return -EINVAL;
32073386 }
3387
+
3388
+ if (nft_chain_is_bound(chain))
3389
+ return -EOPNOTSUPP;
32083390
32093391 if (nla[NFTA_RULE_HANDLE]) {
32103392 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
....@@ -3227,9 +3409,6 @@
32273409 nlh->nlmsg_flags & NLM_F_REPLACE)
32283410 return -EINVAL;
32293411 handle = nf_tables_alloc_handle(table);
3230
-
3231
- if (chain->use == UINT_MAX)
3232
- return -EOVERFLOW;
32333412
32343413 if (nla[NFTA_RULE_POSITION]) {
32353414 pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
....@@ -3316,16 +3495,26 @@
33163495 expr = nft_expr_next(expr);
33173496 }
33183497
3498
+ if (!nft_use_inc(&chain->use)) {
3499
+ err = -EMFILE;
3500
+ goto err2;
3501
+ }
3502
+
33193503 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
3504
+ if (nft_chain_binding(chain)) {
3505
+ err = -EOPNOTSUPP;
3506
+ goto err_destroy_flow_rule;
3507
+ }
3508
+
33203509 trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
33213510 if (trans == NULL) {
33223511 err = -ENOMEM;
3323
- goto err2;
3512
+ goto err_destroy_flow_rule;
33243513 }
33253514 err = nft_delrule(&ctx, old_rule);
33263515 if (err < 0) {
33273516 nft_trans_destroy(trans);
3328
- goto err2;
3517
+ goto err_destroy_flow_rule;
33293518 }
33303519
33313520 list_add_tail_rcu(&rule->list, &old_rule->list);
....@@ -3333,7 +3522,7 @@
33333522 trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
33343523 if (!trans) {
33353524 err = -ENOMEM;
3336
- goto err2;
3525
+ goto err_destroy_flow_rule;
33373526 }
33383527
33393528 if (nlh->nlmsg_flags & NLM_F_APPEND) {
....@@ -3349,9 +3538,8 @@
33493538 }
33503539 }
33513540 kvfree(info);
3352
- chain->use++;
33533541
3354
- if (net->nft.validate_state == NFT_VALIDATE_DO)
3542
+ if (nft_net->validate_state == NFT_VALIDATE_DO)
33553543 return nft_table_validate(net, table);
33563544
33573545 if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
....@@ -3363,8 +3551,12 @@
33633551 }
33643552
33653553 return 0;
3554
+
3555
+err_destroy_flow_rule:
3556
+ nft_use_dec_restore(&chain->use);
33663557 err2:
3367
- nf_tables_rule_release(&ctx, rule);
3558
+ nft_rule_expr_deactivate(&ctx, rule, NFT_TRANS_PREPARE_ERROR);
3559
+ nf_tables_rule_destroy(&ctx, rule);
33683560 err1:
33693561 for (i = 0; i < n; i++) {
33703562 if (info[i].ops) {
....@@ -3381,10 +3573,11 @@
33813573 const struct nft_chain *chain,
33823574 const struct nlattr *nla)
33833575 {
3576
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
33843577 u32 id = ntohl(nla_get_be32(nla));
33853578 struct nft_trans *trans;
33863579
3387
- list_for_each_entry(trans, &net->nft.commit_list, list) {
3580
+ list_for_each_entry(trans, &nft_net->commit_list, list) {
33883581 struct nft_rule *rule = nft_trans_rule(trans);
33893582
33903583 if (trans->msg_type == NFT_MSG_NEWRULE &&
....@@ -3421,7 +3614,7 @@
34213614 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
34223615 return PTR_ERR(chain);
34233616 }
3424
- if (nft_chain_is_bound(chain))
3617
+ if (nft_chain_binding(chain))
34253618 return -EOPNOTSUPP;
34263619 }
34273620
....@@ -3450,6 +3643,8 @@
34503643 } else {
34513644 list_for_each_entry(chain, &table->chains, list) {
34523645 if (!nft_is_active_next(net, chain))
3646
+ continue;
3647
+ if (nft_chain_binding(chain))
34533648 continue;
34543649
34553650 ctx.chain = chain;
....@@ -3497,13 +3692,14 @@
34973692 const struct nft_set_desc *desc,
34983693 enum nft_set_policies policy)
34993694 {
3695
+ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
35003696 const struct nft_set_ops *ops, *bops;
35013697 struct nft_set_estimate est, best;
35023698 const struct nft_set_type *type;
35033699 u32 flags = 0;
35043700 int i;
35053701
3506
- lockdep_assert_held(&ctx->net->nft.commit_mutex);
3702
+ lockdep_assert_held(&nft_net->commit_mutex);
35073703 lockdep_nfnl_nft_mutex_not_held();
35083704
35093705 if (nla[NFTA_SET_FLAGS] != NULL)
....@@ -3641,10 +3837,11 @@
36413837 const struct nft_table *table,
36423838 const struct nlattr *nla, u8 genmask)
36433839 {
3840
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
36443841 struct nft_trans *trans;
36453842 u32 id = ntohl(nla_get_be32(nla));
36463843
3647
- list_for_each_entry(trans, &net->nft.commit_list, list) {
3844
+ list_for_each_entry(trans, &nft_net->commit_list, list) {
36483845 if (trans->msg_type == NFT_MSG_NEWSET) {
36493846 struct nft_set *set = nft_trans_set(trans);
36503847
....@@ -3867,6 +4064,7 @@
38674064 const struct nft_set *set, int event,
38684065 gfp_t gfp_flags)
38694066 {
4067
+ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
38704068 struct sk_buff *skb;
38714069 u32 portid = ctx->portid;
38724070 int err;
....@@ -3885,7 +4083,7 @@
38854083 goto err;
38864084 }
38874085
3888
- nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
4086
+ nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
38894087 return;
38904088 err:
38914089 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
....@@ -3898,14 +4096,16 @@
38984096 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
38994097 struct net *net = sock_net(skb->sk);
39004098 struct nft_ctx *ctx = cb->data, ctx_set;
4099
+ struct nftables_pernet *nft_net;
39014100
39024101 if (cb->args[1])
39034102 return skb->len;
39044103
39054104 rcu_read_lock();
3906
- cb->seq = net->nft.base_seq;
4105
+ nft_net = net_generic(net, nf_tables_net_id);
4106
+ cb->seq = nft_net->base_seq;
39074107
3908
- list_for_each_entry_rcu(table, &net->nft.tables, list) {
4108
+ list_for_each_entry_rcu(table, &nft_net->tables, list) {
39094109 if (ctx->family != NFPROTO_UNSPEC &&
39104110 ctx->family != table->family)
39114111 continue;
....@@ -4269,9 +4469,15 @@
42694469 alloc_size = sizeof(*set) + size + udlen;
42704470 if (alloc_size < size || alloc_size > INT_MAX)
42714471 return -ENOMEM;
4472
+
4473
+ if (!nft_use_inc(&table->use))
4474
+ return -EMFILE;
4475
+
42724476 set = kvzalloc(alloc_size, GFP_KERNEL);
4273
- if (!set)
4274
- return -ENOMEM;
4477
+ if (!set) {
4478
+ err = -ENOMEM;
4479
+ goto err_alloc;
4480
+ }
42754481
42764482 name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
42774483 if (!name) {
....@@ -4291,6 +4497,7 @@
42914497 }
42924498
42934499 INIT_LIST_HEAD(&set->bindings);
4500
+ refcount_set(&set->refs, 1);
42944501 set->table = table;
42954502 write_pnet(&set->net, net);
42964503 set->ops = ops;
....@@ -4326,25 +4533,37 @@
43264533 }
43274534
43284535 set->handle = nf_tables_alloc_handle(table);
4536
+ INIT_LIST_HEAD(&set->pending_update);
43294537
43304538 err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
43314539 if (err < 0)
43324540 goto err_set_expr_alloc;
43334541
43344542 list_add_tail_rcu(&set->list, &table->sets);
4335
- table->use++;
4543
+
43364544 return 0;
43374545
43384546 err_set_expr_alloc:
43394547 if (set->expr)
43404548 nft_expr_destroy(&ctx, set->expr);
43414549
4342
- ops->destroy(set);
4550
+ ops->destroy(&ctx, set);
43434551 err_set_init:
43444552 kfree(set->name);
43454553 err_set_name:
43464554 kvfree(set);
4555
+err_alloc:
4556
+ nft_use_dec_restore(&table->use);
4557
+
43474558 return err;
4559
+}
4560
+
4561
+static void nft_set_put(struct nft_set *set)
4562
+{
4563
+ if (refcount_dec_and_test(&set->refs)) {
4564
+ kfree(set->name);
4565
+ kvfree(set);
4566
+ }
43484567 }
43494568
43504569 static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
....@@ -4355,9 +4574,8 @@
43554574 if (set->expr)
43564575 nft_expr_destroy(ctx, set->expr);
43574576
4358
- set->ops->destroy(set);
4359
- kfree(set->name);
4360
- kvfree(set);
4577
+ set->ops->destroy(ctx, set);
4578
+ nft_set_put(set);
43614579 }
43624580
43634581 static int nf_tables_delset(struct net *net, struct sock *nlsk,
....@@ -4409,10 +4627,9 @@
44094627 enum nft_data_types type,
44104628 unsigned int len);
44114629
4412
-static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
4413
- struct nft_set *set,
4414
- const struct nft_set_iter *iter,
4415
- struct nft_set_elem *elem)
4630
+static int nft_setelem_data_validate(const struct nft_ctx *ctx,
4631
+ struct nft_set *set,
4632
+ struct nft_set_elem *elem)
44164633 {
44174634 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
44184635 enum nft_registers dreg;
....@@ -4424,14 +4641,19 @@
44244641 set->dlen);
44254642 }
44264643
4644
+static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
4645
+ struct nft_set *set,
4646
+ const struct nft_set_iter *iter,
4647
+ struct nft_set_elem *elem)
4648
+{
4649
+ return nft_setelem_data_validate(ctx, set, elem);
4650
+}
4651
+
44274652 int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
44284653 struct nft_set_binding *binding)
44294654 {
44304655 struct nft_set_binding *i;
44314656 struct nft_set_iter iter;
4432
-
4433
- if (set->use == UINT_MAX)
4434
- return -EOVERFLOW;
44354657
44364658 if (!list_empty(&set->bindings) && nft_set_is_anonymous(set))
44374659 return -EBUSY;
....@@ -4457,10 +4679,12 @@
44574679 return iter.err;
44584680 }
44594681 bind:
4682
+ if (!nft_use_inc(&set->use))
4683
+ return -EMFILE;
4684
+
44604685 binding->chain = ctx->chain;
44614686 list_add_tail_rcu(&binding->list, &set->bindings);
44624687 nft_set_trans_bind(ctx, set);
4463
- set->use++;
44644688
44654689 return 0;
44664690 }
....@@ -4479,17 +4703,74 @@
44794703 }
44804704 }
44814705
4706
+static void nft_setelem_data_activate(const struct net *net,
4707
+ const struct nft_set *set,
4708
+ struct nft_set_elem *elem);
4709
+
4710
+static int nft_mapelem_activate(const struct nft_ctx *ctx,
4711
+ struct nft_set *set,
4712
+ const struct nft_set_iter *iter,
4713
+ struct nft_set_elem *elem)
4714
+{
4715
+ nft_setelem_data_activate(ctx->net, set, elem);
4716
+
4717
+ return 0;
4718
+}
4719
+
4720
+static void nft_map_activate(const struct nft_ctx *ctx, struct nft_set *set)
4721
+{
4722
+ struct nft_set_iter iter = {
4723
+ .genmask = nft_genmask_next(ctx->net),
4724
+ .fn = nft_mapelem_activate,
4725
+ };
4726
+
4727
+ set->ops->walk(ctx, set, &iter);
4728
+ WARN_ON_ONCE(iter.err);
4729
+}
4730
+
4731
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
4732
+{
4733
+ if (nft_set_is_anonymous(set)) {
4734
+ if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
4735
+ nft_map_activate(ctx, set);
4736
+
4737
+ nft_clear(ctx->net, set);
4738
+ }
4739
+
4740
+ nft_use_inc_restore(&set->use);
4741
+}
4742
+EXPORT_SYMBOL_GPL(nf_tables_activate_set);
4743
+
44824744 void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
44834745 struct nft_set_binding *binding,
44844746 enum nft_trans_phase phase)
44854747 {
44864748 switch (phase) {
4749
+ case NFT_TRANS_PREPARE_ERROR:
4750
+ nft_set_trans_unbind(ctx, set);
4751
+ if (nft_set_is_anonymous(set))
4752
+ nft_deactivate_next(ctx->net, set);
4753
+ else
4754
+ list_del_rcu(&binding->list);
4755
+
4756
+ nft_use_dec(&set->use);
4757
+ break;
44874758 case NFT_TRANS_PREPARE:
4488
- set->use--;
4759
+ if (nft_set_is_anonymous(set)) {
4760
+ if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
4761
+ nft_map_deactivate(ctx, set);
4762
+
4763
+ nft_deactivate_next(ctx->net, set);
4764
+ }
4765
+ nft_use_dec(&set->use);
44894766 return;
44904767 case NFT_TRANS_ABORT:
44914768 case NFT_TRANS_RELEASE:
4492
- set->use--;
4769
+ if (nft_set_is_anonymous(set) &&
4770
+ set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
4771
+ nft_map_deactivate(ctx, set);
4772
+
4773
+ nft_use_dec(&set->use);
44934774 fallthrough;
44944775 default:
44954776 nf_tables_unbind_set(ctx, set, binding,
....@@ -4679,7 +4960,11 @@
46794960 const struct nft_set_iter *iter,
46804961 struct nft_set_elem *elem)
46814962 {
4963
+ const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
46824964 struct nft_set_dump_args *args;
4965
+
4966
+ if (nft_set_elem_expired(ext))
4967
+ return 0;
46834968
46844969 args = container_of(iter, struct nft_set_dump_args, iter);
46854970 return nf_tables_fill_setelem(args->skb, set, elem);
....@@ -4694,6 +4979,7 @@
46944979 {
46954980 struct nft_set_dump_ctx *dump_ctx = cb->data;
46964981 struct net *net = sock_net(skb->sk);
4982
+ struct nftables_pernet *nft_net;
46974983 struct nft_table *table;
46984984 struct nft_set *set;
46994985 struct nft_set_dump_args args;
....@@ -4704,7 +4990,8 @@
47044990 int event;
47054991
47064992 rcu_read_lock();
4707
- list_for_each_entry_rcu(table, &net->nft.tables, list) {
4993
+ nft_net = net_generic(net, nf_tables_net_id);
4994
+ list_for_each_entry_rcu(table, &nft_net->tables, list) {
47084995 if (dump_ctx->ctx.family != NFPROTO_UNSPEC &&
47094996 dump_ctx->ctx.family != table->family)
47104997 continue;
....@@ -4983,6 +5270,7 @@
49835270 const struct nft_set_elem *elem,
49845271 int event, u16 flags)
49855272 {
5273
+ struct nftables_pernet *nft_net;
49865274 struct net *net = ctx->net;
49875275 u32 portid = ctx->portid;
49885276 struct sk_buff *skb;
....@@ -5002,7 +5290,8 @@
50025290 goto err;
50035291 }
50045292
5005
- nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
5293
+ nft_net = net_generic(net, nf_tables_net_id);
5294
+ nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
50065295 return;
50075296 err:
50085297 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
....@@ -5091,6 +5380,7 @@
50915380 }
50925381 }
50935382
5383
+/* Drop references and destroy. Called from gc, dynset and abort path. */
50945384 void nft_set_elem_destroy(const struct nft_set *set, void *elem,
50955385 bool destroy_expr)
50965386 {
....@@ -5107,16 +5397,16 @@
51075397 nft_set_elem_expr_destroy(&ctx, nft_set_ext_expr(ext));
51085398
51095399 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
5110
- (*nft_set_ext_obj(ext))->use--;
5400
+ nft_use_dec(&(*nft_set_ext_obj(ext))->use);
51115401 kfree(elem);
51125402 }
51135403 EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
51145404
5115
-/* Only called from commit path, nft_set_elem_deactivate() already deals with
5116
- * the refcounting from the preparation phase.
5405
+/* Destroy element. References have been already dropped in the preparation
5406
+ * path via nft_setelem_data_deactivate().
51175407 */
5118
-static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
5119
- const struct nft_set *set, void *elem)
5408
+void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
5409
+ const struct nft_set *set, void *elem)
51205410 {
51215411 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
51225412
....@@ -5281,8 +5571,16 @@
52815571 set->objtype, genmask);
52825572 if (IS_ERR(obj)) {
52835573 err = PTR_ERR(obj);
5574
+ obj = NULL;
52845575 goto err_parse_key_end;
52855576 }
5577
+
5578
+ if (!nft_use_inc(&obj->use)) {
5579
+ err = -EMFILE;
5580
+ obj = NULL;
5581
+ goto err_parse_key_end;
5582
+ }
5583
+
52865584 nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
52875585 }
52885586
....@@ -5347,10 +5645,8 @@
53475645 udata->len = ulen - 1;
53485646 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
53495647 }
5350
- if (obj) {
5648
+ if (obj)
53515649 *nft_set_ext_obj(ext) = obj;
5352
- obj->use++;
5353
- }
53545650
53555651 err = nft_set_elem_expr_setup(ctx, ext, expr);
53565652 if (err < 0)
....@@ -5363,7 +5659,8 @@
53635659 goto err_elem_expr;
53645660 }
53655661
5366
- ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
5662
+ ext->genmask = nft_genmask_cur(ctx->net);
5663
+
53675664 err = set->ops->insert(ctx->net, set, &elem, &ext2);
53685665 if (err) {
53695666 if (err == -EEXIST) {
....@@ -5398,7 +5695,7 @@
53985695 }
53995696
54005697 nft_trans_elem(trans) = elem;
5401
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
5698
+ nft_trans_commit_list_add_tail(ctx->net, trans);
54025699 return 0;
54035700
54045701 err_set_full:
....@@ -5406,14 +5703,14 @@
54065703 err_element_clash:
54075704 kfree(trans);
54085705 err_elem_expr:
5409
- if (obj)
5410
- obj->use--;
5411
-
54125706 nf_tables_set_elem_destroy(ctx, set, elem.priv);
54135707 err_parse_data:
54145708 if (nla[NFTA_SET_ELEM_DATA] != NULL)
54155709 nft_data_release(&elem.data.val, desc.type);
54165710 err_parse_key_end:
5711
+ if (obj)
5712
+ nft_use_dec_restore(&obj->use);
5713
+
54175714 nft_data_release(&elem.key_end.val, NFT_DATA_VALUE);
54185715 err_parse_key:
54195716 nft_data_release(&elem.key.val, NFT_DATA_VALUE);
....@@ -5429,6 +5726,7 @@
54295726 const struct nlattr * const nla[],
54305727 struct netlink_ext_ack *extack)
54315728 {
5729
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
54325730 u8 genmask = nft_genmask_next(net);
54335731 const struct nlattr *attr;
54345732 struct nft_set *set;
....@@ -5448,7 +5746,8 @@
54485746 if (IS_ERR(set))
54495747 return PTR_ERR(set);
54505748
5451
- if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
5749
+ if (!list_empty(&set->bindings) &&
5750
+ (set->flags & (NFT_SET_CONSTANT | NFT_SET_ANONYMOUS)))
54525751 return -EBUSY;
54535752
54545753 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
....@@ -5457,7 +5756,7 @@
54575756 return err;
54585757 }
54595758
5460
- if (net->nft.validate_state == NFT_VALIDATE_DO)
5759
+ if (nft_net->validate_state == NFT_VALIDATE_DO)
54615760 return nft_table_validate(net, ctx.table);
54625761
54635762 return 0;
....@@ -5477,50 +5776,40 @@
54775776 void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
54785777 {
54795778 struct nft_chain *chain;
5480
- struct nft_rule *rule;
54815779
54825780 if (type == NFT_DATA_VERDICT) {
54835781 switch (data->verdict.code) {
54845782 case NFT_JUMP:
54855783 case NFT_GOTO:
54865784 chain = data->verdict.chain;
5487
- chain->use++;
5488
-
5489
- if (!nft_chain_is_bound(chain))
5490
- break;
5491
-
5492
- chain->table->use++;
5493
- list_for_each_entry(rule, &chain->rules, list)
5494
- chain->use++;
5495
-
5496
- nft_chain_add(chain->table, chain);
5785
+ nft_use_inc_restore(&chain->use);
54975786 break;
54985787 }
54995788 }
55005789 }
55015790
5502
-static void nft_set_elem_activate(const struct net *net,
5503
- const struct nft_set *set,
5504
- struct nft_set_elem *elem)
5791
+static void nft_setelem_data_activate(const struct net *net,
5792
+ const struct nft_set *set,
5793
+ struct nft_set_elem *elem)
55055794 {
55065795 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
55075796
55085797 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
55095798 nft_data_hold(nft_set_ext_data(ext), set->dtype);
55105799 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
5511
- (*nft_set_ext_obj(ext))->use++;
5800
+ nft_use_inc_restore(&(*nft_set_ext_obj(ext))->use);
55125801 }
55135802
5514
-static void nft_set_elem_deactivate(const struct net *net,
5515
- const struct nft_set *set,
5516
- struct nft_set_elem *elem)
5803
+void nft_setelem_data_deactivate(const struct net *net,
5804
+ const struct nft_set *set,
5805
+ struct nft_set_elem *elem)
55175806 {
55185807 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
55195808
55205809 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
55215810 nft_data_release(nft_set_ext_data(ext), set->dtype);
55225811 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
5523
- (*nft_set_ext_obj(ext))->use--;
5812
+ nft_use_dec(&(*nft_set_ext_obj(ext))->use);
55245813 }
55255814
55265815 static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
....@@ -5590,10 +5879,10 @@
55905879 kfree(elem.priv);
55915880 elem.priv = priv;
55925881
5593
- nft_set_elem_deactivate(ctx->net, set, &elem);
5882
+ nft_setelem_data_deactivate(ctx->net, set, &elem);
55945883
55955884 nft_trans_elem(trans) = elem;
5596
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
5885
+ nft_trans_commit_list_add_tail(ctx->net, trans);
55975886 return 0;
55985887
55995888 fail_ops:
....@@ -5624,10 +5913,10 @@
56245913 }
56255914 set->ndeact++;
56265915
5627
- nft_set_elem_deactivate(ctx->net, set, elem);
5916
+ nft_setelem_data_deactivate(ctx->net, set, elem);
56285917 nft_trans_elem_set(trans) = set;
56295918 nft_trans_elem(trans) = *elem;
5630
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
5919
+ nft_trans_commit_list_add_tail(ctx->net, trans);
56315920
56325921 return 0;
56335922 err1:
....@@ -5654,7 +5943,11 @@
56545943 set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
56555944 if (IS_ERR(set))
56565945 return PTR_ERR(set);
5657
- if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
5946
+
5947
+ if (nft_set_is_anonymous(set))
5948
+ return -EOPNOTSUPP;
5949
+
5950
+ if (!list_empty(&set->bindings) && (set->flags & NFT_SET_CONSTANT))
56585951 return -EBUSY;
56595952
56605953 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
....@@ -5675,29 +5968,6 @@
56755968 set->ndeact++;
56765969 }
56775970 return err;
5678
-}
5679
-
5680
-void nft_set_gc_batch_release(struct rcu_head *rcu)
5681
-{
5682
- struct nft_set_gc_batch *gcb;
5683
- unsigned int i;
5684
-
5685
- gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
5686
- for (i = 0; i < gcb->head.cnt; i++)
5687
- nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
5688
- kfree(gcb);
5689
-}
5690
-
5691
-struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
5692
- gfp_t gfp)
5693
-{
5694
- struct nft_set_gc_batch *gcb;
5695
-
5696
- gcb = kzalloc(sizeof(*gcb), gfp);
5697
- if (gcb == NULL)
5698
- return gcb;
5699
- gcb->head.set = set;
5700
- return gcb;
57015971 }
57025972
57035973 /*
....@@ -5924,7 +6194,7 @@
59246194 nft_trans_obj(trans) = obj;
59256195 nft_trans_obj_update(trans) = true;
59266196 nft_trans_obj_newobj(trans) = newobj;
5927
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
6197
+ nft_trans_commit_list_add_tail(ctx->net, trans);
59286198
59296199 return 0;
59306200
....@@ -5985,9 +6255,14 @@
59856255
59866256 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
59876257
6258
+ if (!nft_use_inc(&table->use))
6259
+ return -EMFILE;
6260
+
59886261 type = nft_obj_type_get(net, objtype);
5989
- if (IS_ERR(type))
5990
- return PTR_ERR(type);
6262
+ if (IS_ERR(type)) {
6263
+ err = PTR_ERR(type);
6264
+ goto err_type;
6265
+ }
59916266
59926267 obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
59936268 if (IS_ERR(obj)) {
....@@ -6021,7 +6296,7 @@
60216296 goto err_obj_ht;
60226297
60236298 list_add_tail_rcu(&obj->list, &table->objects);
6024
- table->use++;
6299
+
60256300 return 0;
60266301 err_obj_ht:
60276302 /* queued in transaction log */
....@@ -6037,6 +6312,9 @@
60376312 kfree(obj);
60386313 err_init:
60396314 module_put(type->owner);
6315
+err_type:
6316
+ nft_use_dec_restore(&table->use);
6317
+
60406318 return err;
60416319 }
60426320
....@@ -6087,6 +6365,7 @@
60876365 struct nft_obj_filter *filter = cb->data;
60886366 struct net *net = sock_net(skb->sk);
60896367 int family = nfmsg->nfgen_family;
6368
+ struct nftables_pernet *nft_net;
60906369 struct nft_object *obj;
60916370 bool reset = false;
60926371
....@@ -6094,9 +6373,10 @@
60946373 reset = true;
60956374
60966375 rcu_read_lock();
6097
- cb->seq = net->nft.base_seq;
6376
+ nft_net = net_generic(net, nf_tables_net_id);
6377
+ cb->seq = nft_net->base_seq;
60986378
6099
- list_for_each_entry_rcu(table, &net->nft.tables, list) {
6379
+ list_for_each_entry_rcu(table, &nft_net->tables, list) {
61006380 if (family != NFPROTO_UNSPEC && family != table->family)
61016381 continue;
61026382
....@@ -6119,7 +6399,7 @@
61196399 char *buf = kasprintf(GFP_ATOMIC,
61206400 "%s:%u",
61216401 table->name,
6122
- net->nft.base_seq);
6402
+ nft_net->base_seq);
61236403
61246404 audit_log_nfcfg(buf,
61256405 family,
....@@ -6240,8 +6520,11 @@
62406520 reset = true;
62416521
62426522 if (reset) {
6243
- char *buf = kasprintf(GFP_ATOMIC, "%s:%u",
6244
- table->name, net->nft.base_seq);
6523
+ const struct nftables_pernet *nft_net;
6524
+ char *buf;
6525
+
6526
+ nft_net = net_generic(net, nf_tables_net_id);
6527
+ buf = kasprintf(GFP_ATOMIC, "%s:%u", table->name, nft_net->base_seq);
62456528
62466529 audit_log_nfcfg(buf,
62476530 family,
....@@ -6326,10 +6609,11 @@
63266609 struct nft_object *obj, u32 portid, u32 seq, int event,
63276610 int family, int report, gfp_t gfp)
63286611 {
6612
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
63296613 struct sk_buff *skb;
63306614 int err;
63316615 char *buf = kasprintf(gfp, "%s:%u",
6332
- table->name, net->nft.base_seq);
6616
+ table->name, nft_net->base_seq);
63336617
63346618 audit_log_nfcfg(buf,
63356619 family,
....@@ -6355,7 +6639,7 @@
63556639 goto err;
63566640 }
63576641
6358
- nft_notify_enqueue(skb, report, &net->nft.notify_list);
6642
+ nft_notify_enqueue(skb, report, &nft_net->notify_list);
63596643 return;
63606644 err:
63616645 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
....@@ -6417,10 +6701,11 @@
64176701 enum nft_trans_phase phase)
64186702 {
64196703 switch (phase) {
6704
+ case NFT_TRANS_PREPARE_ERROR:
64206705 case NFT_TRANS_PREPARE:
64216706 case NFT_TRANS_ABORT:
64226707 case NFT_TRANS_RELEASE:
6423
- flowtable->use--;
6708
+ nft_use_dec(&flowtable->use);
64246709 fallthrough;
64256710 default:
64266711 return;
....@@ -6560,13 +6845,25 @@
65606845 FLOW_BLOCK_UNBIND);
65616846 }
65626847
6848
+static void __nft_unregister_flowtable_net_hooks(struct net *net,
6849
+ struct list_head *hook_list,
6850
+ bool release_netdev)
6851
+{
6852
+ struct nft_hook *hook, *next;
6853
+
6854
+ list_for_each_entry_safe(hook, next, hook_list, list) {
6855
+ nf_unregister_net_hook(net, &hook->ops);
6856
+ if (release_netdev) {
6857
+ list_del(&hook->list);
6858
+ kfree_rcu(hook, rcu);
6859
+ }
6860
+ }
6861
+}
6862
+
65636863 static void nft_unregister_flowtable_net_hooks(struct net *net,
65646864 struct list_head *hook_list)
65656865 {
6566
- struct nft_hook *hook;
6567
-
6568
- list_for_each_entry(hook, hook_list, list)
6569
- nf_unregister_net_hook(net, &hook->ops);
6866
+ __nft_unregister_flowtable_net_hooks(net, hook_list, false);
65706867 }
65716868
65726869 static int nft_register_flowtable_net_hooks(struct net *net,
....@@ -6691,7 +6988,7 @@
66916988 INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
66926989 list_splice(&flowtable_hook.list, &nft_trans_flowtable_hooks(trans));
66936990
6694
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
6991
+ nft_trans_commit_list_add_tail(ctx->net, trans);
66956992
66966993 return 0;
66976994
....@@ -6757,9 +7054,14 @@
67577054
67587055 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
67597056
7057
+ if (!nft_use_inc(&table->use))
7058
+ return -EMFILE;
7059
+
67607060 flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
6761
- if (!flowtable)
6762
- return -ENOMEM;
7061
+ if (!flowtable) {
7062
+ err = -ENOMEM;
7063
+ goto flowtable_alloc;
7064
+ }
67637065
67647066 flowtable->table = table;
67657067 flowtable->handle = nf_tables_alloc_handle(table);
....@@ -6814,7 +7116,6 @@
68147116 goto err5;
68157117
68167118 list_add_tail_rcu(&flowtable->list, &table->flowtables);
6817
- table->use++;
68187119
68197120 return 0;
68207121 err5:
....@@ -6831,6 +7132,9 @@
68317132 kfree(flowtable->name);
68327133 err1:
68337134 kfree(flowtable);
7135
+flowtable_alloc:
7136
+ nft_use_dec_restore(&table->use);
7137
+
68347138 return err;
68357139 }
68367140
....@@ -6881,7 +7185,7 @@
68817185 list_splice(&flowtable_del_list, &nft_trans_flowtable_hooks(trans));
68827186 nft_flowtable_hook_release(&flowtable_hook);
68837187
6884
- list_add_tail(&trans->list, &ctx->net->nft.commit_list);
7188
+ nft_trans_commit_list_add_tail(ctx->net, trans);
68857189
68867190 return 0;
68877191
....@@ -7007,12 +7311,14 @@
70077311 struct net *net = sock_net(skb->sk);
70087312 int family = nfmsg->nfgen_family;
70097313 struct nft_flowtable *flowtable;
7314
+ struct nftables_pernet *nft_net;
70107315 const struct nft_table *table;
70117316
70127317 rcu_read_lock();
7013
- cb->seq = net->nft.base_seq;
7318
+ nft_net = net_generic(net, nf_tables_net_id);
7319
+ cb->seq = nft_net->base_seq;
70147320
7015
- list_for_each_entry_rcu(table, &net->nft.tables, list) {
7321
+ list_for_each_entry_rcu(table, &nft_net->tables, list) {
70167322 if (family != NFPROTO_UNSPEC && family != table->family)
70177323 continue;
70187324
....@@ -7147,6 +7453,7 @@
71477453 struct list_head *hook_list,
71487454 int event)
71497455 {
7456
+ struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
71507457 struct sk_buff *skb;
71517458 int err;
71527459
....@@ -7166,7 +7473,7 @@
71667473 goto err;
71677474 }
71687475
7169
- nft_notify_enqueue(skb, ctx->report, &ctx->net->nft.notify_list);
7476
+ nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
71707477 return;
71717478 err:
71727479 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
....@@ -7191,6 +7498,7 @@
71917498 static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
71927499 u32 portid, u32 seq)
71937500 {
7501
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
71947502 struct nlmsghdr *nlh;
71957503 char buf[TASK_COMM_LEN];
71967504 int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN);
....@@ -7200,7 +7508,7 @@
72007508 if (!nlh)
72017509 goto nla_put_failure;
72027510
7203
- if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) ||
7511
+ if (nla_put_be32(skb, NFTA_GEN_ID, htonl(nft_net->base_seq)) ||
72047512 nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
72057513 nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
72067514 goto nla_put_failure;
....@@ -7235,6 +7543,7 @@
72357543 {
72367544 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
72377545 struct nft_flowtable *flowtable;
7546
+ struct nftables_pernet *nft_net;
72387547 struct nft_table *table;
72397548 struct net *net;
72407549
....@@ -7242,13 +7551,14 @@
72427551 return 0;
72437552
72447553 net = dev_net(dev);
7245
- mutex_lock(&net->nft.commit_mutex);
7246
- list_for_each_entry(table, &net->nft.tables, list) {
7554
+ nft_net = net_generic(net, nf_tables_net_id);
7555
+ mutex_lock(&nft_net->commit_mutex);
7556
+ list_for_each_entry(table, &nft_net->tables, list) {
72477557 list_for_each_entry(flowtable, &table->flowtables, list) {
72487558 nft_flowtable_event(event, dev, flowtable);
72497559 }
72507560 }
7251
- mutex_unlock(&net->nft.commit_mutex);
7561
+ mutex_unlock(&nft_net->commit_mutex);
72527562
72537563 return NOTIFY_DONE;
72547564 }
....@@ -7429,19 +7739,22 @@
74297739
74307740 static int nf_tables_validate(struct net *net)
74317741 {
7742
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
74327743 struct nft_table *table;
74337744
7434
- switch (net->nft.validate_state) {
7745
+ switch (nft_net->validate_state) {
74357746 case NFT_VALIDATE_SKIP:
74367747 break;
74377748 case NFT_VALIDATE_NEED:
74387749 nft_validate_state_update(net, NFT_VALIDATE_DO);
74397750 fallthrough;
74407751 case NFT_VALIDATE_DO:
7441
- list_for_each_entry(table, &net->nft.tables, list) {
7752
+ list_for_each_entry(table, &nft_net->tables, list) {
74427753 if (nft_table_validate(net, table) < 0)
74437754 return -EAGAIN;
74447755 }
7756
+
7757
+ nft_validate_state_update(net, NFT_VALIDATE_SKIP);
74457758 break;
74467759 }
74477760
....@@ -7569,7 +7882,7 @@
75697882 synchronize_rcu();
75707883
75717884 list_for_each_entry_safe(trans, next, &head, list) {
7572
- list_del(&trans->list);
7885
+ nft_trans_list_del(trans);
75737886 nft_commit_release(trans);
75747887 }
75757888 }
....@@ -7613,9 +7926,10 @@
76137926
76147927 static void nf_tables_commit_chain_prepare_cancel(struct net *net)
76157928 {
7929
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
76167930 struct nft_trans *trans, *next;
76177931
7618
- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
7932
+ list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
76197933 struct nft_chain *chain = trans->ctx.chain;
76207934
76217935 if (trans->msg_type == NFT_MSG_NEWRULE ||
....@@ -7711,12 +8025,197 @@
77118025 list_del_rcu(&chain->list);
77128026 }
77138027
8028
+static void nft_trans_gc_setelem_remove(struct nft_ctx *ctx,
8029
+ struct nft_trans_gc *trans)
8030
+{
8031
+ void **priv = trans->priv;
8032
+ unsigned int i;
8033
+
8034
+ for (i = 0; i < trans->count; i++) {
8035
+ struct nft_set_elem elem = {
8036
+ .priv = priv[i],
8037
+ };
8038
+
8039
+ nft_setelem_data_deactivate(ctx->net, trans->set, &elem);
8040
+ trans->set->ops->remove(trans->net, trans->set, &elem);
8041
+ }
8042
+}
8043
+
8044
+void nft_trans_gc_destroy(struct nft_trans_gc *trans)
8045
+{
8046
+ nft_set_put(trans->set);
8047
+ put_net(trans->net);
8048
+ kfree(trans);
8049
+}
8050
+
8051
+static void nft_trans_gc_trans_free(struct rcu_head *rcu)
8052
+{
8053
+ struct nft_set_elem elem = {};
8054
+ struct nft_trans_gc *trans;
8055
+ struct nft_ctx ctx = {};
8056
+ unsigned int i;
8057
+
8058
+ trans = container_of(rcu, struct nft_trans_gc, rcu);
8059
+ ctx.net = read_pnet(&trans->set->net);
8060
+
8061
+ for (i = 0; i < trans->count; i++) {
8062
+ elem.priv = trans->priv[i];
8063
+ atomic_dec(&trans->set->nelems);
8064
+
8065
+ nf_tables_set_elem_destroy(&ctx, trans->set, elem.priv);
8066
+ }
8067
+
8068
+ nft_trans_gc_destroy(trans);
8069
+}
8070
+
8071
+static bool nft_trans_gc_work_done(struct nft_trans_gc *trans)
8072
+{
8073
+ struct nftables_pernet *nft_net;
8074
+ struct nft_ctx ctx = {};
8075
+
8076
+ nft_net = net_generic(trans->net, nf_tables_net_id);
8077
+
8078
+ mutex_lock(&nft_net->commit_mutex);
8079
+
8080
+ /* Check for race with transaction, otherwise this batch refers to
8081
+ * stale objects that might not be there anymore. Skip transaction if
8082
+ * set has been destroyed from control plane transaction in case gc
8083
+ * worker loses race.
8084
+ */
8085
+ if (READ_ONCE(nft_net->gc_seq) != trans->seq || trans->set->dead) {
8086
+ mutex_unlock(&nft_net->commit_mutex);
8087
+ return false;
8088
+ }
8089
+
8090
+ ctx.net = trans->net;
8091
+ ctx.table = trans->set->table;
8092
+
8093
+ nft_trans_gc_setelem_remove(&ctx, trans);
8094
+ mutex_unlock(&nft_net->commit_mutex);
8095
+
8096
+ return true;
8097
+}
8098
+
8099
+static void nft_trans_gc_work(struct work_struct *work)
8100
+{
8101
+ struct nft_trans_gc *trans, *next;
8102
+ LIST_HEAD(trans_gc_list);
8103
+
8104
+ spin_lock(&nf_tables_gc_list_lock);
8105
+ list_splice_init(&nf_tables_gc_list, &trans_gc_list);
8106
+ spin_unlock(&nf_tables_gc_list_lock);
8107
+
8108
+ list_for_each_entry_safe(trans, next, &trans_gc_list, list) {
8109
+ list_del(&trans->list);
8110
+ if (!nft_trans_gc_work_done(trans)) {
8111
+ nft_trans_gc_destroy(trans);
8112
+ continue;
8113
+ }
8114
+ call_rcu(&trans->rcu, nft_trans_gc_trans_free);
8115
+ }
8116
+}
8117
+
8118
+struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set,
8119
+ unsigned int gc_seq, gfp_t gfp)
8120
+{
8121
+ struct net *net = read_pnet(&set->net);
8122
+ struct nft_trans_gc *trans;
8123
+
8124
+ trans = kzalloc(sizeof(*trans), gfp);
8125
+ if (!trans)
8126
+ return NULL;
8127
+
8128
+ trans->net = maybe_get_net(net);
8129
+ if (!trans->net) {
8130
+ kfree(trans);
8131
+ return NULL;
8132
+ }
8133
+
8134
+ refcount_inc(&set->refs);
8135
+ trans->set = set;
8136
+ trans->seq = gc_seq;
8137
+
8138
+ return trans;
8139
+}
8140
+
8141
+void nft_trans_gc_elem_add(struct nft_trans_gc *trans, void *priv)
8142
+{
8143
+ trans->priv[trans->count++] = priv;
8144
+}
8145
+
8146
+static void nft_trans_gc_queue_work(struct nft_trans_gc *trans)
8147
+{
8148
+ spin_lock(&nf_tables_gc_list_lock);
8149
+ list_add_tail(&trans->list, &nf_tables_gc_list);
8150
+ spin_unlock(&nf_tables_gc_list_lock);
8151
+
8152
+ schedule_work(&trans_gc_work);
8153
+}
8154
+
8155
+static int nft_trans_gc_space(struct nft_trans_gc *trans)
8156
+{
8157
+ return NFT_TRANS_GC_BATCHCOUNT - trans->count;
8158
+}
8159
+
8160
+struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc,
8161
+ unsigned int gc_seq, gfp_t gfp)
8162
+{
8163
+ struct nft_set *set;
8164
+
8165
+ if (nft_trans_gc_space(gc))
8166
+ return gc;
8167
+
8168
+ set = gc->set;
8169
+ nft_trans_gc_queue_work(gc);
8170
+
8171
+ return nft_trans_gc_alloc(set, gc_seq, gfp);
8172
+}
8173
+
8174
+void nft_trans_gc_queue_async_done(struct nft_trans_gc *trans)
8175
+{
8176
+ if (trans->count == 0) {
8177
+ nft_trans_gc_destroy(trans);
8178
+ return;
8179
+ }
8180
+
8181
+ nft_trans_gc_queue_work(trans);
8182
+}
8183
+
8184
+struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp)
8185
+{
8186
+ struct nft_set *set;
8187
+
8188
+ if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net)))
8189
+ return NULL;
8190
+
8191
+ if (nft_trans_gc_space(gc))
8192
+ return gc;
8193
+
8194
+ set = gc->set;
8195
+ call_rcu(&gc->rcu, nft_trans_gc_trans_free);
8196
+
8197
+ return nft_trans_gc_alloc(set, 0, gfp);
8198
+}
8199
+
8200
+void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans)
8201
+{
8202
+ WARN_ON_ONCE(!lockdep_commit_lock_is_held(trans->net));
8203
+
8204
+ if (trans->count == 0) {
8205
+ nft_trans_gc_destroy(trans);
8206
+ return;
8207
+ }
8208
+
8209
+ call_rcu(&trans->rcu, nft_trans_gc_trans_free);
8210
+}
8211
+
77148212 static void nf_tables_module_autoload_cleanup(struct net *net)
77158213 {
8214
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
77168215 struct nft_module_request *req, *next;
77178216
7718
- WARN_ON_ONCE(!list_empty(&net->nft.commit_list));
7719
- list_for_each_entry_safe(req, next, &net->nft.module_list, list) {
8217
+ WARN_ON_ONCE(!list_empty(&nft_net->commit_list));
8218
+ list_for_each_entry_safe(req, next, &nft_net->module_list, list) {
77208219 WARN_ON_ONCE(!req->done);
77218220 list_del(&req->list);
77228221 kfree(req);
....@@ -7725,6 +8224,7 @@
77258224
77268225 static void nf_tables_commit_release(struct net *net)
77278226 {
8227
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
77288228 struct nft_trans *trans;
77298229
77308230 /* all side effects have to be made visible.
....@@ -7734,35 +8234,36 @@
77348234 * Memory reclaim happens asynchronously from work queue
77358235 * to prevent expensive synchronize_rcu() in commit phase.
77368236 */
7737
- if (list_empty(&net->nft.commit_list)) {
8237
+ if (list_empty(&nft_net->commit_list)) {
77388238 nf_tables_module_autoload_cleanup(net);
7739
- mutex_unlock(&net->nft.commit_mutex);
8239
+ mutex_unlock(&nft_net->commit_mutex);
77408240 return;
77418241 }
77428242
7743
- trans = list_last_entry(&net->nft.commit_list,
8243
+ trans = list_last_entry(&nft_net->commit_list,
77448244 struct nft_trans, list);
77458245 get_net(trans->ctx.net);
77468246 WARN_ON_ONCE(trans->put_net);
77478247
77488248 trans->put_net = true;
77498249 spin_lock(&nf_tables_destroy_list_lock);
7750
- list_splice_tail_init(&net->nft.commit_list, &nf_tables_destroy_list);
8250
+ list_splice_tail_init(&nft_net->commit_list, &nf_tables_destroy_list);
77518251 spin_unlock(&nf_tables_destroy_list_lock);
77528252
77538253 nf_tables_module_autoload_cleanup(net);
77548254 schedule_work(&trans_destroy_work);
77558255
7756
- mutex_unlock(&net->nft.commit_mutex);
8256
+ mutex_unlock(&nft_net->commit_mutex);
77578257 }
77588258
77598259 static void nft_commit_notify(struct net *net, u32 portid)
77608260 {
8261
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
77618262 struct sk_buff *batch_skb = NULL, *nskb, *skb;
77628263 unsigned char *data;
77638264 int len;
77648265
7765
- list_for_each_entry_safe(skb, nskb, &net->nft.notify_list, list) {
8266
+ list_for_each_entry_safe(skb, nskb, &nft_net->notify_list, list) {
77668267 if (!batch_skb) {
77678268 new_batch:
77688269 batch_skb = skb;
....@@ -7788,7 +8289,7 @@
77888289 NFT_CB(batch_skb).report, GFP_KERNEL);
77898290 }
77908291
7791
- WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
8292
+ WARN_ON_ONCE(!list_empty(&nft_net->notify_list));
77928293 }
77938294
77948295 static int nf_tables_commit_audit_alloc(struct list_head *adl,
....@@ -7852,18 +8353,71 @@
78528353 }
78538354 }
78548355
8356
+static void nft_set_commit_update(struct list_head *set_update_list)
8357
+{
8358
+ struct nft_set *set, *next;
8359
+
8360
+ list_for_each_entry_safe(set, next, set_update_list, pending_update) {
8361
+ list_del_init(&set->pending_update);
8362
+
8363
+ if (!set->ops->commit)
8364
+ continue;
8365
+
8366
+ set->ops->commit(set);
8367
+ }
8368
+}
8369
+
8370
+static unsigned int nft_gc_seq_begin(struct nftables_pernet *nft_net)
8371
+{
8372
+ unsigned int gc_seq;
8373
+
8374
+ /* Bump gc counter, it becomes odd, this is the busy mark. */
8375
+ gc_seq = READ_ONCE(nft_net->gc_seq);
8376
+ WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
8377
+
8378
+ return gc_seq;
8379
+}
8380
+
8381
+static void nft_gc_seq_end(struct nftables_pernet *nft_net, unsigned int gc_seq)
8382
+{
8383
+ WRITE_ONCE(nft_net->gc_seq, ++gc_seq);
8384
+}
8385
+
78558386 static int nf_tables_commit(struct net *net, struct sk_buff *skb)
78568387 {
8388
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
78578389 struct nft_trans *trans, *next;
8390
+ LIST_HEAD(set_update_list);
78588391 struct nft_trans_elem *te;
78598392 struct nft_chain *chain;
78608393 struct nft_table *table;
8394
+ unsigned int gc_seq;
78618395 LIST_HEAD(adl);
78628396 int err;
78638397
7864
- if (list_empty(&net->nft.commit_list)) {
7865
- mutex_unlock(&net->nft.commit_mutex);
8398
+ if (list_empty(&nft_net->commit_list)) {
8399
+ mutex_unlock(&nft_net->commit_mutex);
78668400 return 0;
8401
+ }
8402
+
8403
+ list_for_each_entry(trans, &nft_net->binding_list, binding_list) {
8404
+ switch (trans->msg_type) {
8405
+ case NFT_MSG_NEWSET:
8406
+ if (nft_set_is_anonymous(nft_trans_set(trans)) &&
8407
+ !nft_trans_set_bound(trans)) {
8408
+ pr_warn_once("nftables ruleset with unbound set\n");
8409
+ return -EINVAL;
8410
+ }
8411
+ break;
8412
+ case NFT_MSG_NEWCHAIN:
8413
+ if (!nft_trans_chain_update(trans) &&
8414
+ nft_chain_binding(nft_trans_chain(trans)) &&
8415
+ !nft_trans_chain_bound(trans)) {
8416
+ pr_warn_once("nftables ruleset with unbound chain\n");
8417
+ return -EINVAL;
8418
+ }
8419
+ break;
8420
+ }
78678421 }
78688422
78698423 /* 0. Validate ruleset, otherwise roll back for error reporting. */
....@@ -7875,7 +8429,7 @@
78758429 return err;
78768430
78778431 /* 1. Allocate space for next generation rules_gen_X[] */
7878
- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
8432
+ list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
78798433 int ret;
78808434
78818435 ret = nf_tables_commit_audit_alloc(&adl, trans->ctx.table);
....@@ -7898,7 +8452,7 @@
78988452 }
78998453
79008454 /* step 2. Make rules_gen_X visible to packet path */
7901
- list_for_each_entry(table, &net->nft.tables, list) {
8455
+ list_for_each_entry(table, &nft_net->tables, list) {
79028456 list_for_each_entry(chain, &table->chains, list)
79038457 nf_tables_commit_chain(net, chain);
79048458 }
....@@ -7907,12 +8461,15 @@
79078461 * Bump generation counter, invalidate any dump in progress.
79088462 * Cannot fail after this point.
79098463 */
7910
- while (++net->nft.base_seq == 0);
8464
+ while (++nft_net->base_seq == 0)
8465
+ ;
8466
+
8467
+ gc_seq = nft_gc_seq_begin(nft_net);
79118468
79128469 /* step 3. Start new generation, rules_gen_X now in use. */
79138470 net->nft.gencursor = nft_gencursor_next(net);
79148471
7915
- list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
8472
+ list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
79168473 nf_tables_commit_audit_collect(&adl, trans->ctx.table,
79178474 trans->msg_type);
79188475 switch (trans->msg_type) {
....@@ -7981,13 +8538,14 @@
79818538 */
79828539 if (nft_set_is_anonymous(nft_trans_set(trans)) &&
79838540 !list_empty(&nft_trans_set(trans)->bindings))
7984
- trans->ctx.table->use--;
8541
+ nft_use_dec(&trans->ctx.table->use);
79858542
79868543 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
79878544 NFT_MSG_NEWSET, GFP_KERNEL);
79888545 nft_trans_destroy(trans);
79898546 break;
79908547 case NFT_MSG_DELSET:
8548
+ nft_trans_set(trans)->dead = 1;
79918549 list_del_rcu(&nft_trans_set(trans)->list);
79928550 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
79938551 NFT_MSG_DELSET, GFP_KERNEL);
....@@ -7999,6 +8557,11 @@
79998557 nf_tables_setelem_notify(&trans->ctx, te->set,
80008558 &te->elem,
80018559 NFT_MSG_NEWSETELEM, 0);
8560
+ if (te->set->ops->commit &&
8561
+ list_empty(&te->set->pending_update)) {
8562
+ list_add_tail(&te->set->pending_update,
8563
+ &set_update_list);
8564
+ }
80028565 nft_trans_destroy(trans);
80038566 break;
80048567 case NFT_MSG_DELSETELEM:
....@@ -8010,6 +8573,11 @@
80108573 te->set->ops->remove(net, te->set, &te->elem);
80118574 atomic_dec(&te->set->nelems);
80128575 te->set->ndeact--;
8576
+ if (te->set->ops->commit &&
8577
+ list_empty(&te->set->pending_update)) {
8578
+ list_add_tail(&te->set->pending_update,
8579
+ &set_update_list);
8580
+ }
80138581 break;
80148582 case NFT_MSG_NEWOBJ:
80158583 if (nft_trans_obj_update(trans)) {
....@@ -8070,9 +8638,13 @@
80708638 }
80718639 }
80728640
8641
+ nft_set_commit_update(&set_update_list);
8642
+
80738643 nft_commit_notify(net, NETLINK_CB(skb).portid);
80748644 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
8075
- nf_tables_commit_audit_log(&adl, net->nft.base_seq);
8645
+ nf_tables_commit_audit_log(&adl, nft_net->base_seq);
8646
+
8647
+ nft_gc_seq_end(nft_net, gc_seq);
80768648 nf_tables_commit_release(net);
80778649
80788650 return 0;
....@@ -8080,17 +8652,18 @@
80808652
80818653 static void nf_tables_module_autoload(struct net *net)
80828654 {
8655
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
80838656 struct nft_module_request *req, *next;
80848657 LIST_HEAD(module_list);
80858658
8086
- list_splice_init(&net->nft.module_list, &module_list);
8087
- mutex_unlock(&net->nft.commit_mutex);
8659
+ list_splice_init(&nft_net->module_list, &module_list);
8660
+ mutex_unlock(&nft_net->commit_mutex);
80888661 list_for_each_entry_safe(req, next, &module_list, list) {
80898662 request_module("%s", req->module);
80908663 req->done = true;
80918664 }
8092
- mutex_lock(&net->nft.commit_mutex);
8093
- list_splice(&module_list, &net->nft.module_list);
8665
+ mutex_lock(&nft_net->commit_mutex);
8666
+ list_splice(&module_list, &nft_net->module_list);
80948667 }
80958668
80968669 static void nf_tables_abort_release(struct nft_trans *trans)
....@@ -8125,16 +8698,32 @@
81258698 kfree(trans);
81268699 }
81278700
8701
+static void nft_set_abort_update(struct list_head *set_update_list)
8702
+{
8703
+ struct nft_set *set, *next;
8704
+
8705
+ list_for_each_entry_safe(set, next, set_update_list, pending_update) {
8706
+ list_del_init(&set->pending_update);
8707
+
8708
+ if (!set->ops->abort)
8709
+ continue;
8710
+
8711
+ set->ops->abort(set);
8712
+ }
8713
+}
8714
+
81288715 static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
81298716 {
8717
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
81308718 struct nft_trans *trans, *next;
8719
+ LIST_HEAD(set_update_list);
81318720 struct nft_trans_elem *te;
81328721
81338722 if (action == NFNL_ABORT_VALIDATE &&
81348723 nf_tables_validate(net) < 0)
81358724 return -EAGAIN;
81368725
8137
- list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
8726
+ list_for_each_entry_safe_reverse(trans, next, &nft_net->commit_list,
81388727 list) {
81398728 switch (trans->msg_type) {
81408729 case NFT_MSG_NEWTABLE:
....@@ -8159,11 +8748,11 @@
81598748 kfree(nft_trans_chain_name(trans));
81608749 nft_trans_destroy(trans);
81618750 } else {
8162
- if (nft_chain_is_bound(trans->ctx.chain)) {
8751
+ if (nft_trans_chain_bound(trans)) {
81638752 nft_trans_destroy(trans);
81648753 break;
81658754 }
8166
- trans->ctx.table->use--;
8755
+ nft_use_dec_restore(&trans->ctx.table->use);
81678756 nft_chain_del(trans->ctx.chain);
81688757 nf_tables_unregister_hook(trans->ctx.net,
81698758 trans->ctx.table,
....@@ -8171,25 +8760,29 @@
81718760 }
81728761 break;
81738762 case NFT_MSG_DELCHAIN:
8174
- trans->ctx.table->use++;
8763
+ nft_use_inc_restore(&trans->ctx.table->use);
81758764 nft_clear(trans->ctx.net, trans->ctx.chain);
81768765 nft_trans_destroy(trans);
81778766 break;
81788767 case NFT_MSG_NEWRULE:
8179
- trans->ctx.chain->use--;
8768
+ if (nft_trans_rule_bound(trans)) {
8769
+ nft_trans_destroy(trans);
8770
+ break;
8771
+ }
8772
+ nft_use_dec_restore(&trans->ctx.chain->use);
81808773 list_del_rcu(&nft_trans_rule(trans)->list);
81818774 nft_rule_expr_deactivate(&trans->ctx,
81828775 nft_trans_rule(trans),
81838776 NFT_TRANS_ABORT);
81848777 break;
81858778 case NFT_MSG_DELRULE:
8186
- trans->ctx.chain->use++;
8779
+ nft_use_inc_restore(&trans->ctx.chain->use);
81878780 nft_clear(trans->ctx.net, nft_trans_rule(trans));
81888781 nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
81898782 nft_trans_destroy(trans);
81908783 break;
81918784 case NFT_MSG_NEWSET:
8192
- trans->ctx.table->use--;
8785
+ nft_use_dec_restore(&trans->ctx.table->use);
81938786 if (nft_trans_set_bound(trans)) {
81948787 nft_trans_destroy(trans);
81958788 break;
....@@ -8197,8 +8790,11 @@
81978790 list_del_rcu(&nft_trans_set(trans)->list);
81988791 break;
81998792 case NFT_MSG_DELSET:
8200
- trans->ctx.table->use++;
8793
+ nft_use_inc_restore(&trans->ctx.table->use);
82018794 nft_clear(trans->ctx.net, nft_trans_set(trans));
8795
+ if (nft_trans_set(trans)->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
8796
+ nft_map_activate(&trans->ctx, nft_trans_set(trans));
8797
+
82028798 nft_trans_destroy(trans);
82038799 break;
82048800 case NFT_MSG_NEWSETELEM:
....@@ -8209,14 +8805,25 @@
82098805 te = (struct nft_trans_elem *)trans->data;
82108806 te->set->ops->remove(net, te->set, &te->elem);
82118807 atomic_dec(&te->set->nelems);
8808
+
8809
+ if (te->set->ops->abort &&
8810
+ list_empty(&te->set->pending_update)) {
8811
+ list_add_tail(&te->set->pending_update,
8812
+ &set_update_list);
8813
+ }
82128814 break;
82138815 case NFT_MSG_DELSETELEM:
82148816 te = (struct nft_trans_elem *)trans->data;
82158817
8216
- nft_set_elem_activate(net, te->set, &te->elem);
8818
+ nft_setelem_data_activate(net, te->set, &te->elem);
82178819 te->set->ops->activate(net, te->set, &te->elem);
82188820 te->set->ndeact--;
82198821
8822
+ if (te->set->ops->abort &&
8823
+ list_empty(&te->set->pending_update)) {
8824
+ list_add_tail(&te->set->pending_update,
8825
+ &set_update_list);
8826
+ }
82208827 nft_trans_destroy(trans);
82218828 break;
82228829 case NFT_MSG_NEWOBJ:
....@@ -8224,12 +8831,12 @@
82248831 nft_obj_destroy(&trans->ctx, nft_trans_obj_newobj(trans));
82258832 nft_trans_destroy(trans);
82268833 } else {
8227
- trans->ctx.table->use--;
8834
+ nft_use_dec_restore(&trans->ctx.table->use);
82288835 nft_obj_del(nft_trans_obj(trans));
82298836 }
82308837 break;
82318838 case NFT_MSG_DELOBJ:
8232
- trans->ctx.table->use++;
8839
+ nft_use_inc_restore(&trans->ctx.table->use);
82338840 nft_clear(trans->ctx.net, nft_trans_obj(trans));
82348841 nft_trans_destroy(trans);
82358842 break;
....@@ -8238,7 +8845,7 @@
82388845 nft_unregister_flowtable_net_hooks(net,
82398846 &nft_trans_flowtable_hooks(trans));
82408847 } else {
8241
- trans->ctx.table->use--;
8848
+ nft_use_dec_restore(&trans->ctx.table->use);
82428849 list_del_rcu(&nft_trans_flowtable(trans)->list);
82438850 nft_unregister_flowtable_net_hooks(net,
82448851 &nft_trans_flowtable(trans)->hook_list);
....@@ -8249,7 +8856,7 @@
82498856 list_splice(&nft_trans_flowtable_hooks(trans),
82508857 &nft_trans_flowtable(trans)->hook_list);
82518858 } else {
8252
- trans->ctx.table->use++;
8859
+ nft_use_inc_restore(&trans->ctx.table->use);
82538860 nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
82548861 }
82558862 nft_trans_destroy(trans);
....@@ -8257,11 +8864,13 @@
82578864 }
82588865 }
82598866
8867
+ nft_set_abort_update(&set_update_list);
8868
+
82608869 synchronize_rcu();
82618870
82628871 list_for_each_entry_safe_reverse(trans, next,
8263
- &net->nft.commit_list, list) {
8264
- list_del(&trans->list);
8872
+ &nft_net->commit_list, list) {
8873
+ nft_trans_list_del(trans);
82658874 nf_tables_abort_release(trans);
82668875 }
82678876
....@@ -8273,30 +8882,32 @@
82738882 return 0;
82748883 }
82758884
8276
-static void nf_tables_cleanup(struct net *net)
8277
-{
8278
- nft_validate_state_update(net, NFT_VALIDATE_SKIP);
8279
-}
8280
-
82818885 static int nf_tables_abort(struct net *net, struct sk_buff *skb,
82828886 enum nfnl_abort_action action)
82838887 {
8284
- int ret = __nf_tables_abort(net, action);
8888
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
8889
+ unsigned int gc_seq;
8890
+ int ret;
82858891
8286
- mutex_unlock(&net->nft.commit_mutex);
8892
+ gc_seq = nft_gc_seq_begin(nft_net);
8893
+ ret = __nf_tables_abort(net, action);
8894
+ nft_gc_seq_end(nft_net, gc_seq);
8895
+
8896
+ mutex_unlock(&nft_net->commit_mutex);
82878897
82888898 return ret;
82898899 }
82908900
82918901 static bool nf_tables_valid_genid(struct net *net, u32 genid)
82928902 {
8903
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
82938904 bool genid_ok;
82948905
8295
- mutex_lock(&net->nft.commit_mutex);
8906
+ mutex_lock(&nft_net->commit_mutex);
82968907
8297
- genid_ok = genid == 0 || net->nft.base_seq == genid;
8908
+ genid_ok = genid == 0 || nft_net->base_seq == genid;
82988909 if (!genid_ok)
8299
- mutex_unlock(&net->nft.commit_mutex);
8910
+ mutex_unlock(&nft_net->commit_mutex);
83008911
83018912 /* else, commit mutex has to be released by commit or abort function */
83028913 return genid_ok;
....@@ -8309,7 +8920,6 @@
83098920 .cb = nf_tables_cb,
83108921 .commit = nf_tables_commit,
83118922 .abort = nf_tables_abort,
8312
- .cleanup = nf_tables_cleanup,
83138923 .valid_genid = nf_tables_valid_genid,
83148924 .owner = THIS_MODULE,
83158925 };
....@@ -8472,28 +9082,24 @@
84729082 }
84739083 EXPORT_SYMBOL_GPL(nft_parse_u32_check);
84749084
8475
-/**
8476
- * nft_parse_register - parse a register value from a netlink attribute
8477
- *
8478
- * @attr: netlink attribute
8479
- *
8480
- * Parse and translate a register value from a netlink attribute.
8481
- * Registers used to be 128 bit wide, these register numbers will be
8482
- * mapped to the corresponding 32 bit register numbers.
8483
- */
8484
-unsigned int nft_parse_register(const struct nlattr *attr)
9085
+static int nft_parse_register(const struct nlattr *attr, u32 *preg)
84859086 {
84869087 unsigned int reg;
84879088
84889089 reg = ntohl(nla_get_be32(attr));
84899090 switch (reg) {
84909091 case NFT_REG_VERDICT...NFT_REG_4:
8491
- return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
9092
+ *preg = reg * NFT_REG_SIZE / NFT_REG32_SIZE;
9093
+ break;
9094
+ case NFT_REG32_00...NFT_REG32_15:
9095
+ *preg = reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
9096
+ break;
84929097 default:
8493
- return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
9098
+ return -ERANGE;
84949099 }
9100
+
9101
+ return 0;
84959102 }
8496
-EXPORT_SYMBOL_GPL(nft_parse_register);
84979103
84989104 /**
84999105 * nft_dump_register - dump a register value to a netlink attribute
....@@ -8543,7 +9149,10 @@
85439149 u32 reg;
85449150 int err;
85459151
8546
- reg = nft_parse_register(attr);
9152
+ err = nft_parse_register(attr, &reg);
9153
+ if (err < 0)
9154
+ return err;
9155
+
85479156 err = nft_validate_register_load(reg, len);
85489157 if (err < 0)
85499158 return err;
....@@ -8612,7 +9221,10 @@
86129221 int err;
86139222 u32 reg;
86149223
8615
- reg = nft_parse_register(attr);
9224
+ err = nft_parse_register(attr, &reg);
9225
+ if (err < 0)
9226
+ return err;
9227
+
86169228 err = nft_validate_register_store(ctx, reg, data, type, len);
86179229 if (err < 0)
86189230 return err;
....@@ -8644,6 +9256,9 @@
86449256
86459257 if (!tb[NFTA_VERDICT_CODE])
86469258 return -EINVAL;
9259
+
9260
+ /* zero padding hole for memcmp */
9261
+ memset(data, 0, sizeof(*data));
86479262 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
86489263
86499264 switch (data->verdict.code) {
....@@ -8669,7 +9284,8 @@
86699284 genmask);
86709285 } else if (tb[NFTA_VERDICT_CHAIN_ID]) {
86719286 chain = nft_chain_lookup_byid(ctx->net, ctx->table,
8672
- tb[NFTA_VERDICT_CHAIN_ID]);
9287
+ tb[NFTA_VERDICT_CHAIN_ID],
9288
+ genmask);
86739289 if (IS_ERR(chain))
86749290 return PTR_ERR(chain);
86759291 } else {
....@@ -8685,8 +9301,9 @@
86859301 if (desc->flags & NFT_DATA_DESC_SETELEM &&
86869302 chain->flags & NFT_CHAIN_BINDING)
86879303 return -EINVAL;
9304
+ if (!nft_use_inc(&chain->use))
9305
+ return -EMFILE;
86889306
8689
- chain->use++;
86909307 data->verdict.chain = chain;
86919308 break;
86929309 }
....@@ -8699,22 +9316,12 @@
86999316 static void nft_verdict_uninit(const struct nft_data *data)
87009317 {
87019318 struct nft_chain *chain;
8702
- struct nft_rule *rule;
87039319
87049320 switch (data->verdict.code) {
87059321 case NFT_JUMP:
87069322 case NFT_GOTO:
87079323 chain = data->verdict.chain;
8708
- chain->use--;
8709
-
8710
- if (!nft_chain_is_bound(chain))
8711
- break;
8712
-
8713
- chain->table->use--;
8714
- list_for_each_entry(rule, &chain->rules, list)
8715
- chain->use--;
8716
-
8717
- nft_chain_del(chain);
9324
+ nft_use_dec(&chain->use);
87189325 break;
87199326 }
87209327 }
....@@ -8883,32 +9490,41 @@
88839490 nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
88849491 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
88859492 list_del(&rule->list);
8886
- ctx->chain->use--;
9493
+ nft_use_dec(&ctx->chain->use);
88879494 nf_tables_rule_release(ctx, rule);
88889495 }
88899496 nft_chain_del(ctx->chain);
8890
- ctx->table->use--;
9497
+ nft_use_dec(&ctx->table->use);
88919498 nf_tables_chain_destroy(ctx);
88929499
88939500 return 0;
88949501 }
88959502 EXPORT_SYMBOL_GPL(__nft_release_basechain);
88969503
8897
-static void __nft_release_hooks(struct net *net)
9504
+static void __nft_release_hook(struct net *net, struct nft_table *table)
88989505 {
8899
- struct nft_table *table;
9506
+ struct nft_flowtable *flowtable;
89009507 struct nft_chain *chain;
89019508
8902
- list_for_each_entry(table, &net->nft.tables, list) {
8903
- list_for_each_entry(chain, &table->chains, list)
8904
- nf_tables_unregister_hook(net, table, chain);
8905
- }
9509
+ list_for_each_entry(chain, &table->chains, list)
9510
+ __nf_tables_unregister_hook(net, table, chain, true);
9511
+ list_for_each_entry(flowtable, &table->flowtables, list)
9512
+ __nft_unregister_flowtable_net_hooks(net, &flowtable->hook_list,
9513
+ true);
89069514 }
89079515
8908
-static void __nft_release_tables(struct net *net)
9516
+static void __nft_release_hooks(struct net *net)
9517
+{
9518
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
9519
+ struct nft_table *table;
9520
+
9521
+ list_for_each_entry(table, &nft_net->tables, list)
9522
+ __nft_release_hook(net, table);
9523
+}
9524
+
9525
+static void __nft_release_table(struct net *net, struct nft_table *table)
89099526 {
89109527 struct nft_flowtable *flowtable, *nf;
8911
- struct nft_table *table, *nt;
89129528 struct nft_chain *chain, *nc;
89139529 struct nft_object *obj, *ne;
89149530 struct nft_rule *rule, *nr;
....@@ -8918,77 +9534,115 @@
89189534 .family = NFPROTO_NETDEV,
89199535 };
89209536
8921
- list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
8922
- ctx.family = table->family;
8923
- ctx.table = table;
8924
- list_for_each_entry(chain, &table->chains, list) {
8925
- ctx.chain = chain;
8926
- list_for_each_entry_safe(rule, nr, &chain->rules, list) {
8927
- list_del(&rule->list);
8928
- chain->use--;
8929
- nf_tables_rule_release(&ctx, rule);
8930
- }
9537
+ ctx.family = table->family;
9538
+ ctx.table = table;
9539
+ list_for_each_entry(chain, &table->chains, list) {
9540
+ if (nft_chain_binding(chain))
9541
+ continue;
9542
+
9543
+ ctx.chain = chain;
9544
+ list_for_each_entry_safe(rule, nr, &chain->rules, list) {
9545
+ list_del(&rule->list);
9546
+ nft_use_dec(&chain->use);
9547
+ nf_tables_rule_release(&ctx, rule);
89319548 }
8932
- list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
8933
- list_del(&flowtable->list);
8934
- table->use--;
8935
- nf_tables_flowtable_destroy(flowtable);
8936
- }
8937
- list_for_each_entry_safe(set, ns, &table->sets, list) {
8938
- list_del(&set->list);
8939
- table->use--;
8940
- nft_set_destroy(&ctx, set);
8941
- }
8942
- list_for_each_entry_safe(obj, ne, &table->objects, list) {
8943
- nft_obj_del(obj);
8944
- table->use--;
8945
- nft_obj_destroy(&ctx, obj);
8946
- }
8947
- list_for_each_entry_safe(chain, nc, &table->chains, list) {
8948
- ctx.chain = chain;
8949
- nft_chain_del(chain);
8950
- table->use--;
8951
- nf_tables_chain_destroy(&ctx);
8952
- }
8953
- list_del(&table->list);
8954
- nf_tables_table_destroy(&ctx);
89559549 }
9550
+ list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
9551
+ list_del(&flowtable->list);
9552
+ nft_use_dec(&table->use);
9553
+ nf_tables_flowtable_destroy(flowtable);
9554
+ }
9555
+ list_for_each_entry_safe(set, ns, &table->sets, list) {
9556
+ list_del(&set->list);
9557
+ nft_use_dec(&table->use);
9558
+ if (set->flags & (NFT_SET_MAP | NFT_SET_OBJECT))
9559
+ nft_map_deactivate(&ctx, set);
9560
+
9561
+ nft_set_destroy(&ctx, set);
9562
+ }
9563
+ list_for_each_entry_safe(obj, ne, &table->objects, list) {
9564
+ nft_obj_del(obj);
9565
+ nft_use_dec(&table->use);
9566
+ nft_obj_destroy(&ctx, obj);
9567
+ }
9568
+ list_for_each_entry_safe(chain, nc, &table->chains, list) {
9569
+ ctx.chain = chain;
9570
+ nft_chain_del(chain);
9571
+ nft_use_dec(&table->use);
9572
+ nf_tables_chain_destroy(&ctx);
9573
+ }
9574
+ list_del(&table->list);
9575
+ nf_tables_table_destroy(&ctx);
9576
+}
9577
+
9578
+static void __nft_release_tables(struct net *net)
9579
+{
9580
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
9581
+ struct nft_table *table, *nt;
9582
+
9583
+ list_for_each_entry_safe(table, nt, &nft_net->tables, list)
9584
+ __nft_release_table(net, table);
89569585 }
89579586
89589587 static int __net_init nf_tables_init_net(struct net *net)
89599588 {
8960
- INIT_LIST_HEAD(&net->nft.tables);
8961
- INIT_LIST_HEAD(&net->nft.commit_list);
8962
- INIT_LIST_HEAD(&net->nft.module_list);
8963
- INIT_LIST_HEAD(&net->nft.notify_list);
8964
- mutex_init(&net->nft.commit_mutex);
8965
- net->nft.base_seq = 1;
8966
- net->nft.validate_state = NFT_VALIDATE_SKIP;
9589
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
9590
+
9591
+ INIT_LIST_HEAD(&nft_net->tables);
9592
+ INIT_LIST_HEAD(&nft_net->commit_list);
9593
+ INIT_LIST_HEAD(&nft_net->binding_list);
9594
+ INIT_LIST_HEAD(&nft_net->module_list);
9595
+ INIT_LIST_HEAD(&nft_net->notify_list);
9596
+ mutex_init(&nft_net->commit_mutex);
9597
+ nft_net->base_seq = 1;
9598
+ nft_net->validate_state = NFT_VALIDATE_SKIP;
9599
+ nft_net->gc_seq = 0;
89679600
89689601 return 0;
89699602 }
89709603
89719604 static void __net_exit nf_tables_pre_exit_net(struct net *net)
89729605 {
9606
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
9607
+
9608
+ mutex_lock(&nft_net->commit_mutex);
89739609 __nft_release_hooks(net);
9610
+ mutex_unlock(&nft_net->commit_mutex);
89749611 }
89759612
89769613 static void __net_exit nf_tables_exit_net(struct net *net)
89779614 {
8978
- mutex_lock(&net->nft.commit_mutex);
8979
- if (!list_empty(&net->nft.commit_list))
9615
+ struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
9616
+ unsigned int gc_seq;
9617
+
9618
+ mutex_lock(&nft_net->commit_mutex);
9619
+
9620
+ gc_seq = nft_gc_seq_begin(nft_net);
9621
+
9622
+ if (!list_empty(&nft_net->commit_list))
89809623 __nf_tables_abort(net, NFNL_ABORT_NONE);
89819624 __nft_release_tables(net);
8982
- mutex_unlock(&net->nft.commit_mutex);
8983
- WARN_ON_ONCE(!list_empty(&net->nft.tables));
8984
- WARN_ON_ONCE(!list_empty(&net->nft.module_list));
8985
- WARN_ON_ONCE(!list_empty(&net->nft.notify_list));
9625
+
9626
+ nft_gc_seq_end(nft_net, gc_seq);
9627
+
9628
+ mutex_unlock(&nft_net->commit_mutex);
9629
+ WARN_ON_ONCE(!list_empty(&nft_net->tables));
9630
+ WARN_ON_ONCE(!list_empty(&nft_net->module_list));
9631
+ WARN_ON_ONCE(!list_empty(&nft_net->notify_list));
9632
+}
9633
+
9634
+static void nf_tables_exit_batch(struct list_head *net_exit_list)
9635
+{
9636
+ flush_work(&trans_gc_work);
89869637 }
89879638
89889639 static struct pernet_operations nf_tables_net_ops = {
89899640 .init = nf_tables_init_net,
89909641 .pre_exit = nf_tables_pre_exit_net,
89919642 .exit = nf_tables_exit_net,
9643
+ .exit_batch = nf_tables_exit_batch,
9644
+ .id = &nf_tables_net_id,
9645
+ .size = sizeof(struct nftables_pernet),
89929646 };
89939647
89949648 static int __init nf_tables_module_init(void)
....@@ -9051,6 +9705,7 @@
90519705 nft_chain_filter_fini();
90529706 nft_chain_route_fini();
90539707 unregister_pernet_subsys(&nf_tables_net_ops);
9708
+ cancel_work_sync(&trans_gc_work);
90549709 cancel_work_sync(&trans_destroy_work);
90559710 rcu_barrier();
90569711 rhltable_destroy(&nft_objname_ht);