netfilter: nf_log_syslog: Unset bridge logger in pernet exit
[linux-block.git] / net / netfilter / nf_tables_api.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
96518518 2/*
20a69341 3 * Copyright (c) 2007-2009 Patrick McHardy <kaber@trash.net>
96518518 4 *
96518518
PM
5 * Development of this code funded by Astaro AG (http://www.astaro.com/)
6 */
7
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/list.h>
11#include <linux/skbuff.h>
12#include <linux/netlink.h>
1ff75a3e 13#include <linux/vmalloc.h>
0eb71a9d 14#include <linux/rhashtable.h>
8e6cf365 15#include <linux/audit.h>
96518518
PM
16#include <linux/netfilter.h>
17#include <linux/netfilter/nfnetlink.h>
18#include <linux/netfilter/nf_tables.h>
3b49e2e9 19#include <net/netfilter/nf_flow_table.h>
96518518
PM
20#include <net/netfilter/nf_tables_core.h>
21#include <net/netfilter/nf_tables.h>
c9626a2c 22#include <net/netfilter/nf_tables_offload.h>
99633ab2 23#include <net/net_namespace.h>
0854db2a 24#include <net/netns/generic.h>
96518518
PM
25#include <net/sock.h>
26
9332d27d
FW
27#define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-"))
28
0854db2a
FW
29unsigned int nf_tables_net_id __read_mostly;
30
96518518 31static LIST_HEAD(nf_tables_expressions);
e5009240 32static LIST_HEAD(nf_tables_objects);
3b49e2e9 33static LIST_HEAD(nf_tables_flowtables);
0935d558
FW
34static LIST_HEAD(nf_tables_destroy_list);
35static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
3ecbfd65 36static u64 table_handle;
96518518 37
a654de8f
PNA
38enum {
39 NFT_VALIDATE_SKIP = 0,
40 NFT_VALIDATE_NEED,
41 NFT_VALIDATE_DO,
42};
43
4d44175a
FW
44static struct rhltable nft_objname_ht;
45
1b2470e5
FW
46static u32 nft_chain_hash(const void *data, u32 len, u32 seed);
47static u32 nft_chain_hash_obj(const void *data, u32 len, u32 seed);
48static int nft_chain_hash_cmp(struct rhashtable_compare_arg *, const void *);
49
4d44175a
FW
50static u32 nft_objname_hash(const void *data, u32 len, u32 seed);
51static u32 nft_objname_hash_obj(const void *data, u32 len, u32 seed);
52static int nft_objname_hash_cmp(struct rhashtable_compare_arg *, const void *);
53
1b2470e5
FW
54static const struct rhashtable_params nft_chain_ht_params = {
55 .head_offset = offsetof(struct nft_chain, rhlhead),
56 .key_offset = offsetof(struct nft_chain, name),
57 .hashfn = nft_chain_hash,
58 .obj_hashfn = nft_chain_hash_obj,
59 .obj_cmpfn = nft_chain_hash_cmp,
1b2470e5
FW
60 .automatic_shrinking = true,
61};
62
4d44175a
FW
63static const struct rhashtable_params nft_objname_ht_params = {
64 .head_offset = offsetof(struct nft_object, rhlhead),
65 .key_offset = offsetof(struct nft_object, key),
66 .hashfn = nft_objname_hash,
67 .obj_hashfn = nft_objname_hash_obj,
68 .obj_cmpfn = nft_objname_hash_cmp,
69 .automatic_shrinking = true,
70};
71
c520292f
RGB
72struct nft_audit_data {
73 struct nft_table *table;
74 int entries;
75 int op;
76 struct list_head list;
77};
78
79static const u8 nft2audit_op[NFT_MSG_MAX] = { // enum nf_tables_msg_types
80 [NFT_MSG_NEWTABLE] = AUDIT_NFT_OP_TABLE_REGISTER,
81 [NFT_MSG_GETTABLE] = AUDIT_NFT_OP_INVALID,
82 [NFT_MSG_DELTABLE] = AUDIT_NFT_OP_TABLE_UNREGISTER,
83 [NFT_MSG_NEWCHAIN] = AUDIT_NFT_OP_CHAIN_REGISTER,
84 [NFT_MSG_GETCHAIN] = AUDIT_NFT_OP_INVALID,
85 [NFT_MSG_DELCHAIN] = AUDIT_NFT_OP_CHAIN_UNREGISTER,
86 [NFT_MSG_NEWRULE] = AUDIT_NFT_OP_RULE_REGISTER,
87 [NFT_MSG_GETRULE] = AUDIT_NFT_OP_INVALID,
88 [NFT_MSG_DELRULE] = AUDIT_NFT_OP_RULE_UNREGISTER,
89 [NFT_MSG_NEWSET] = AUDIT_NFT_OP_SET_REGISTER,
90 [NFT_MSG_GETSET] = AUDIT_NFT_OP_INVALID,
91 [NFT_MSG_DELSET] = AUDIT_NFT_OP_SET_UNREGISTER,
92 [NFT_MSG_NEWSETELEM] = AUDIT_NFT_OP_SETELEM_REGISTER,
93 [NFT_MSG_GETSETELEM] = AUDIT_NFT_OP_INVALID,
94 [NFT_MSG_DELSETELEM] = AUDIT_NFT_OP_SETELEM_UNREGISTER,
95 [NFT_MSG_NEWGEN] = AUDIT_NFT_OP_GEN_REGISTER,
96 [NFT_MSG_GETGEN] = AUDIT_NFT_OP_INVALID,
97 [NFT_MSG_TRACE] = AUDIT_NFT_OP_INVALID,
98 [NFT_MSG_NEWOBJ] = AUDIT_NFT_OP_OBJ_REGISTER,
99 [NFT_MSG_GETOBJ] = AUDIT_NFT_OP_INVALID,
100 [NFT_MSG_DELOBJ] = AUDIT_NFT_OP_OBJ_UNREGISTER,
101 [NFT_MSG_GETOBJ_RESET] = AUDIT_NFT_OP_OBJ_RESET,
102 [NFT_MSG_NEWFLOWTABLE] = AUDIT_NFT_OP_FLOWTABLE_REGISTER,
103 [NFT_MSG_GETFLOWTABLE] = AUDIT_NFT_OP_INVALID,
104 [NFT_MSG_DELFLOWTABLE] = AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
105};
106
a654de8f
PNA
107static void nft_validate_state_update(struct net *net, u8 new_validate_state)
108{
0854db2a
FW
109 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
110
111 switch (nft_net->validate_state) {
a654de8f
PNA
112 case NFT_VALIDATE_SKIP:
113 WARN_ON_ONCE(new_validate_state == NFT_VALIDATE_DO);
114 break;
115 case NFT_VALIDATE_NEED:
116 break;
117 case NFT_VALIDATE_DO:
118 if (new_validate_state == NFT_VALIDATE_NEED)
119 return;
120 }
121
0854db2a 122 nft_net->validate_state = new_validate_state;
a654de8f 123}
0935d558
FW
124static void nf_tables_trans_destroy_work(struct work_struct *w);
125static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
a654de8f 126
7c95f6d8 127static void nft_ctx_init(struct nft_ctx *ctx,
633c9a84 128 struct net *net,
7c95f6d8
PNA
129 const struct sk_buff *skb,
130 const struct nlmsghdr *nlh,
36596dad 131 u8 family,
7c95f6d8
PNA
132 struct nft_table *table,
133 struct nft_chain *chain,
134 const struct nlattr * const *nla)
135{
633c9a84 136 ctx->net = net;
36596dad 137 ctx->family = family;
26b2f552 138 ctx->level = 0;
128ad332
PNA
139 ctx->table = table;
140 ctx->chain = chain;
141 ctx->nla = nla;
142 ctx->portid = NETLINK_CB(skb).portid;
143 ctx->report = nlmsg_report(nlh);
c9626a2c 144 ctx->flags = nlh->nlmsg_flags;
128ad332 145 ctx->seq = nlh->nlmsg_seq;
7c95f6d8
PNA
146}
147
8411b644
PNA
148static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
149 int msg_type, u32 size, gfp_t gfp)
1081d11b
PNA
150{
151 struct nft_trans *trans;
152
8411b644 153 trans = kzalloc(sizeof(struct nft_trans) + size, gfp);
1081d11b
PNA
154 if (trans == NULL)
155 return NULL;
156
b380e5c7 157 trans->msg_type = msg_type;
1081d11b
PNA
158 trans->ctx = *ctx;
159
160 return trans;
161}
162
8411b644
PNA
163static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx,
164 int msg_type, u32 size)
165{
166 return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL);
167}
168
1081d11b
PNA
169static void nft_trans_destroy(struct nft_trans *trans)
170{
171 list_del(&trans->list);
172 kfree(trans);
173}
174
f6ac8585
PNA
175static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
176{
0854db2a 177 struct nftables_pernet *nft_net;
f6ac8585
PNA
178 struct net *net = ctx->net;
179 struct nft_trans *trans;
180
181 if (!nft_set_is_anonymous(set))
182 return;
183
0854db2a
FW
184 nft_net = net_generic(net, nf_tables_net_id);
185 list_for_each_entry_reverse(trans, &nft_net->commit_list, list) {
6a0a8d10
PNA
186 switch (trans->msg_type) {
187 case NFT_MSG_NEWSET:
188 if (nft_trans_set(trans) == set)
189 nft_trans_set_bound(trans) = true;
190 break;
191 case NFT_MSG_NEWSETELEM:
192 if (nft_trans_elem_set(trans) == set)
193 nft_trans_elem_set_bound(trans) = true;
f6ac8585
PNA
194 break;
195 }
196 }
197}
198
d54725cd
PNA
199static int nft_netdev_register_hooks(struct net *net,
200 struct list_head *hook_list)
201{
202 struct nft_hook *hook;
203 int err, j;
204
205 j = 0;
206 list_for_each_entry(hook, hook_list, list) {
207 err = nf_register_net_hook(net, &hook->ops);
208 if (err < 0)
209 goto err_register;
210
211 j++;
212 }
213 return 0;
214
215err_register:
216 list_for_each_entry(hook, hook_list, list) {
217 if (j-- <= 0)
218 break;
219
220 nf_unregister_net_hook(net, &hook->ops);
221 }
222 return err;
223}
224
225static void nft_netdev_unregister_hooks(struct net *net,
226 struct list_head *hook_list)
227{
228 struct nft_hook *hook;
229
230 list_for_each_entry(hook, hook_list, list)
231 nf_unregister_net_hook(net, &hook->ops);
232}
233
c974a3a3
PNA
234static int nf_tables_register_hook(struct net *net,
235 const struct nft_table *table,
236 struct nft_chain *chain)
d8ee8f7c 237{
d54725cd 238 struct nft_base_chain *basechain;
a37061a6 239 const struct nf_hook_ops *ops;
ae6153b5 240
d8ee8f7c 241 if (table->flags & NFT_TABLE_F_DORMANT ||
f323d954 242 !nft_is_base_chain(chain))
d8ee8f7c
PNA
243 return 0;
244
4e25ceb8
FW
245 basechain = nft_base_chain(chain);
246 ops = &basechain->ops;
ae6153b5 247
4e25ceb8
FW
248 if (basechain->type->ops_register)
249 return basechain->type->ops_register(net, ops);
250
d3519cb8 251 if (nft_base_chain_netdev(table->family, basechain->ops.hooknum))
1e9451cb
FW
252 return nft_netdev_register_hooks(net, &basechain->hook_list);
253
254 return nf_register_net_hook(net, &basechain->ops);
d8ee8f7c
PNA
255}
256
c974a3a3
PNA
257static void nf_tables_unregister_hook(struct net *net,
258 const struct nft_table *table,
259 struct nft_chain *chain)
c5598794 260{
d54725cd 261 struct nft_base_chain *basechain;
4e25ceb8
FW
262 const struct nf_hook_ops *ops;
263
d8ee8f7c 264 if (table->flags & NFT_TABLE_F_DORMANT ||
f323d954 265 !nft_is_base_chain(chain))
d8ee8f7c 266 return;
4e25ceb8
FW
267 basechain = nft_base_chain(chain);
268 ops = &basechain->ops;
d8ee8f7c 269
4e25ceb8
FW
270 if (basechain->type->ops_unregister)
271 return basechain->type->ops_unregister(net, ops);
272
d3519cb8 273 if (nft_base_chain_netdev(table->family, basechain->ops.hooknum))
1e9451cb
FW
274 nft_netdev_unregister_hooks(net, &basechain->hook_list);
275 else
276 nf_unregister_net_hook(net, &basechain->ops);
c5598794
AB
277}
278
0854db2a
FW
279static void nft_trans_commit_list_add_tail(struct net *net, struct nft_trans *trans)
280{
281 struct nftables_pernet *nft_net;
282
283 nft_net = net_generic(net, nf_tables_net_id);
284 list_add_tail(&trans->list, &nft_net->commit_list);
285}
286
ee01d542
AB
287static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
288{
289 struct nft_trans *trans;
290
291 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
292 if (trans == NULL)
293 return -ENOMEM;
294
295 if (msg_type == NFT_MSG_NEWTABLE)
f2a6d766 296 nft_activate_next(ctx->net, ctx->table);
ee01d542 297
0854db2a 298 nft_trans_commit_list_add_tail(ctx->net, trans);
ee01d542
AB
299 return 0;
300}
301
302static int nft_deltable(struct nft_ctx *ctx)
303{
304 int err;
305
306 err = nft_trans_table_add(ctx, NFT_MSG_DELTABLE);
307 if (err < 0)
308 return err;
309
f2a6d766 310 nft_deactivate_next(ctx->net, ctx->table);
ee01d542
AB
311 return err;
312}
313
66293c46 314static struct nft_trans *nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
ee01d542
AB
315{
316 struct nft_trans *trans;
317
318 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
319 if (trans == NULL)
66293c46 320 return ERR_PTR(-ENOMEM);
ee01d542 321
74cccc3d 322 if (msg_type == NFT_MSG_NEWCHAIN) {
664b0f8c 323 nft_activate_next(ctx->net, ctx->chain);
ee01d542 324
74cccc3d
PNA
325 if (ctx->nla[NFTA_CHAIN_ID]) {
326 nft_trans_chain_id(trans) =
327 ntohl(nla_get_be32(ctx->nla[NFTA_CHAIN_ID]));
328 }
329 }
330
0854db2a 331 nft_trans_commit_list_add_tail(ctx->net, trans);
66293c46 332 return trans;
ee01d542
AB
333}
334
335static int nft_delchain(struct nft_ctx *ctx)
336{
66293c46 337 struct nft_trans *trans;
ee01d542 338
66293c46
FW
339 trans = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
340 if (IS_ERR(trans))
341 return PTR_ERR(trans);
ee01d542
AB
342
343 ctx->table->use--;
664b0f8c 344 nft_deactivate_next(ctx->net, ctx->chain);
ee01d542 345
66293c46 346 return 0;
ee01d542
AB
347}
348
bb7b40ae
PNA
349static void nft_rule_expr_activate(const struct nft_ctx *ctx,
350 struct nft_rule *rule)
351{
352 struct nft_expr *expr;
353
354 expr = nft_expr_first(rule);
31cc578a 355 while (nft_expr_more(rule, expr)) {
bb7b40ae
PNA
356 if (expr->ops->activate)
357 expr->ops->activate(ctx, expr);
358
359 expr = nft_expr_next(expr);
360 }
361}
362
363static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
f6ac8585
PNA
364 struct nft_rule *rule,
365 enum nft_trans_phase phase)
bb7b40ae
PNA
366{
367 struct nft_expr *expr;
368
369 expr = nft_expr_first(rule);
31cc578a 370 while (nft_expr_more(rule, expr)) {
bb7b40ae 371 if (expr->ops->deactivate)
f6ac8585 372 expr->ops->deactivate(ctx, expr, phase);
bb7b40ae
PNA
373
374 expr = nft_expr_next(expr);
375 }
376}
377
ee01d542
AB
378static int
379nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
380{
381 /* You cannot delete the same rule twice */
889f7ee7
PNA
382 if (nft_is_active_next(ctx->net, rule)) {
383 nft_deactivate_next(ctx->net, rule);
ee01d542
AB
384 ctx->chain->use--;
385 return 0;
386 }
387 return -ENOENT;
388}
389
390static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
391 struct nft_rule *rule)
392{
393 struct nft_trans *trans;
394
395 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
396 if (trans == NULL)
397 return NULL;
398
1a94e38d
PNA
399 if (msg_type == NFT_MSG_NEWRULE && ctx->nla[NFTA_RULE_ID] != NULL) {
400 nft_trans_rule_id(trans) =
401 ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
402 }
ee01d542 403 nft_trans_rule(trans) = rule;
0854db2a 404 nft_trans_commit_list_add_tail(ctx->net, trans);
ee01d542
AB
405
406 return trans;
407}
408
409static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
410{
63b48c73 411 struct nft_flow_rule *flow;
ee01d542
AB
412 struct nft_trans *trans;
413 int err;
414
415 trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
416 if (trans == NULL)
417 return -ENOMEM;
418
63b48c73
PNA
419 if (ctx->chain->flags & NFT_CHAIN_HW_OFFLOAD) {
420 flow = nft_flow_rule_create(ctx->net, rule);
421 if (IS_ERR(flow)) {
422 nft_trans_destroy(trans);
423 return PTR_ERR(flow);
424 }
425
426 nft_trans_flow_rule(trans) = flow;
427 }
428
ee01d542
AB
429 err = nf_tables_delrule_deactivate(ctx, rule);
430 if (err < 0) {
431 nft_trans_destroy(trans);
432 return err;
433 }
f6ac8585 434 nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_PREPARE);
ee01d542
AB
435
436 return 0;
437}
438
439static int nft_delrule_by_chain(struct nft_ctx *ctx)
440{
441 struct nft_rule *rule;
442 int err;
443
444 list_for_each_entry(rule, &ctx->chain->rules, list) {
23b7ca4f
PNA
445 if (!nft_is_active_next(ctx->net, rule))
446 continue;
447
ee01d542
AB
448 err = nft_delrule(ctx, rule);
449 if (err < 0)
450 return err;
451 }
452 return 0;
453}
454
cd5125d8 455static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
ee01d542
AB
456 struct nft_set *set)
457{
458 struct nft_trans *trans;
459
460 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
461 if (trans == NULL)
462 return -ENOMEM;
463
464 if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
465 nft_trans_set_id(trans) =
466 ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
37a9cc52 467 nft_activate_next(ctx->net, set);
ee01d542
AB
468 }
469 nft_trans_set(trans) = set;
0854db2a 470 nft_trans_commit_list_add_tail(ctx->net, trans);
ee01d542
AB
471
472 return 0;
473}
474
cd5125d8 475static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
ee01d542
AB
476{
477 int err;
478
479 err = nft_trans_set_add(ctx, NFT_MSG_DELSET, set);
480 if (err < 0)
481 return err;
482
37a9cc52 483 nft_deactivate_next(ctx->net, set);
ee01d542
AB
484 ctx->table->use--;
485
486 return err;
487}
488
e5009240
PNA
489static int nft_trans_obj_add(struct nft_ctx *ctx, int msg_type,
490 struct nft_object *obj)
491{
492 struct nft_trans *trans;
493
494 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_obj));
495 if (trans == NULL)
496 return -ENOMEM;
497
498 if (msg_type == NFT_MSG_NEWOBJ)
499 nft_activate_next(ctx->net, obj);
500
501 nft_trans_obj(trans) = obj;
0854db2a 502 nft_trans_commit_list_add_tail(ctx->net, trans);
e5009240
PNA
503
504 return 0;
505}
506
507static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj)
508{
509 int err;
510
511 err = nft_trans_obj_add(ctx, NFT_MSG_DELOBJ, obj);
512 if (err < 0)
513 return err;
514
515 nft_deactivate_next(ctx->net, obj);
516 ctx->table->use--;
517
518 return err;
519}
520
3b49e2e9
PNA
521static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type,
522 struct nft_flowtable *flowtable)
523{
524 struct nft_trans *trans;
525
526 trans = nft_trans_alloc(ctx, msg_type,
527 sizeof(struct nft_trans_flowtable));
528 if (trans == NULL)
529 return -ENOMEM;
530
531 if (msg_type == NFT_MSG_NEWFLOWTABLE)
532 nft_activate_next(ctx->net, flowtable);
533
534 nft_trans_flowtable(trans) = flowtable;
0854db2a 535 nft_trans_commit_list_add_tail(ctx->net, trans);
3b49e2e9
PNA
536
537 return 0;
538}
539
540static int nft_delflowtable(struct nft_ctx *ctx,
541 struct nft_flowtable *flowtable)
542{
543 int err;
544
545 err = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable);
546 if (err < 0)
547 return err;
548
549 nft_deactivate_next(ctx->net, flowtable);
550 ctx->table->use--;
551
552 return err;
553}
554
96518518
PM
555/*
556 * Tables
557 */
558
36596dad 559static struct nft_table *nft_table_lookup(const struct net *net,
f2a6d766 560 const struct nlattr *nla,
6001a930 561 u8 family, u8 genmask, u32 nlpid)
96518518 562{
0854db2a 563 struct nftables_pernet *nft_net;
96518518
PM
564 struct nft_table *table;
565
cac20fcd
PNA
566 if (nla == NULL)
567 return ERR_PTR(-EINVAL);
568
0854db2a
FW
569 nft_net = net_generic(net, nf_tables_net_id);
570 list_for_each_entry_rcu(table, &nft_net->tables, list,
571 lockdep_is_held(&nft_net->commit_mutex)) {
f2a6d766 572 if (!nla_strcmp(nla, table->name) &&
98319cb9 573 table->family == family &&
6001a930
PNA
574 nft_active_genmask(table, genmask)) {
575 if (nft_table_has_owner(table) &&
576 table->nlpid != nlpid)
577 return ERR_PTR(-EPERM);
578
96518518 579 return table;
6001a930 580 }
96518518 581 }
cac20fcd
PNA
582
583 return ERR_PTR(-ENOENT);
96518518
PM
584}
585
3ecbfd65
HS
586static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
587 const struct nlattr *nla,
588 u8 genmask)
589{
0854db2a 590 struct nftables_pernet *nft_net;
3ecbfd65
HS
591 struct nft_table *table;
592
0854db2a
FW
593 nft_net = net_generic(net, nf_tables_net_id);
594 list_for_each_entry(table, &nft_net->tables, list) {
3ecbfd65
HS
595 if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
596 nft_active_genmask(table, genmask))
597 return table;
598 }
3ecbfd65
HS
599
600 return ERR_PTR(-ENOENT);
601}
602
96518518
PM
603static inline u64 nf_tables_alloc_handle(struct nft_table *table)
604{
605 return ++table->hgenerator;
606}
607
32537e91 608static const struct nft_chain_type *chain_type[NFPROTO_NUMPROTO][NFT_CHAIN_T_MAX];
9370761c 609
82603549
PNA
610static const struct nft_chain_type *
611__nft_chain_type_get(u8 family, enum nft_chain_types type)
612{
613 if (family >= NFPROTO_NUMPROTO ||
614 type >= NFT_CHAIN_T_MAX)
615 return NULL;
616
617 return chain_type[family][type];
618}
619
32537e91 620static const struct nft_chain_type *
1ea26cca 621__nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family)
9370761c 622{
82603549 623 const struct nft_chain_type *type;
9370761c
PNA
624 int i;
625
baae3e62 626 for (i = 0; i < NFT_CHAIN_T_MAX; i++) {
82603549
PNA
627 type = __nft_chain_type_get(family, i);
628 if (!type)
629 continue;
630 if (!nla_strcmp(nla, type->name))
631 return type;
9370761c 632 }
baae3e62 633 return NULL;
9370761c
PNA
634}
635
eb014de4
PNA
636struct nft_module_request {
637 struct list_head list;
638 char module[MODULE_NAME_LEN];
639 bool done;
640};
641
452238e8 642#ifdef CONFIG_MODULES
cefa31a9
FW
643__printf(2, 3) int nft_request_module(struct net *net, const char *fmt,
644 ...)
452238e8
FW
645{
646 char module_name[MODULE_NAME_LEN];
0854db2a 647 struct nftables_pernet *nft_net;
eb014de4 648 struct nft_module_request *req;
452238e8
FW
649 va_list args;
650 int ret;
651
452238e8
FW
652 va_start(args, fmt);
653 ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
654 va_end(args);
9332d27d 655 if (ret >= MODULE_NAME_LEN)
eb014de4 656 return 0;
452238e8 657
0854db2a
FW
658 nft_net = net_generic(net, nf_tables_net_id);
659 list_for_each_entry(req, &nft_net->module_list, list) {
eb014de4
PNA
660 if (!strcmp(req->module, module_name)) {
661 if (req->done)
662 return 0;
ec7470b8 663
eb014de4
PNA
664 /* A request to load this module already exists. */
665 return -EAGAIN;
666 }
667 }
668
669 req = kmalloc(sizeof(*req), GFP_KERNEL);
670 if (!req)
671 return -ENOMEM;
672
673 req->done = false;
674 strlcpy(req->module, module_name, MODULE_NAME_LEN);
0854db2a 675 list_add_tail(&req->list, &nft_net->module_list);
eb014de4
PNA
676
677 return -EAGAIN;
452238e8 678}
cefa31a9 679EXPORT_SYMBOL_GPL(nft_request_module);
452238e8
FW
680#endif
681
f102d66b
FW
682static void lockdep_nfnl_nft_mutex_not_held(void)
683{
684#ifdef CONFIG_PROVE_LOCKING
c0700dfa
FW
685 if (debug_locks)
686 WARN_ON_ONCE(lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES));
f102d66b
FW
687#endif
688}
689
32537e91 690static const struct nft_chain_type *
452238e8
FW
691nf_tables_chain_type_lookup(struct net *net, const struct nlattr *nla,
692 u8 family, bool autoload)
9370761c 693{
32537e91 694 const struct nft_chain_type *type;
9370761c 695
1ea26cca 696 type = __nf_tables_chain_type_lookup(nla, family);
93b0806f
PM
697 if (type != NULL)
698 return type;
f102d66b
FW
699
700 lockdep_nfnl_nft_mutex_not_held();
9370761c 701#ifdef CONFIG_MODULES
93b0806f 702 if (autoload) {
eb014de4
PNA
703 if (nft_request_module(net, "nft-chain-%u-%.*s", family,
704 nla_len(nla),
705 (const char *)nla_data(nla)) == -EAGAIN)
93b0806f 706 return ERR_PTR(-EAGAIN);
9370761c
PNA
707 }
708#endif
93b0806f 709 return ERR_PTR(-ENOENT);
9370761c
PNA
710}
711
802b8051
PNA
712static __be16 nft_base_seq(const struct net *net)
713{
0854db2a
FW
714 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
715
716 return htons(nft_net->base_seq & 0xffff);
802b8051
PNA
717}
718
96518518 719static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
1cae565e
PNA
720 [NFTA_TABLE_NAME] = { .type = NLA_STRING,
721 .len = NFT_TABLE_MAXNAMELEN - 1 },
9ddf6323 722 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
3ecbfd65 723 [NFTA_TABLE_HANDLE] = { .type = NLA_U64 },
7a81575b
JGG
724 [NFTA_TABLE_USERDATA] = { .type = NLA_BINARY,
725 .len = NFT_USERDATA_MAXLEN }
96518518
PM
726};
727
84d7fce6
PNA
728static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
729 u32 portid, u32 seq, int event, u32 flags,
730 int family, const struct nft_table *table)
96518518
PM
731{
732 struct nlmsghdr *nlh;
96518518 733
dedb67c4 734 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
19c28b13
PNA
735 nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
736 NFNETLINK_V0, nft_base_seq(net));
737 if (!nlh)
96518518
PM
738 goto nla_put_failure;
739
9ddf6323 740 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
d8bcc768 741 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||
3ecbfd65
HS
742 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) ||
743 nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle),
744 NFTA_TABLE_PAD))
96518518 745 goto nla_put_failure;
6001a930
PNA
746 if (nft_table_has_owner(table) &&
747 nla_put_be32(skb, NFTA_TABLE_OWNER, htonl(table->nlpid)))
748 goto nla_put_failure;
96518518 749
7a81575b
JGG
750 if (table->udata) {
751 if (nla_put(skb, NFTA_TABLE_USERDATA, table->udlen, table->udata))
752 goto nla_put_failure;
753 }
754
053c095a
JB
755 nlmsg_end(skb, nlh);
756 return 0;
96518518
PM
757
758nla_put_failure:
759 nlmsg_trim(skb, nlh);
760 return -1;
761}
762
67cc570e
PNA
763struct nftnl_skb_parms {
764 bool report;
765};
766#define NFT_CB(skb) (*(struct nftnl_skb_parms*)&((skb)->cb))
767
768static void nft_notify_enqueue(struct sk_buff *skb, bool report,
769 struct list_head *notify_list)
770{
771 NFT_CB(skb).report = report;
772 list_add_tail(&skb->list, notify_list);
773}
774
25e94a99 775static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
96518518 776{
0854db2a 777 struct nftables_pernet *nft_net;
96518518 778 struct sk_buff *skb;
96518518
PM
779 int err;
780
128ad332
PNA
781 if (!ctx->report &&
782 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 783 return;
96518518 784
96518518
PM
785 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
786 if (skb == NULL)
787 goto err;
788
84d7fce6 789 err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
36596dad 790 event, 0, ctx->family, ctx->table);
96518518
PM
791 if (err < 0) {
792 kfree_skb(skb);
793 goto err;
794 }
795
0854db2a
FW
796 nft_net = net_generic(ctx->net, nf_tables_net_id);
797 nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
25e94a99 798 return;
96518518 799err:
25e94a99 800 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
801}
802
803static int nf_tables_dump_tables(struct sk_buff *skb,
804 struct netlink_callback *cb)
805{
806 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
0854db2a 807 struct nftables_pernet *nft_net;
96518518
PM
808 const struct nft_table *table;
809 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 810 struct net *net = sock_net(skb->sk);
96518518
PM
811 int family = nfmsg->nfgen_family;
812
e688a7f8 813 rcu_read_lock();
0854db2a
FW
814 nft_net = net_generic(net, nf_tables_net_id);
815 cb->seq = nft_net->base_seq;
38e029f1 816
0854db2a 817 list_for_each_entry_rcu(table, &nft_net->tables, list) {
98319cb9 818 if (family != NFPROTO_UNSPEC && family != table->family)
96518518
PM
819 continue;
820
36596dad
PNA
821 if (idx < s_idx)
822 goto cont;
823 if (idx > s_idx)
824 memset(&cb->args[1], 0,
825 sizeof(cb->args) - sizeof(cb->args[0]));
826 if (!nft_is_active(net, table))
827 continue;
828 if (nf_tables_fill_table_info(skb, net,
829 NETLINK_CB(cb->skb).portid,
830 cb->nlh->nlmsg_seq,
831 NFT_MSG_NEWTABLE, NLM_F_MULTI,
98319cb9 832 table->family, table) < 0)
36596dad
PNA
833 goto done;
834
835 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518 836cont:
36596dad 837 idx++;
96518518
PM
838 }
839done:
e688a7f8 840 rcu_read_unlock();
96518518
PM
841 cb->args[0] = idx;
842 return skb->len;
843}
844
d9adf22a
FW
845static int nft_netlink_dump_start_rcu(struct sock *nlsk, struct sk_buff *skb,
846 const struct nlmsghdr *nlh,
847 struct netlink_dump_control *c)
848{
849 int err;
850
851 if (!try_module_get(THIS_MODULE))
852 return -EINVAL;
853
854 rcu_read_unlock();
855 err = netlink_dump_start(nlsk, skb, nlh, c);
856 rcu_read_lock();
857 module_put(THIS_MODULE);
858
859 return err;
860}
861
862/* called with rcu_read_lock held */
7b8002a1
PNA
863static int nf_tables_gettable(struct net *net, struct sock *nlsk,
864 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
865 const struct nlattr * const nla[],
866 struct netlink_ext_ack *extack)
96518518
PM
867{
868 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 869 u8 genmask = nft_genmask_cur(net);
96518518
PM
870 const struct nft_table *table;
871 struct sk_buff *skb2;
872 int family = nfmsg->nfgen_family;
873 int err;
874
875 if (nlh->nlmsg_flags & NLM_F_DUMP) {
876 struct netlink_dump_control c = {
877 .dump = nf_tables_dump_tables,
d9adf22a 878 .module = THIS_MODULE,
96518518 879 };
d9adf22a
FW
880
881 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
96518518
PM
882 }
883
6001a930 884 table = nft_table_lookup(net, nla[NFTA_TABLE_NAME], family, genmask, 0);
36dd1bcc
PNA
885 if (IS_ERR(table)) {
886 NL_SET_BAD_ATTR(extack, nla[NFTA_TABLE_NAME]);
96518518 887 return PTR_ERR(table);
36dd1bcc 888 }
96518518 889
d9adf22a 890 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
96518518
PM
891 if (!skb2)
892 return -ENOMEM;
893
84d7fce6 894 err = nf_tables_fill_table_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
895 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
896 family, table);
897 if (err < 0)
ee921183 898 goto err_fill_table_info;
96518518 899
ee921183 900 return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
96518518 901
ee921183 902err_fill_table_info:
96518518
PM
903 kfree_skb(skb2);
904 return err;
905}
906
c9c17211 907static void nft_table_disable(struct net *net, struct nft_table *table, u32 cnt)
10435c11
F
908{
909 struct nft_chain *chain;
910 u32 i = 0;
911
912 list_for_each_entry(chain, &table->chains, list) {
913 if (!nft_is_active_next(net, chain))
914 continue;
f323d954 915 if (!nft_is_base_chain(chain))
10435c11
F
916 continue;
917
918 if (cnt && i++ == cnt)
919 break;
920
1e9451cb 921 nf_tables_unregister_hook(net, table, chain);
10435c11
F
922 }
923}
924
c9c17211 925static int nf_tables_table_enable(struct net *net, struct nft_table *table)
9ddf6323
PNA
926{
927 struct nft_chain *chain;
928 int err, i = 0;
929
930 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
931 if (!nft_is_active_next(net, chain))
932 continue;
f323d954 933 if (!nft_is_base_chain(chain))
d2012975
PNA
934 continue;
935
1e9451cb 936 err = nf_tables_register_hook(net, table, chain);
9ddf6323 937 if (err < 0)
d54725cd 938 goto err_register_hooks;
9ddf6323
PNA
939
940 i++;
941 }
942 return 0;
d54725cd
PNA
943
944err_register_hooks:
10435c11 945 if (i)
c9c17211 946 nft_table_disable(net, table, i);
9ddf6323
PNA
947 return err;
948}
949
c9c17211 950static void nf_tables_table_disable(struct net *net, struct nft_table *table)
9ddf6323 951{
c9c17211 952 nft_table_disable(net, table, 0);
9ddf6323
PNA
953}
954
0ce7cf41
PNA
955enum {
956 NFT_TABLE_STATE_UNCHANGED = 0,
957 NFT_TABLE_STATE_DORMANT,
958 NFT_TABLE_STATE_WAKEUP
959};
960
e1aaca93 961static int nf_tables_updtable(struct nft_ctx *ctx)
9ddf6323 962{
55dd6f93 963 struct nft_trans *trans;
e1aaca93 964 u32 flags;
55dd6f93 965 int ret = 0;
9ddf6323 966
e1aaca93
PNA
967 if (!ctx->nla[NFTA_TABLE_FLAGS])
968 return 0;
9ddf6323 969
e1aaca93 970 flags = ntohl(nla_get_be32(ctx->nla[NFTA_TABLE_FLAGS]));
6001a930
PNA
971 if (flags & ~NFT_TABLE_F_MASK)
972 return -EOPNOTSUPP;
e1aaca93 973
63283dd2
PNA
974 if (flags == ctx->table->flags)
975 return 0;
976
9cc0001a
PNA
977 if ((nft_table_has_owner(ctx->table) &&
978 !(flags & NFT_TABLE_F_OWNER)) ||
979 (!nft_table_has_owner(ctx->table) &&
980 flags & NFT_TABLE_F_OWNER))
981 return -EOPNOTSUPP;
982
55dd6f93
PNA
983 trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
984 sizeof(struct nft_trans_table));
985 if (trans == NULL)
986 return -ENOMEM;
9ddf6323 987
e1aaca93
PNA
988 if ((flags & NFT_TABLE_F_DORMANT) &&
989 !(ctx->table->flags & NFT_TABLE_F_DORMANT)) {
0ce7cf41 990 nft_trans_table_state(trans) = NFT_TABLE_STATE_DORMANT;
e1aaca93
PNA
991 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
992 ctx->table->flags & NFT_TABLE_F_DORMANT) {
c9c17211 993 ret = nf_tables_table_enable(ctx->net, ctx->table);
1e9451cb 994 if (ret >= 0)
0ce7cf41 995 nft_trans_table_state(trans) = NFT_TABLE_STATE_WAKEUP;
9ddf6323 996 }
e1aaca93
PNA
997 if (ret < 0)
998 goto err;
9ddf6323 999
0ce7cf41 1000 nft_trans_table_flags(trans) = flags;
55dd6f93 1001 nft_trans_table_update(trans) = true;
0854db2a 1002 nft_trans_commit_list_add_tail(ctx->net, trans);
55dd6f93 1003 return 0;
9ddf6323 1004err:
55dd6f93 1005 nft_trans_destroy(trans);
9ddf6323
PNA
1006 return ret;
1007}
1008
1b2470e5
FW
1009static u32 nft_chain_hash(const void *data, u32 len, u32 seed)
1010{
1011 const char *name = data;
1012
1013 return jhash(name, strlen(name), seed);
1014}
1015
1016static u32 nft_chain_hash_obj(const void *data, u32 len, u32 seed)
1017{
1018 const struct nft_chain *chain = data;
1019
1020 return nft_chain_hash(chain->name, 0, seed);
1021}
1022
1023static int nft_chain_hash_cmp(struct rhashtable_compare_arg *arg,
1024 const void *ptr)
1025{
1026 const struct nft_chain *chain = ptr;
1027 const char *name = arg->key;
1028
1029 return strcmp(chain->name, name);
1030}
1031
4d44175a
FW
1032static u32 nft_objname_hash(const void *data, u32 len, u32 seed)
1033{
1034 const struct nft_object_hash_key *k = data;
1035
1036 seed ^= hash_ptr(k->table, 32);
1037
1038 return jhash(k->name, strlen(k->name), seed);
1039}
1040
1041static u32 nft_objname_hash_obj(const void *data, u32 len, u32 seed)
1042{
1043 const struct nft_object *obj = data;
1044
1045 return nft_objname_hash(&obj->key, 0, seed);
1046}
1047
1048static int nft_objname_hash_cmp(struct rhashtable_compare_arg *arg,
1049 const void *ptr)
1050{
1051 const struct nft_object_hash_key *k = arg->key;
1052 const struct nft_object *obj = ptr;
1053
1054 if (obj->key.table != k->table)
1055 return -1;
1056
1057 return strcmp(obj->key.name, k->name);
1058}
1059
633c9a84
PNA
1060static int nf_tables_newtable(struct net *net, struct sock *nlsk,
1061 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1062 const struct nlattr * const nla[],
1063 struct netlink_ext_ack *extack)
96518518 1064{
0854db2a 1065 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
96518518 1066 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1067 u8 genmask = nft_genmask_next(net);
96518518 1068 int family = nfmsg->nfgen_family;
36dd1bcc
PNA
1069 const struct nlattr *attr;
1070 struct nft_table *table;
e1aaca93 1071 struct nft_ctx ctx;
7a81575b 1072 u32 flags = 0;
55dd6f93 1073 int err;
96518518 1074
0854db2a 1075 lockdep_assert_held(&nft_net->commit_mutex);
36dd1bcc 1076 attr = nla[NFTA_TABLE_NAME];
6001a930
PNA
1077 table = nft_table_lookup(net, attr, family, genmask,
1078 NETLINK_CB(skb).portid);
96518518
PM
1079 if (IS_ERR(table)) {
1080 if (PTR_ERR(table) != -ENOENT)
1081 return PTR_ERR(table);
1a28ad74 1082 } else {
36dd1bcc
PNA
1083 if (nlh->nlmsg_flags & NLM_F_EXCL) {
1084 NL_SET_BAD_ATTR(extack, attr);
96518518 1085 return -EEXIST;
36dd1bcc 1086 }
96518518
PM
1087 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1088 return -EOPNOTSUPP;
e1aaca93 1089
98319cb9 1090 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e1aaca93 1091 return nf_tables_updtable(&ctx);
96518518
PM
1092 }
1093
c5c1f975
PM
1094 if (nla[NFTA_TABLE_FLAGS]) {
1095 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
6001a930
PNA
1096 if (flags & ~NFT_TABLE_F_MASK)
1097 return -EOPNOTSUPP;
c5c1f975
PM
1098 }
1099
ffdb210e 1100 err = -ENOMEM;
1cae565e 1101 table = kzalloc(sizeof(*table), GFP_KERNEL);
ffdb210e 1102 if (table == NULL)
98319cb9 1103 goto err_kzalloc;
96518518 1104
36dd1bcc 1105 table->name = nla_strdup(attr, GFP_KERNEL);
e46abbcc 1106 if (table->name == NULL)
98319cb9 1107 goto err_strdup;
e46abbcc 1108
7a81575b 1109 if (nla[NFTA_TABLE_USERDATA]) {
85db827a 1110 table->udata = nla_memdup(nla[NFTA_TABLE_USERDATA], GFP_KERNEL);
7a81575b
JGG
1111 if (table->udata == NULL)
1112 goto err_table_udata;
1113
85db827a 1114 table->udlen = nla_len(nla[NFTA_TABLE_USERDATA]);
7a81575b
JGG
1115 }
1116
1b2470e5
FW
1117 err = rhltable_init(&table->chains_ht, &nft_chain_ht_params);
1118 if (err)
1119 goto err_chain_ht;
1120
96518518 1121 INIT_LIST_HEAD(&table->chains);
20a69341 1122 INIT_LIST_HEAD(&table->sets);
e5009240 1123 INIT_LIST_HEAD(&table->objects);
3b49e2e9 1124 INIT_LIST_HEAD(&table->flowtables);
98319cb9 1125 table->family = family;
c5c1f975 1126 table->flags = flags;
3ecbfd65 1127 table->handle = ++table_handle;
6001a930
PNA
1128 if (table->flags & NFT_TABLE_F_OWNER)
1129 table->nlpid = NETLINK_CB(skb).portid;
9ddf6323 1130
98319cb9 1131 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
55dd6f93 1132 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
ffdb210e 1133 if (err < 0)
98319cb9 1134 goto err_trans;
ffdb210e 1135
0854db2a 1136 list_add_tail_rcu(&table->list, &nft_net->tables);
96518518 1137 return 0;
98319cb9 1138err_trans:
1b2470e5
FW
1139 rhltable_destroy(&table->chains_ht);
1140err_chain_ht:
7a81575b
JGG
1141 kfree(table->udata);
1142err_table_udata:
e46abbcc 1143 kfree(table->name);
98319cb9 1144err_strdup:
ffdb210e 1145 kfree(table);
98319cb9 1146err_kzalloc:
ffdb210e 1147 return err;
96518518
PM
1148}
1149
b9ac12ef
AB
1150static int nft_flush_table(struct nft_ctx *ctx)
1151{
3b49e2e9 1152 struct nft_flowtable *flowtable, *nft;
b9ac12ef 1153 struct nft_chain *chain, *nc;
e5009240 1154 struct nft_object *obj, *ne;
b9ac12ef 1155 struct nft_set *set, *ns;
3b49e2e9 1156 int err;
b9ac12ef 1157
a2f18db0 1158 list_for_each_entry(chain, &ctx->table->chains, list) {
664b0f8c
PNA
1159 if (!nft_is_active_next(ctx->net, chain))
1160 continue;
1161
d0e2c7de
PNA
1162 if (nft_chain_is_bound(chain))
1163 continue;
1164
b9ac12ef
AB
1165 ctx->chain = chain;
1166
1167 err = nft_delrule_by_chain(ctx);
1168 if (err < 0)
1169 goto out;
b9ac12ef
AB
1170 }
1171
1172 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
37a9cc52
PNA
1173 if (!nft_is_active_next(ctx->net, set))
1174 continue;
1175
408070d6 1176 if (nft_set_is_anonymous(set) &&
b9ac12ef
AB
1177 !list_empty(&set->bindings))
1178 continue;
1179
1180 err = nft_delset(ctx, set);
1181 if (err < 0)
1182 goto out;
1183 }
1184
3b49e2e9 1185 list_for_each_entry_safe(flowtable, nft, &ctx->table->flowtables, list) {
335178d5
FW
1186 if (!nft_is_active_next(ctx->net, flowtable))
1187 continue;
1188
3b49e2e9
PNA
1189 err = nft_delflowtable(ctx, flowtable);
1190 if (err < 0)
1191 goto out;
1192 }
1193
e5009240 1194 list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) {
335178d5
FW
1195 if (!nft_is_active_next(ctx->net, obj))
1196 continue;
1197
e5009240
PNA
1198 err = nft_delobj(ctx, obj);
1199 if (err < 0)
1200 goto out;
1201 }
1202
a2f18db0 1203 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
664b0f8c
PNA
1204 if (!nft_is_active_next(ctx->net, chain))
1205 continue;
1206
d0e2c7de
PNA
1207 if (nft_chain_is_bound(chain))
1208 continue;
1209
a2f18db0
PNA
1210 ctx->chain = chain;
1211
1212 err = nft_delchain(ctx);
1213 if (err < 0)
1214 goto out;
1215 }
1216
b9ac12ef
AB
1217 err = nft_deltable(ctx);
1218out:
1219 return err;
1220}
1221
1222static int nft_flush(struct nft_ctx *ctx, int family)
1223{
0854db2a 1224 struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
b9ac12ef
AB
1225 struct nft_table *table, *nt;
1226 const struct nlattr * const *nla = ctx->nla;
1227 int err = 0;
1228
0854db2a 1229 list_for_each_entry_safe(table, nt, &nft_net->tables, list) {
98319cb9 1230 if (family != AF_UNSPEC && table->family != family)
b9ac12ef
AB
1231 continue;
1232
98319cb9 1233 ctx->family = table->family;
f2a6d766 1234
36596dad
PNA
1235 if (!nft_is_active_next(ctx->net, table))
1236 continue;
b9ac12ef 1237
6001a930
PNA
1238 if (nft_table_has_owner(table) && table->nlpid != ctx->portid)
1239 continue;
1240
36596dad
PNA
1241 if (nla[NFTA_TABLE_NAME] &&
1242 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
1243 continue;
b9ac12ef 1244
36596dad
PNA
1245 ctx->table = table;
1246
1247 err = nft_flush_table(ctx);
1248 if (err < 0)
1249 goto out;
b9ac12ef
AB
1250 }
1251out:
1252 return err;
1253}
1254
633c9a84
PNA
1255static int nf_tables_deltable(struct net *net, struct sock *nlsk,
1256 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1257 const struct nlattr * const nla[],
1258 struct netlink_ext_ack *extack)
96518518
PM
1259{
1260 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1261 u8 genmask = nft_genmask_next(net);
ee01d542 1262 int family = nfmsg->nfgen_family;
36dd1bcc
PNA
1263 const struct nlattr *attr;
1264 struct nft_table *table;
55dd6f93 1265 struct nft_ctx ctx;
96518518 1266
36596dad 1267 nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla);
3ecbfd65
HS
1268 if (family == AF_UNSPEC ||
1269 (!nla[NFTA_TABLE_NAME] && !nla[NFTA_TABLE_HANDLE]))
b9ac12ef
AB
1270 return nft_flush(&ctx, family);
1271
36dd1bcc
PNA
1272 if (nla[NFTA_TABLE_HANDLE]) {
1273 attr = nla[NFTA_TABLE_HANDLE];
1274 table = nft_table_lookup_byhandle(net, attr, genmask);
1275 } else {
1276 attr = nla[NFTA_TABLE_NAME];
6001a930
PNA
1277 table = nft_table_lookup(net, attr, family, genmask,
1278 NETLINK_CB(skb).portid);
36dd1bcc 1279 }
3ecbfd65 1280
36dd1bcc
PNA
1281 if (IS_ERR(table)) {
1282 NL_SET_BAD_ATTR(extack, attr);
96518518 1283 return PTR_ERR(table);
36dd1bcc 1284 }
96518518 1285
a8278400
PNA
1286 if (nlh->nlmsg_flags & NLM_F_NONREC &&
1287 table->use > 0)
1288 return -EBUSY;
1289
98319cb9 1290 ctx.family = family;
b9ac12ef 1291 ctx.table = table;
55dd6f93 1292
b9ac12ef 1293 return nft_flush_table(&ctx);
96518518
PM
1294}
1295
55dd6f93
PNA
1296static void nf_tables_table_destroy(struct nft_ctx *ctx)
1297{
fa5950e4
FW
1298 if (WARN_ON(ctx->table->use > 0))
1299 return;
4fefee57 1300
1b2470e5 1301 rhltable_destroy(&ctx->table->chains_ht);
e46abbcc 1302 kfree(ctx->table->name);
bc7a7082 1303 kfree(ctx->table->udata);
55dd6f93 1304 kfree(ctx->table);
55dd6f93
PNA
1305}
1306
cc07eeb0 1307void nft_register_chain_type(const struct nft_chain_type *ctype)
96518518 1308{
96518518 1309 nfnl_lock(NFNL_SUBSYS_NFTABLES);
82603549 1310 if (WARN_ON(__nft_chain_type_get(ctype->family, ctype->type))) {
cc07eeb0
PNA
1311 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1312 return;
96518518 1313 }
9370761c 1314 chain_type[ctype->family][ctype->type] = ctype;
96518518 1315 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
96518518 1316}
9370761c 1317EXPORT_SYMBOL_GPL(nft_register_chain_type);
96518518 1318
32537e91 1319void nft_unregister_chain_type(const struct nft_chain_type *ctype)
96518518 1320{
96518518 1321 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c 1322 chain_type[ctype->family][ctype->type] = NULL;
96518518
PM
1323 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1324}
9370761c 1325EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
96518518
PM
1326
1327/*
1328 * Chains
1329 */
1330
1331static struct nft_chain *
cac20fcd 1332nft_chain_lookup_byhandle(const struct nft_table *table, u64 handle, u8 genmask)
96518518
PM
1333{
1334 struct nft_chain *chain;
1335
1336 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
1337 if (chain->handle == handle &&
1338 nft_active_genmask(chain, genmask))
96518518
PM
1339 return chain;
1340 }
1341
1342 return ERR_PTR(-ENOENT);
1343}
1344
4d44175a 1345static bool lockdep_commit_lock_is_held(const struct net *net)
f102d66b
FW
1346{
1347#ifdef CONFIG_PROVE_LOCKING
0854db2a
FW
1348 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
1349
1350 return lockdep_is_held(&nft_net->commit_mutex);
f102d66b
FW
1351#else
1352 return true;
1353#endif
1354}
1355
1356static struct nft_chain *nft_chain_lookup(struct net *net,
1357 struct nft_table *table,
cac20fcd 1358 const struct nlattr *nla, u8 genmask)
96518518 1359{
1b2470e5
FW
1360 char search[NFT_CHAIN_MAXNAMELEN + 1];
1361 struct rhlist_head *tmp, *list;
96518518
PM
1362 struct nft_chain *chain;
1363
1364 if (nla == NULL)
1365 return ERR_PTR(-EINVAL);
1366
872f6903 1367 nla_strscpy(search, nla, sizeof(search));
96518518 1368
1b2470e5 1369 WARN_ON(!rcu_read_lock_held() &&
f102d66b 1370 !lockdep_commit_lock_is_held(net));
1b2470e5
FW
1371
1372 chain = ERR_PTR(-ENOENT);
1373 rcu_read_lock();
1374 list = rhltable_lookup(&table->chains_ht, search, nft_chain_ht_params);
1375 if (!list)
1376 goto out_unlock;
1377
1378 rhl_for_each_entry_rcu(chain, tmp, list, rhlhead) {
1379 if (nft_active_genmask(chain, genmask))
1380 goto out_unlock;
1381 }
1382 chain = ERR_PTR(-ENOENT);
1383out_unlock:
1384 rcu_read_unlock();
1385 return chain;
96518518
PM
1386}
1387
1388static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
b2fbd044
LZ
1389 [NFTA_CHAIN_TABLE] = { .type = NLA_STRING,
1390 .len = NFT_TABLE_MAXNAMELEN - 1 },
96518518
PM
1391 [NFTA_CHAIN_HANDLE] = { .type = NLA_U64 },
1392 [NFTA_CHAIN_NAME] = { .type = NLA_STRING,
1393 .len = NFT_CHAIN_MAXNAMELEN - 1 },
1394 [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED },
0ca743a5 1395 [NFTA_CHAIN_POLICY] = { .type = NLA_U32 },
9332d27d
FW
1396 [NFTA_CHAIN_TYPE] = { .type = NLA_STRING,
1397 .len = NFT_MODULE_AUTOLOAD_LIMIT },
0ca743a5 1398 [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED },
c9626a2c 1399 [NFTA_CHAIN_FLAGS] = { .type = NLA_U32 },
74cccc3d 1400 [NFTA_CHAIN_ID] = { .type = NLA_U32 },
002f2176
JGG
1401 [NFTA_CHAIN_USERDATA] = { .type = NLA_BINARY,
1402 .len = NFT_USERDATA_MAXLEN },
96518518
PM
1403};
1404
1405static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
1406 [NFTA_HOOK_HOOKNUM] = { .type = NLA_U32 },
1407 [NFTA_HOOK_PRIORITY] = { .type = NLA_U32 },
2cbce139
PNA
1408 [NFTA_HOOK_DEV] = { .type = NLA_STRING,
1409 .len = IFNAMSIZ - 1 },
96518518
PM
1410};
1411
0ca743a5
PNA
1412static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
1413{
1414 struct nft_stats *cpu_stats, total;
1415 struct nlattr *nest;
ce355e20
ED
1416 unsigned int seq;
1417 u64 pkts, bytes;
0ca743a5
PNA
1418 int cpu;
1419
edbd82c5
FW
1420 if (!stats)
1421 return 0;
1422
0ca743a5
PNA
1423 memset(&total, 0, sizeof(total));
1424 for_each_possible_cpu(cpu) {
1425 cpu_stats = per_cpu_ptr(stats, cpu);
ce355e20
ED
1426 do {
1427 seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
1428 pkts = cpu_stats->pkts;
1429 bytes = cpu_stats->bytes;
1430 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
1431 total.pkts += pkts;
1432 total.bytes += bytes;
0ca743a5 1433 }
ae0be8de 1434 nest = nla_nest_start_noflag(skb, NFTA_CHAIN_COUNTERS);
0ca743a5
PNA
1435 if (nest == NULL)
1436 goto nla_put_failure;
1437
b46f6ded
ND
1438 if (nla_put_be64(skb, NFTA_COUNTER_PACKETS, cpu_to_be64(total.pkts),
1439 NFTA_COUNTER_PAD) ||
1440 nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
1441 NFTA_COUNTER_PAD))
0ca743a5
PNA
1442 goto nla_put_failure;
1443
1444 nla_nest_end(skb, nest);
1445 return 0;
1446
1447nla_put_failure:
1448 return -ENOSPC;
1449}
1450
d54725cd
PNA
1451static int nft_dump_basechain_hook(struct sk_buff *skb, int family,
1452 const struct nft_base_chain *basechain)
1453{
1454 const struct nf_hook_ops *ops = &basechain->ops;
1455 struct nft_hook *hook, *first = NULL;
1456 struct nlattr *nest, *nest_devs;
1457 int n = 0;
1458
1459 nest = nla_nest_start_noflag(skb, NFTA_CHAIN_HOOK);
1460 if (nest == NULL)
1461 goto nla_put_failure;
1462 if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum)))
1463 goto nla_put_failure;
1464 if (nla_put_be32(skb, NFTA_HOOK_PRIORITY, htonl(ops->priority)))
1465 goto nla_put_failure;
1466
d3519cb8 1467 if (nft_base_chain_netdev(family, ops->hooknum)) {
d54725cd
PNA
1468 nest_devs = nla_nest_start_noflag(skb, NFTA_HOOK_DEVS);
1469 list_for_each_entry(hook, &basechain->hook_list, list) {
1470 if (!first)
1471 first = hook;
1472
1473 if (nla_put_string(skb, NFTA_DEVICE_NAME,
1474 hook->ops.dev->name))
1475 goto nla_put_failure;
1476 n++;
1477 }
1478 nla_nest_end(skb, nest_devs);
1479
1480 if (n == 1 &&
1481 nla_put_string(skb, NFTA_HOOK_DEV, first->ops.dev->name))
1482 goto nla_put_failure;
1483 }
1484 nla_nest_end(skb, nest);
1485
1486 return 0;
1487nla_put_failure:
1488 return -1;
1489}
1490
84d7fce6
PNA
1491static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
1492 u32 portid, u32 seq, int event, u32 flags,
1493 int family, const struct nft_table *table,
96518518
PM
1494 const struct nft_chain *chain)
1495{
1496 struct nlmsghdr *nlh;
96518518 1497
dedb67c4 1498 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
19c28b13
PNA
1499 nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
1500 NFNETLINK_V0, nft_base_seq(net));
1501 if (!nlh)
96518518
PM
1502 goto nla_put_failure;
1503
96518518
PM
1504 if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
1505 goto nla_put_failure;
b46f6ded
ND
1506 if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
1507 NFTA_CHAIN_PAD))
96518518
PM
1508 goto nla_put_failure;
1509 if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
1510 goto nla_put_failure;
1511
f323d954 1512 if (nft_is_base_chain(chain)) {
0ca743a5 1513 const struct nft_base_chain *basechain = nft_base_chain(chain);
edbd82c5 1514 struct nft_stats __percpu *stats;
0ca743a5 1515
d54725cd 1516 if (nft_dump_basechain_hook(skb, family, basechain))
2cbce139 1517 goto nla_put_failure;
9370761c 1518
0ca743a5
PNA
1519 if (nla_put_be32(skb, NFTA_CHAIN_POLICY,
1520 htonl(basechain->policy)))
1521 goto nla_put_failure;
1522
baae3e62
PM
1523 if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name))
1524 goto nla_put_failure;
0ca743a5 1525
edbd82c5
FW
1526 stats = rcu_dereference_check(basechain->stats,
1527 lockdep_commit_lock_is_held(net));
1528 if (nft_dump_stats(skb, stats))
0ca743a5 1529 goto nla_put_failure;
96518518
PM
1530 }
1531
d0e2c7de
PNA
1532 if (chain->flags &&
1533 nla_put_be32(skb, NFTA_CHAIN_FLAGS, htonl(chain->flags)))
1534 goto nla_put_failure;
1535
0ca743a5
PNA
1536 if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
1537 goto nla_put_failure;
1538
002f2176
JGG
1539 if (chain->udata &&
1540 nla_put(skb, NFTA_CHAIN_USERDATA, chain->udlen, chain->udata))
1541 goto nla_put_failure;
1542
053c095a
JB
1543 nlmsg_end(skb, nlh);
1544 return 0;
96518518
PM
1545
1546nla_put_failure:
1547 nlmsg_trim(skb, nlh);
1548 return -1;
1549}
1550
25e94a99 1551static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
96518518 1552{
0854db2a 1553 struct nftables_pernet *nft_net;
96518518 1554 struct sk_buff *skb;
96518518
PM
1555 int err;
1556
128ad332
PNA
1557 if (!ctx->report &&
1558 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 1559 return;
96518518 1560
96518518
PM
1561 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1562 if (skb == NULL)
1563 goto err;
1564
84d7fce6 1565 err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
36596dad 1566 event, 0, ctx->family, ctx->table,
35151d84 1567 ctx->chain);
96518518
PM
1568 if (err < 0) {
1569 kfree_skb(skb);
1570 goto err;
1571 }
1572
0854db2a
FW
1573 nft_net = net_generic(ctx->net, nf_tables_net_id);
1574 nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
25e94a99 1575 return;
96518518 1576err:
25e94a99 1577 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
1578}
1579
1580static int nf_tables_dump_chains(struct sk_buff *skb,
1581 struct netlink_callback *cb)
1582{
1583 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
96518518
PM
1584 const struct nft_table *table;
1585 const struct nft_chain *chain;
1586 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 1587 struct net *net = sock_net(skb->sk);
96518518 1588 int family = nfmsg->nfgen_family;
0854db2a 1589 struct nftables_pernet *nft_net;
96518518 1590
e688a7f8 1591 rcu_read_lock();
0854db2a
FW
1592 nft_net = net_generic(net, nf_tables_net_id);
1593 cb->seq = nft_net->base_seq;
38e029f1 1594
0854db2a 1595 list_for_each_entry_rcu(table, &nft_net->tables, list) {
98319cb9 1596 if (family != NFPROTO_UNSPEC && family != table->family)
96518518
PM
1597 continue;
1598
36596dad
PNA
1599 list_for_each_entry_rcu(chain, &table->chains, list) {
1600 if (idx < s_idx)
1601 goto cont;
1602 if (idx > s_idx)
1603 memset(&cb->args[1], 0,
1604 sizeof(cb->args) - sizeof(cb->args[0]));
1605 if (!nft_is_active(net, chain))
1606 continue;
1607 if (nf_tables_fill_chain_info(skb, net,
1608 NETLINK_CB(cb->skb).portid,
1609 cb->nlh->nlmsg_seq,
1610 NFT_MSG_NEWCHAIN,
1611 NLM_F_MULTI,
98319cb9 1612 table->family, table,
36596dad
PNA
1613 chain) < 0)
1614 goto done;
38e029f1 1615
36596dad 1616 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518 1617cont:
36596dad 1618 idx++;
96518518
PM
1619 }
1620 }
1621done:
e688a7f8 1622 rcu_read_unlock();
96518518
PM
1623 cb->args[0] = idx;
1624 return skb->len;
1625}
1626
d9adf22a 1627/* called with rcu_read_lock held */
7b8002a1
PNA
1628static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1629 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1630 const struct nlattr * const nla[],
1631 struct netlink_ext_ack *extack)
96518518
PM
1632{
1633 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1634 u8 genmask = nft_genmask_cur(net);
96518518 1635 const struct nft_chain *chain;
1b2470e5 1636 struct nft_table *table;
96518518
PM
1637 struct sk_buff *skb2;
1638 int family = nfmsg->nfgen_family;
1639 int err;
1640
1641 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1642 struct netlink_dump_control c = {
1643 .dump = nf_tables_dump_chains,
d9adf22a 1644 .module = THIS_MODULE,
96518518 1645 };
d9adf22a
FW
1646
1647 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
96518518
PM
1648 }
1649
6001a930 1650 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask, 0);
36dd1bcc
PNA
1651 if (IS_ERR(table)) {
1652 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_TABLE]);
96518518 1653 return PTR_ERR(table);
36dd1bcc 1654 }
96518518 1655
f102d66b 1656 chain = nft_chain_lookup(net, table, nla[NFTA_CHAIN_NAME], genmask);
36dd1bcc
PNA
1657 if (IS_ERR(chain)) {
1658 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_NAME]);
96518518 1659 return PTR_ERR(chain);
36dd1bcc 1660 }
96518518 1661
d9adf22a 1662 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
96518518
PM
1663 if (!skb2)
1664 return -ENOMEM;
1665
84d7fce6 1666 err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
1667 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
1668 family, table, chain);
1669 if (err < 0)
ee921183 1670 goto err_fill_chain_info;
96518518 1671
ee921183 1672 return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
96518518 1673
ee921183 1674err_fill_chain_info:
96518518
PM
1675 kfree_skb(skb2);
1676 return err;
1677}
1678
0ca743a5
PNA
1679static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
1680 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
1681 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
1682};
1683
ff3cd7b3 1684static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
0ca743a5
PNA
1685{
1686 struct nlattr *tb[NFTA_COUNTER_MAX+1];
1687 struct nft_stats __percpu *newstats;
1688 struct nft_stats *stats;
1689 int err;
1690
8cb08174
JB
1691 err = nla_parse_nested_deprecated(tb, NFTA_COUNTER_MAX, attr,
1692 nft_counter_policy, NULL);
0ca743a5 1693 if (err < 0)
ff3cd7b3 1694 return ERR_PTR(err);
0ca743a5
PNA
1695
1696 if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
ff3cd7b3 1697 return ERR_PTR(-EINVAL);
0ca743a5 1698
ce355e20 1699 newstats = netdev_alloc_pcpu_stats(struct nft_stats);
0ca743a5 1700 if (newstats == NULL)
ff3cd7b3 1701 return ERR_PTR(-ENOMEM);
0ca743a5
PNA
1702
1703 /* Restore old counters on this cpu, no problem. Per-cpu statistics
1704 * are not exposed to userspace.
1705 */
e8781f70 1706 preempt_disable();
0ca743a5
PNA
1707 stats = this_cpu_ptr(newstats);
1708 stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
1709 stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
e8781f70 1710 preempt_enable();
0ca743a5 1711
ff3cd7b3
PNA
1712 return newstats;
1713}
1714
53315ac6 1715static void nft_chain_stats_replace(struct nft_trans *trans)
ff3cd7b3 1716{
53315ac6 1717 struct nft_base_chain *chain = nft_base_chain(trans->ctx.chain);
0befd061 1718
53315ac6 1719 if (!nft_trans_chain_stats(trans))
b88825de
PNA
1720 return;
1721
b685b534
PM
1722 nft_trans_chain_stats(trans) =
1723 rcu_replace_pointer(chain->stats, nft_trans_chain_stats(trans),
1724 lockdep_commit_lock_is_held(trans->ctx.net));
53315ac6
FW
1725
1726 if (!nft_trans_chain_stats(trans))
bbb8c61f 1727 static_branch_inc(&nft_counters_enabled);
0ca743a5
PNA
1728}
1729
0cbc06b3
FW
1730static void nf_tables_chain_free_chain_rules(struct nft_chain *chain)
1731{
1732 struct nft_rule **g0 = rcu_dereference_raw(chain->rules_gen_0);
1733 struct nft_rule **g1 = rcu_dereference_raw(chain->rules_gen_1);
1734
1735 if (g0 != g1)
1736 kvfree(g1);
1737 kvfree(g0);
1738
1739 /* should be NULL either via abort or via successful commit */
1740 WARN_ON_ONCE(chain->rules_next);
1741 kvfree(chain->rules_next);
1742}
1743
d0e2c7de 1744void nf_tables_chain_destroy(struct nft_ctx *ctx)
91c7b38d 1745{
43a605f2 1746 struct nft_chain *chain = ctx->chain;
d54725cd 1747 struct nft_hook *hook, *next;
43a605f2 1748
fa5950e4
FW
1749 if (WARN_ON(chain->use > 0))
1750 return;
91c7b38d 1751
0cbc06b3
FW
1752 /* no concurrent access possible anymore */
1753 nf_tables_chain_free_chain_rules(chain);
1754
f323d954 1755 if (nft_is_base_chain(chain)) {
2cbce139
PNA
1756 struct nft_base_chain *basechain = nft_base_chain(chain);
1757
d3519cb8 1758 if (nft_base_chain_netdev(ctx->family, basechain->ops.hooknum)) {
d54725cd
PNA
1759 list_for_each_entry_safe(hook, next,
1760 &basechain->hook_list, list) {
1761 list_del_rcu(&hook->list);
1762 kfree_rcu(hook, rcu);
1763 }
1764 }
2cbce139 1765 module_put(basechain->type->owner);
4c05ec47 1766 if (rcu_access_pointer(basechain->stats)) {
9f08ea84 1767 static_branch_dec(&nft_counters_enabled);
4c05ec47
TY
1768 free_percpu(rcu_dereference_raw(basechain->stats));
1769 }
b7263e07 1770 kfree(chain->name);
002f2176 1771 kfree(chain->udata);
2cbce139 1772 kfree(basechain);
91c7b38d 1773 } else {
b7263e07 1774 kfree(chain->name);
002f2176 1775 kfree(chain->udata);
91c7b38d
PNA
1776 kfree(chain);
1777 }
1778}
1779
3f0465a9
PNA
1780static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
1781 const struct nlattr *attr)
1782{
1783 struct net_device *dev;
1784 char ifname[IFNAMSIZ];
1785 struct nft_hook *hook;
1786 int err;
1787
1788 hook = kmalloc(sizeof(struct nft_hook), GFP_KERNEL);
1789 if (!hook) {
1790 err = -ENOMEM;
1791 goto err_hook_alloc;
1792 }
1793
872f6903 1794 nla_strscpy(ifname, attr, IFNAMSIZ);
42f1c271
PNA
1795 /* nf_tables_netdev_event() is called under rtnl_mutex, this is
1796 * indirectly serializing all the other holders of the commit_mutex with
1797 * the rtnl_mutex.
1798 */
3f0465a9
PNA
1799 dev = __dev_get_by_name(net, ifname);
1800 if (!dev) {
1801 err = -ENOENT;
1802 goto err_hook_dev;
1803 }
1804 hook->ops.dev = dev;
abadb2f8 1805 hook->inactive = false;
3f0465a9
PNA
1806
1807 return hook;
1808
1809err_hook_dev:
1810 kfree(hook);
1811err_hook_alloc:
1812 return ERR_PTR(err);
1813}
1814
abadb2f8
PNA
1815static struct nft_hook *nft_hook_list_find(struct list_head *hook_list,
1816 const struct nft_hook *this)
b75a3e83
PNA
1817{
1818 struct nft_hook *hook;
1819
1820 list_for_each_entry(hook, hook_list, list) {
1821 if (this->ops.dev == hook->ops.dev)
abadb2f8 1822 return hook;
b75a3e83
PNA
1823 }
1824
abadb2f8 1825 return NULL;
b75a3e83
PNA
1826}
1827
3f0465a9
PNA
1828static int nf_tables_parse_netdev_hooks(struct net *net,
1829 const struct nlattr *attr,
1830 struct list_head *hook_list)
1831{
1832 struct nft_hook *hook, *next;
1833 const struct nlattr *tmp;
1834 int rem, n = 0, err;
1835
1836 nla_for_each_nested(tmp, attr, rem) {
1837 if (nla_type(tmp) != NFTA_DEVICE_NAME) {
1838 err = -EINVAL;
1839 goto err_hook;
1840 }
1841
1842 hook = nft_netdev_hook_alloc(net, tmp);
1843 if (IS_ERR(hook)) {
1844 err = PTR_ERR(hook);
1845 goto err_hook;
1846 }
b75a3e83 1847 if (nft_hook_list_find(hook_list, hook)) {
cd77e75b 1848 kfree(hook);
b75a3e83
PNA
1849 err = -EEXIST;
1850 goto err_hook;
1851 }
3f0465a9
PNA
1852 list_add_tail(&hook->list, hook_list);
1853 n++;
1854
cb662ac6 1855 if (n == NFT_NETDEVICE_MAX) {
3f0465a9
PNA
1856 err = -EFBIG;
1857 goto err_hook;
1858 }
1859 }
3f0465a9
PNA
1860
1861 return 0;
1862
1863err_hook:
1864 list_for_each_entry_safe(hook, next, hook_list, list) {
1865 list_del(&hook->list);
1866 kfree(hook);
1867 }
1868 return err;
1869}
1870
508f8ccd
PNA
1871struct nft_chain_hook {
1872 u32 num;
84ba7dd7 1873 s32 priority;
32537e91 1874 const struct nft_chain_type *type;
d54725cd 1875 struct list_head list;
508f8ccd
PNA
1876};
1877
d54725cd
PNA
1878static int nft_chain_parse_netdev(struct net *net,
1879 struct nlattr *tb[],
1880 struct list_head *hook_list)
1881{
1882 struct nft_hook *hook;
1883 int err;
1884
1885 if (tb[NFTA_HOOK_DEV]) {
1886 hook = nft_netdev_hook_alloc(net, tb[NFTA_HOOK_DEV]);
1887 if (IS_ERR(hook))
1888 return PTR_ERR(hook);
1889
1890 list_add_tail(&hook->list, hook_list);
1891 } else if (tb[NFTA_HOOK_DEVS]) {
1892 err = nf_tables_parse_netdev_hooks(net, tb[NFTA_HOOK_DEVS],
1893 hook_list);
1894 if (err < 0)
1895 return err;
05abe445
PNA
1896
1897 if (list_empty(hook_list))
1898 return -EINVAL;
d54725cd
PNA
1899 } else {
1900 return -EINVAL;
1901 }
1902
1903 return 0;
1904}
1905
508f8ccd
PNA
1906static int nft_chain_parse_hook(struct net *net,
1907 const struct nlattr * const nla[],
36596dad 1908 struct nft_chain_hook *hook, u8 family,
445509eb 1909 bool autoload)
508f8ccd 1910{
0854db2a 1911 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
508f8ccd 1912 struct nlattr *ha[NFTA_HOOK_MAX + 1];
32537e91 1913 const struct nft_chain_type *type;
508f8ccd
PNA
1914 int err;
1915
0854db2a 1916 lockdep_assert_held(&nft_net->commit_mutex);
f102d66b
FW
1917 lockdep_nfnl_nft_mutex_not_held();
1918
8cb08174
JB
1919 err = nla_parse_nested_deprecated(ha, NFTA_HOOK_MAX,
1920 nla[NFTA_CHAIN_HOOK],
1921 nft_hook_policy, NULL);
508f8ccd
PNA
1922 if (err < 0)
1923 return err;
1924
1925 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
1926 ha[NFTA_HOOK_PRIORITY] == NULL)
1927 return -EINVAL;
1928
1929 hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
508f8ccd
PNA
1930 hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
1931
82603549
PNA
1932 type = __nft_chain_type_get(family, NFT_CHAIN_T_DEFAULT);
1933 if (!type)
1934 return -EOPNOTSUPP;
1935
508f8ccd 1936 if (nla[NFTA_CHAIN_TYPE]) {
452238e8 1937 type = nf_tables_chain_type_lookup(net, nla[NFTA_CHAIN_TYPE],
445509eb 1938 family, autoload);
508f8ccd
PNA
1939 if (IS_ERR(type))
1940 return PTR_ERR(type);
1941 }
d25e2e93 1942 if (hook->num >= NFT_MAX_HOOKS || !(type->hook_mask & (1 << hook->num)))
508f8ccd 1943 return -EOPNOTSUPP;
84ba7dd7
FW
1944
1945 if (type->type == NFT_CHAIN_T_NAT &&
1946 hook->priority <= NF_IP_PRI_CONNTRACK)
1947 return -EOPNOTSUPP;
1948
508f8ccd
PNA
1949 if (!try_module_get(type->owner))
1950 return -ENOENT;
1951
1952 hook->type = type;
1953
d54725cd 1954 INIT_LIST_HEAD(&hook->list);
d3519cb8 1955 if (nft_base_chain_netdev(family, hook->num)) {
d54725cd
PNA
1956 err = nft_chain_parse_netdev(net, ha, &hook->list);
1957 if (err < 0) {
508f8ccd 1958 module_put(type->owner);
d54725cd 1959 return err;
508f8ccd 1960 }
d54725cd 1961 } else if (ha[NFTA_HOOK_DEV] || ha[NFTA_HOOK_DEVS]) {
508f8ccd
PNA
1962 module_put(type->owner);
1963 return -EOPNOTSUPP;
1964 }
1965
1966 return 0;
1967}
1968
1969static void nft_chain_release_hook(struct nft_chain_hook *hook)
1970{
d54725cd
PNA
1971 struct nft_hook *h, *next;
1972
1973 list_for_each_entry_safe(h, next, &hook->list, list) {
1974 list_del(&h->list);
1975 kfree(h);
1976 }
508f8ccd 1977 module_put(hook->type->owner);
508f8ccd
PNA
1978}
1979
0cbc06b3
FW
1980struct nft_rules_old {
1981 struct rcu_head h;
1982 struct nft_rule **start;
1983};
1984
1985static struct nft_rule **nf_tables_chain_alloc_rules(const struct nft_chain *chain,
1986 unsigned int alloc)
1987{
1988 if (alloc > INT_MAX)
1989 return NULL;
1990
1991 alloc += 1; /* NULL, ends rules */
1992 if (sizeof(struct nft_rule *) > INT_MAX / alloc)
1993 return NULL;
1994
1995 alloc *= sizeof(struct nft_rule *);
1996 alloc += sizeof(struct nft_rules_old);
1997
1998 return kvmalloc(alloc, GFP_KERNEL);
1999}
2000
d54725cd
PNA
2001static void nft_basechain_hook_init(struct nf_hook_ops *ops, u8 family,
2002 const struct nft_chain_hook *hook,
2003 struct nft_chain *chain)
2004{
2005 ops->pf = family;
2006 ops->hooknum = hook->num;
2007 ops->priority = hook->priority;
2008 ops->priv = chain;
2009 ops->hook = hook->type->hooks[ops->hooknum];
2010}
2011
2012static int nft_basechain_init(struct nft_base_chain *basechain, u8 family,
2013 struct nft_chain_hook *hook, u32 flags)
2014{
2015 struct nft_chain *chain;
2016 struct nft_hook *h;
2017
2018 basechain->type = hook->type;
2019 INIT_LIST_HEAD(&basechain->hook_list);
2020 chain = &basechain->chain;
2021
d3519cb8 2022 if (nft_base_chain_netdev(family, hook->num)) {
d54725cd
PNA
2023 list_splice_init(&hook->list, &basechain->hook_list);
2024 list_for_each_entry(h, &basechain->hook_list, list)
2025 nft_basechain_hook_init(&h->ops, family, hook, chain);
2026
2027 basechain->ops.hooknum = hook->num;
2028 basechain->ops.priority = hook->priority;
2029 } else {
2030 nft_basechain_hook_init(&basechain->ops, family, hook, chain);
2031 }
2032
67c49de4 2033 chain->flags |= NFT_CHAIN_BASE | flags;
d54725cd
PNA
2034 basechain->policy = NF_ACCEPT;
2035 if (chain->flags & NFT_CHAIN_HW_OFFLOAD &&
2036 nft_chain_offload_priority(basechain) < 0)
2037 return -EOPNOTSUPP;
2038
2039 flow_block_init(&basechain->flow_block);
2040
2041 return 0;
2042}
2043
04b7db41
PNA
2044static int nft_chain_add(struct nft_table *table, struct nft_chain *chain)
2045{
2046 int err;
2047
2048 err = rhltable_insert_key(&table->chains_ht, chain->name,
2049 &chain->rhlhead, nft_chain_ht_params);
2050 if (err)
2051 return err;
2052
2053 list_add_tail_rcu(&chain->list, &table->chains);
2054
2055 return 0;
2056}
2057
d0e2c7de
PNA
2058static u64 chain_id;
2059
4035285f 2060static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
c9626a2c 2061 u8 policy, u32 flags)
4035285f
PNA
2062{
2063 const struct nlattr * const *nla = ctx->nla;
2064 struct nft_table *table = ctx->table;
4035285f
PNA
2065 struct nft_base_chain *basechain;
2066 struct nft_stats __percpu *stats;
2067 struct net *net = ctx->net;
d0e2c7de 2068 char name[NFT_NAME_MAXLEN];
66293c46 2069 struct nft_trans *trans;
4035285f 2070 struct nft_chain *chain;
0cbc06b3 2071 struct nft_rule **rules;
4035285f
PNA
2072 int err;
2073
2074 if (table->use == UINT_MAX)
2075 return -EOVERFLOW;
2076
2077 if (nla[NFTA_CHAIN_HOOK]) {
2078 struct nft_chain_hook hook;
4035285f 2079
d0e2c7de
PNA
2080 if (flags & NFT_CHAIN_BINDING)
2081 return -EOPNOTSUPP;
2082
445509eb 2083 err = nft_chain_parse_hook(net, nla, &hook, family, true);
4035285f
PNA
2084 if (err < 0)
2085 return err;
2086
2087 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
2088 if (basechain == NULL) {
2089 nft_chain_release_hook(&hook);
2090 return -ENOMEM;
2091 }
d54725cd 2092 chain = &basechain->chain;
4035285f
PNA
2093
2094 if (nla[NFTA_CHAIN_COUNTERS]) {
2095 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
2096 if (IS_ERR(stats)) {
2097 nft_chain_release_hook(&hook);
2098 kfree(basechain);
2099 return PTR_ERR(stats);
2100 }
4c05ec47 2101 rcu_assign_pointer(basechain->stats, stats);
4035285f
PNA
2102 static_branch_inc(&nft_counters_enabled);
2103 }
2104
d54725cd
PNA
2105 err = nft_basechain_init(basechain, family, &hook, flags);
2106 if (err < 0) {
2107 nft_chain_release_hook(&hook);
2108 kfree(basechain);
2109 return err;
2110 }
4035285f 2111 } else {
d0e2c7de
PNA
2112 if (flags & NFT_CHAIN_BASE)
2113 return -EINVAL;
2114 if (flags & NFT_CHAIN_HW_OFFLOAD)
2115 return -EOPNOTSUPP;
2116
4035285f
PNA
2117 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
2118 if (chain == NULL)
2119 return -ENOMEM;
d0e2c7de
PNA
2120
2121 chain->flags = flags;
4035285f 2122 }
43a605f2
PNA
2123 ctx->chain = chain;
2124
4035285f
PNA
2125 INIT_LIST_HEAD(&chain->rules);
2126 chain->handle = nf_tables_alloc_handle(table);
2127 chain->table = table;
d0e2c7de
PNA
2128
2129 if (nla[NFTA_CHAIN_NAME]) {
2130 chain->name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
2131 } else {
59136aa3
FW
2132 if (!(flags & NFT_CHAIN_BINDING)) {
2133 err = -EINVAL;
002f2176 2134 goto err_destroy_chain;
59136aa3 2135 }
d0e2c7de
PNA
2136
2137 snprintf(name, sizeof(name), "__chain%llu", ++chain_id);
2138 chain->name = kstrdup(name, GFP_KERNEL);
2139 }
2140
4035285f
PNA
2141 if (!chain->name) {
2142 err = -ENOMEM;
002f2176
JGG
2143 goto err_destroy_chain;
2144 }
2145
2146 if (nla[NFTA_CHAIN_USERDATA]) {
2147 chain->udata = nla_memdup(nla[NFTA_CHAIN_USERDATA], GFP_KERNEL);
2148 if (chain->udata == NULL) {
2149 err = -ENOMEM;
2150 goto err_destroy_chain;
2151 }
2152 chain->udlen = nla_len(nla[NFTA_CHAIN_USERDATA]);
4035285f
PNA
2153 }
2154
0cbc06b3
FW
2155 rules = nf_tables_chain_alloc_rules(chain, 0);
2156 if (!rules) {
2157 err = -ENOMEM;
002f2176 2158 goto err_destroy_chain;
0cbc06b3
FW
2159 }
2160
2161 *rules = NULL;
2162 rcu_assign_pointer(chain->rules_gen_0, rules);
2163 rcu_assign_pointer(chain->rules_gen_1, rules);
2164
c974a3a3 2165 err = nf_tables_register_hook(net, table, chain);
4035285f 2166 if (err < 0)
002f2176 2167 goto err_destroy_chain;
4035285f 2168
66293c46
FW
2169 trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
2170 if (IS_ERR(trans)) {
2171 err = PTR_ERR(trans);
002f2176 2172 goto err_unregister_hook;
1b2470e5 2173 }
4035285f 2174
ad652f38 2175 nft_trans_chain_policy(trans) = NFT_CHAIN_POLICY_UNSET;
66293c46
FW
2176 if (nft_is_base_chain(chain))
2177 nft_trans_chain_policy(trans) = policy;
2178
04b7db41
PNA
2179 err = nft_chain_add(table, chain);
2180 if (err < 0) {
2181 nft_trans_destroy(trans);
002f2176 2182 goto err_unregister_hook;
04b7db41
PNA
2183 }
2184
4035285f 2185 table->use++;
4035285f
PNA
2186
2187 return 0;
002f2176 2188err_unregister_hook:
c974a3a3 2189 nf_tables_unregister_hook(net, table, chain);
002f2176 2190err_destroy_chain:
43a605f2 2191 nf_tables_chain_destroy(ctx);
4035285f
PNA
2192
2193 return err;
2194}
2195
d54725cd
PNA
2196static bool nft_hook_list_equal(struct list_head *hook_list1,
2197 struct list_head *hook_list2)
2198{
2199 struct nft_hook *hook;
2200 int n = 0, m = 0;
2201
2202 n = 0;
2203 list_for_each_entry(hook, hook_list2, list) {
2204 if (!nft_hook_list_find(hook_list1, hook))
2205 return false;
2206
2207 n++;
2208 }
2209 list_for_each_entry(hook, hook_list1, list)
2210 m++;
2211
2212 return n == m;
2213}
2214
c9626a2c 2215static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
98a381a7
PNA
2216 u32 flags, const struct nlattr *attr,
2217 struct netlink_ext_ack *extack)
2c4a488a
PNA
2218{
2219 const struct nlattr * const *nla = ctx->nla;
2220 struct nft_table *table = ctx->table;
2221 struct nft_chain *chain = ctx->chain;
2c4a488a
PNA
2222 struct nft_base_chain *basechain;
2223 struct nft_stats *stats = NULL;
2224 struct nft_chain_hook hook;
2c4a488a
PNA
2225 struct nf_hook_ops *ops;
2226 struct nft_trans *trans;
c974a3a3 2227 int err;
2c4a488a 2228
c9626a2c
PNA
2229 if (chain->flags ^ flags)
2230 return -EOPNOTSUPP;
2231
2c4a488a 2232 if (nla[NFTA_CHAIN_HOOK]) {
98a381a7
PNA
2233 if (!nft_is_base_chain(chain)) {
2234 NL_SET_BAD_ATTR(extack, attr);
77a92189 2235 return -EEXIST;
98a381a7 2236 }
36596dad 2237 err = nft_chain_parse_hook(ctx->net, nla, &hook, ctx->family,
445509eb 2238 false);
2c4a488a
PNA
2239 if (err < 0)
2240 return err;
2241
2242 basechain = nft_base_chain(chain);
2243 if (basechain->type != hook.type) {
2244 nft_chain_release_hook(&hook);
98a381a7 2245 NL_SET_BAD_ATTR(extack, attr);
77a92189 2246 return -EEXIST;
2c4a488a
PNA
2247 }
2248
d3519cb8 2249 if (nft_base_chain_netdev(ctx->family, hook.num)) {
d54725cd
PNA
2250 if (!nft_hook_list_equal(&basechain->hook_list,
2251 &hook.list)) {
2252 nft_chain_release_hook(&hook);
98a381a7 2253 NL_SET_BAD_ATTR(extack, attr);
77a92189 2254 return -EEXIST;
d54725cd
PNA
2255 }
2256 } else {
2257 ops = &basechain->ops;
2258 if (ops->hooknum != hook.num ||
2259 ops->priority != hook.priority) {
2260 nft_chain_release_hook(&hook);
98a381a7 2261 NL_SET_BAD_ATTR(extack, attr);
77a92189 2262 return -EEXIST;
d54725cd 2263 }
2c4a488a
PNA
2264 }
2265 nft_chain_release_hook(&hook);
2266 }
2267
2268 if (nla[NFTA_CHAIN_HANDLE] &&
2269 nla[NFTA_CHAIN_NAME]) {
2270 struct nft_chain *chain2;
2271
f102d66b
FW
2272 chain2 = nft_chain_lookup(ctx->net, table,
2273 nla[NFTA_CHAIN_NAME], genmask);
98a381a7
PNA
2274 if (!IS_ERR(chain2)) {
2275 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_NAME]);
0d18779b 2276 return -EEXIST;
98a381a7 2277 }
2c4a488a
PNA
2278 }
2279
2280 if (nla[NFTA_CHAIN_COUNTERS]) {
2281 if (!nft_is_base_chain(chain))
2282 return -EOPNOTSUPP;
2283
2284 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
2285 if (IS_ERR(stats))
2286 return PTR_ERR(stats);
2287 }
2288
c6cc94df 2289 err = -ENOMEM;
2c4a488a
PNA
2290 trans = nft_trans_alloc(ctx, NFT_MSG_NEWCHAIN,
2291 sizeof(struct nft_trans_chain));
c6cc94df
FW
2292 if (trans == NULL)
2293 goto err;
2c4a488a
PNA
2294
2295 nft_trans_chain_stats(trans) = stats;
2296 nft_trans_chain_update(trans) = true;
2297
2298 if (nla[NFTA_CHAIN_POLICY])
2299 nft_trans_chain_policy(trans) = policy;
2300 else
2301 nft_trans_chain_policy(trans) = -1;
2302
c6cc94df
FW
2303 if (nla[NFTA_CHAIN_HANDLE] &&
2304 nla[NFTA_CHAIN_NAME]) {
0854db2a 2305 struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
c6cc94df
FW
2306 struct nft_trans *tmp;
2307 char *name;
2308
2309 err = -ENOMEM;
2310 name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
2311 if (!name)
2312 goto err;
2313
2314 err = -EEXIST;
0854db2a 2315 list_for_each_entry(tmp, &nft_net->commit_list, list) {
c6cc94df
FW
2316 if (tmp->msg_type == NFT_MSG_NEWCHAIN &&
2317 tmp->ctx.table == table &&
2318 nft_trans_chain_update(tmp) &&
2319 nft_trans_chain_name(tmp) &&
2320 strcmp(name, nft_trans_chain_name(tmp)) == 0) {
98a381a7 2321 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_NAME]);
c6cc94df
FW
2322 kfree(name);
2323 goto err;
2324 }
2c4a488a 2325 }
c6cc94df
FW
2326
2327 nft_trans_chain_name(trans) = name;
2c4a488a 2328 }
0854db2a 2329 nft_trans_commit_list_add_tail(ctx->net, trans);
2c4a488a
PNA
2330
2331 return 0;
c6cc94df
FW
2332err:
2333 free_percpu(stats);
2334 kfree(trans);
2335 return err;
2c4a488a
PNA
2336}
2337
837830a4
PNA
2338static struct nft_chain *nft_chain_lookup_byid(const struct net *net,
2339 const struct nlattr *nla)
2340{
0854db2a 2341 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
837830a4
PNA
2342 u32 id = ntohl(nla_get_be32(nla));
2343 struct nft_trans *trans;
2344
0854db2a 2345 list_for_each_entry(trans, &nft_net->commit_list, list) {
837830a4
PNA
2346 struct nft_chain *chain = trans->ctx.chain;
2347
2348 if (trans->msg_type == NFT_MSG_NEWCHAIN &&
2349 id == nft_trans_chain_id(trans))
2350 return chain;
2351 }
2352 return ERR_PTR(-ENOENT);
2353}
2354
633c9a84
PNA
2355static int nf_tables_newchain(struct net *net, struct sock *nlsk,
2356 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2357 const struct nlattr * const nla[],
2358 struct netlink_ext_ack *extack)
96518518 2359{
0854db2a 2360 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
96518518 2361 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4035285f
PNA
2362 u8 genmask = nft_genmask_next(net);
2363 int family = nfmsg->nfgen_family;
74cccc3d 2364 struct nft_chain *chain = NULL;
36dd1bcc 2365 const struct nlattr *attr;
96518518 2366 struct nft_table *table;
57de2a0c 2367 u8 policy = NF_ACCEPT;
4035285f 2368 struct nft_ctx ctx;
96518518 2369 u64 handle = 0;
c9626a2c 2370 u32 flags = 0;
96518518 2371
0854db2a 2372 lockdep_assert_held(&nft_net->commit_mutex);
f102d66b 2373
6001a930
PNA
2374 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask,
2375 NETLINK_CB(skb).portid);
36dd1bcc
PNA
2376 if (IS_ERR(table)) {
2377 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_TABLE]);
96518518 2378 return PTR_ERR(table);
36dd1bcc 2379 }
96518518 2380
96518518 2381 chain = NULL;
36dd1bcc 2382 attr = nla[NFTA_CHAIN_NAME];
96518518
PM
2383
2384 if (nla[NFTA_CHAIN_HANDLE]) {
2385 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
cac20fcd 2386 chain = nft_chain_lookup_byhandle(table, handle, genmask);
36dd1bcc
PNA
2387 if (IS_ERR(chain)) {
2388 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_HANDLE]);
96518518 2389 return PTR_ERR(chain);
36dd1bcc
PNA
2390 }
2391 attr = nla[NFTA_CHAIN_HANDLE];
74cccc3d 2392 } else if (nla[NFTA_CHAIN_NAME]) {
f102d66b 2393 chain = nft_chain_lookup(net, table, attr, genmask);
96518518 2394 if (IS_ERR(chain)) {
36dd1bcc
PNA
2395 if (PTR_ERR(chain) != -ENOENT) {
2396 NL_SET_BAD_ATTR(extack, attr);
96518518 2397 return PTR_ERR(chain);
36dd1bcc 2398 }
96518518
PM
2399 chain = NULL;
2400 }
74cccc3d
PNA
2401 } else if (!nla[NFTA_CHAIN_ID]) {
2402 return -EINVAL;
96518518
PM
2403 }
2404
57de2a0c 2405 if (nla[NFTA_CHAIN_POLICY]) {
f323d954 2406 if (chain != NULL &&
36dd1bcc
PNA
2407 !nft_is_base_chain(chain)) {
2408 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_POLICY]);
d6b6cb1d 2409 return -EOPNOTSUPP;
36dd1bcc 2410 }
d6b6cb1d
PNA
2411
2412 if (chain == NULL &&
36dd1bcc
PNA
2413 nla[NFTA_CHAIN_HOOK] == NULL) {
2414 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_POLICY]);
57de2a0c 2415 return -EOPNOTSUPP;
36dd1bcc 2416 }
57de2a0c 2417
8f46df18 2418 policy = ntohl(nla_get_be32(nla[NFTA_CHAIN_POLICY]));
57de2a0c
PM
2419 switch (policy) {
2420 case NF_DROP:
2421 case NF_ACCEPT:
2422 break;
2423 default:
2424 return -EINVAL;
2425 }
2426 }
2427
c9626a2c
PNA
2428 if (nla[NFTA_CHAIN_FLAGS])
2429 flags = ntohl(nla_get_be32(nla[NFTA_CHAIN_FLAGS]));
b717273d
FW
2430 else if (chain)
2431 flags = chain->flags;
c9626a2c 2432
c1f79a2e
PNA
2433 if (flags & ~NFT_CHAIN_FLAGS)
2434 return -EOPNOTSUPP;
2435
98319cb9 2436 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
4035285f 2437
96518518 2438 if (chain != NULL) {
36dd1bcc
PNA
2439 if (nlh->nlmsg_flags & NLM_F_EXCL) {
2440 NL_SET_BAD_ATTR(extack, attr);
96518518 2441 return -EEXIST;
36dd1bcc 2442 }
96518518
PM
2443 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2444 return -EOPNOTSUPP;
2445
67c49de4 2446 flags |= chain->flags & NFT_CHAIN_BASE;
98a381a7
PNA
2447 return nf_tables_updchain(&ctx, genmask, policy, flags, attr,
2448 extack);
96518518
PM
2449 }
2450
c9626a2c 2451 return nf_tables_addchain(&ctx, family, genmask, policy, flags);
96518518
PM
2452}
2453
633c9a84
PNA
2454static int nf_tables_delchain(struct net *net, struct sock *nlsk,
2455 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2456 const struct nlattr * const nla[],
2457 struct netlink_ext_ack *extack)
96518518
PM
2458{
2459 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2460 u8 genmask = nft_genmask_next(net);
36dd1bcc
PNA
2461 int family = nfmsg->nfgen_family;
2462 const struct nlattr *attr;
96518518
PM
2463 struct nft_table *table;
2464 struct nft_chain *chain;
9dee1474 2465 struct nft_rule *rule;
91c7b38d 2466 struct nft_ctx ctx;
3ecbfd65 2467 u64 handle;
9dee1474
PNA
2468 u32 use;
2469 int err;
96518518 2470
6001a930
PNA
2471 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask,
2472 NETLINK_CB(skb).portid);
36dd1bcc
PNA
2473 if (IS_ERR(table)) {
2474 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_TABLE]);
96518518 2475 return PTR_ERR(table);
36dd1bcc 2476 }
96518518 2477
3ecbfd65 2478 if (nla[NFTA_CHAIN_HANDLE]) {
36dd1bcc
PNA
2479 attr = nla[NFTA_CHAIN_HANDLE];
2480 handle = be64_to_cpu(nla_get_be64(attr));
cac20fcd 2481 chain = nft_chain_lookup_byhandle(table, handle, genmask);
3ecbfd65 2482 } else {
36dd1bcc 2483 attr = nla[NFTA_CHAIN_NAME];
f102d66b 2484 chain = nft_chain_lookup(net, table, attr, genmask);
3ecbfd65 2485 }
36dd1bcc
PNA
2486 if (IS_ERR(chain)) {
2487 NL_SET_BAD_ATTR(extack, attr);
96518518 2488 return PTR_ERR(chain);
36dd1bcc 2489 }
9dee1474
PNA
2490
2491 if (nlh->nlmsg_flags & NLM_F_NONREC &&
2492 chain->use > 0)
96518518
PM
2493 return -EBUSY;
2494
98319cb9 2495 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
0165d932 2496
9dee1474
PNA
2497 use = chain->use;
2498 list_for_each_entry(rule, &chain->rules, list) {
2499 if (!nft_is_active_next(net, rule))
2500 continue;
2501 use--;
2502
2503 err = nft_delrule(&ctx, rule);
2504 if (err < 0)
2505 return err;
2506 }
2507
2508 /* There are rules and elements that are still holding references to us,
2509 * we cannot do a recursive removal in this case.
2510 */
36dd1bcc
PNA
2511 if (use > 0) {
2512 NL_SET_BAD_ATTR(extack, attr);
9dee1474 2513 return -EBUSY;
36dd1bcc 2514 }
9dee1474 2515
ee01d542 2516 return nft_delchain(&ctx);
96518518
PM
2517}
2518
96518518
PM
2519/*
2520 * Expressions
2521 */
2522
2523/**
ef1f7df9 2524 * nft_register_expr - register nf_tables expr type
3db86c39 2525 * @type: expr type
96518518 2526 *
ef1f7df9 2527 * Registers the expr type for use with nf_tables. Returns zero on
96518518
PM
2528 * success or a negative errno code otherwise.
2529 */
ef1f7df9 2530int nft_register_expr(struct nft_expr_type *type)
96518518
PM
2531{
2532 nfnl_lock(NFNL_SUBSYS_NFTABLES);
758dbcec 2533 if (type->family == NFPROTO_UNSPEC)
e688a7f8 2534 list_add_tail_rcu(&type->list, &nf_tables_expressions);
758dbcec 2535 else
e688a7f8 2536 list_add_rcu(&type->list, &nf_tables_expressions);
96518518
PM
2537 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2538 return 0;
2539}
2540EXPORT_SYMBOL_GPL(nft_register_expr);
2541
2542/**
ef1f7df9 2543 * nft_unregister_expr - unregister nf_tables expr type
3db86c39 2544 * @type: expr type
96518518 2545 *
ef1f7df9 2546 * Unregisters the expr typefor use with nf_tables.
96518518 2547 */
ef1f7df9 2548void nft_unregister_expr(struct nft_expr_type *type)
96518518
PM
2549{
2550 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 2551 list_del_rcu(&type->list);
96518518
PM
2552 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2553}
2554EXPORT_SYMBOL_GPL(nft_unregister_expr);
2555
64d46806
PM
2556static const struct nft_expr_type *__nft_expr_type_get(u8 family,
2557 struct nlattr *nla)
96518518 2558{
9cff126f 2559 const struct nft_expr_type *type, *candidate = NULL;
96518518 2560
ef1f7df9 2561 list_for_each_entry(type, &nf_tables_expressions, list) {
9cff126f
PNA
2562 if (!nla_strcmp(nla, type->name)) {
2563 if (!type->family && !candidate)
2564 candidate = type;
2565 else if (type->family == family)
2566 candidate = type;
2567 }
96518518 2568 }
9cff126f 2569 return candidate;
96518518
PM
2570}
2571
b9c04ae7
PNA
2572#ifdef CONFIG_MODULES
2573static int nft_expr_type_request_module(struct net *net, u8 family,
2574 struct nlattr *nla)
2575{
eb014de4
PNA
2576 if (nft_request_module(net, "nft-expr-%u-%.*s", family,
2577 nla_len(nla), (char *)nla_data(nla)) == -EAGAIN)
b9c04ae7
PNA
2578 return -EAGAIN;
2579
2580 return 0;
2581}
2582#endif
2583
452238e8
FW
2584static const struct nft_expr_type *nft_expr_type_get(struct net *net,
2585 u8 family,
64d46806 2586 struct nlattr *nla)
96518518 2587{
ef1f7df9 2588 const struct nft_expr_type *type;
96518518
PM
2589
2590 if (nla == NULL)
2591 return ERR_PTR(-EINVAL);
2592
64d46806 2593 type = __nft_expr_type_get(family, nla);
ef1f7df9
PM
2594 if (type != NULL && try_module_get(type->owner))
2595 return type;
96518518 2596
f102d66b 2597 lockdep_nfnl_nft_mutex_not_held();
96518518 2598#ifdef CONFIG_MODULES
ef1f7df9 2599 if (type == NULL) {
b9c04ae7 2600 if (nft_expr_type_request_module(net, family, nla) == -EAGAIN)
64d46806
PM
2601 return ERR_PTR(-EAGAIN);
2602
eb014de4
PNA
2603 if (nft_request_module(net, "nft-expr-%.*s",
2604 nla_len(nla),
2605 (char *)nla_data(nla)) == -EAGAIN)
96518518
PM
2606 return ERR_PTR(-EAGAIN);
2607 }
2608#endif
2609 return ERR_PTR(-ENOENT);
2610}
2611
2612static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
9332d27d
FW
2613 [NFTA_EXPR_NAME] = { .type = NLA_STRING,
2614 .len = NFT_MODULE_AUTOLOAD_LIMIT },
96518518
PM
2615 [NFTA_EXPR_DATA] = { .type = NLA_NESTED },
2616};
2617
2618static int nf_tables_fill_expr_info(struct sk_buff *skb,
2619 const struct nft_expr *expr)
2620{
ef1f7df9 2621 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
96518518
PM
2622 goto nla_put_failure;
2623
2624 if (expr->ops->dump) {
ae0be8de
MK
2625 struct nlattr *data = nla_nest_start_noflag(skb,
2626 NFTA_EXPR_DATA);
96518518
PM
2627 if (data == NULL)
2628 goto nla_put_failure;
2629 if (expr->ops->dump(skb, expr) < 0)
2630 goto nla_put_failure;
2631 nla_nest_end(skb, data);
2632 }
2633
2634 return skb->len;
2635
2636nla_put_failure:
2637 return -1;
2638};
2639
0b2d8a7b
PM
2640int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
2641 const struct nft_expr *expr)
2642{
2643 struct nlattr *nest;
2644
ae0be8de 2645 nest = nla_nest_start_noflag(skb, attr);
0b2d8a7b
PM
2646 if (!nest)
2647 goto nla_put_failure;
2648 if (nf_tables_fill_expr_info(skb, expr) < 0)
2649 goto nla_put_failure;
2650 nla_nest_end(skb, nest);
2651 return 0;
2652
2653nla_put_failure:
2654 return -1;
2655}
2656
96518518
PM
2657struct nft_expr_info {
2658 const struct nft_expr_ops *ops;
83d9dcba 2659 const struct nlattr *attr;
ef1f7df9 2660 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
96518518
PM
2661};
2662
0ca743a5
PNA
2663static int nf_tables_expr_parse(const struct nft_ctx *ctx,
2664 const struct nlattr *nla,
96518518
PM
2665 struct nft_expr_info *info)
2666{
ef1f7df9 2667 const struct nft_expr_type *type;
96518518 2668 const struct nft_expr_ops *ops;
ef1f7df9 2669 struct nlattr *tb[NFTA_EXPR_MAX + 1];
96518518
PM
2670 int err;
2671
8cb08174
JB
2672 err = nla_parse_nested_deprecated(tb, NFTA_EXPR_MAX, nla,
2673 nft_expr_policy, NULL);
96518518
PM
2674 if (err < 0)
2675 return err;
2676
452238e8 2677 type = nft_expr_type_get(ctx->net, ctx->family, tb[NFTA_EXPR_NAME]);
ef1f7df9
PM
2678 if (IS_ERR(type))
2679 return PTR_ERR(type);
2680
2681 if (tb[NFTA_EXPR_DATA]) {
8cb08174
JB
2682 err = nla_parse_nested_deprecated(info->tb, type->maxattr,
2683 tb[NFTA_EXPR_DATA],
2684 type->policy, NULL);
ef1f7df9
PM
2685 if (err < 0)
2686 goto err1;
2687 } else
2688 memset(info->tb, 0, sizeof(info->tb[0]) * (type->maxattr + 1));
2689
2690 if (type->select_ops != NULL) {
0ca743a5
PNA
2691 ops = type->select_ops(ctx,
2692 (const struct nlattr * const *)info->tb);
ef1f7df9
PM
2693 if (IS_ERR(ops)) {
2694 err = PTR_ERR(ops);
0ef1efd1
PNA
2695#ifdef CONFIG_MODULES
2696 if (err == -EAGAIN)
eb014de4
PNA
2697 if (nft_expr_type_request_module(ctx->net,
2698 ctx->family,
2699 tb[NFTA_EXPR_NAME]) != -EAGAIN)
2700 err = -ENOENT;
0ef1efd1 2701#endif
ef1f7df9
PM
2702 goto err1;
2703 }
2704 } else
2705 ops = type->ops;
2706
83d9dcba 2707 info->attr = nla;
96518518 2708 info->ops = ops;
83d9dcba 2709
96518518 2710 return 0;
ef1f7df9
PM
2711
2712err1:
2713 module_put(type->owner);
2714 return err;
96518518
PM
2715}
2716
2717static int nf_tables_newexpr(const struct nft_ctx *ctx,
ef1f7df9 2718 const struct nft_expr_info *info,
96518518
PM
2719 struct nft_expr *expr)
2720{
2721 const struct nft_expr_ops *ops = info->ops;
2722 int err;
2723
2724 expr->ops = ops;
2725 if (ops->init) {
ef1f7df9 2726 err = ops->init(ctx, expr, (const struct nlattr **)info->tb);
96518518
PM
2727 if (err < 0)
2728 goto err1;
2729 }
2730
96518518 2731 return 0;
96518518
PM
2732err1:
2733 expr->ops = NULL;
2734 return err;
2735}
2736
62472bce
PM
2737static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
2738 struct nft_expr *expr)
96518518 2739{
3f3a390d
PNA
2740 const struct nft_expr_type *type = expr->ops->type;
2741
96518518 2742 if (expr->ops->destroy)
62472bce 2743 expr->ops->destroy(ctx, expr);
3f3a390d 2744 module_put(type->owner);
96518518
PM
2745}
2746
795a6d6b
PNA
2747static struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
2748 const struct nlattr *nla)
0b2d8a7b
PM
2749{
2750 struct nft_expr_info info;
2751 struct nft_expr *expr;
b8e20400 2752 struct module *owner;
0b2d8a7b
PM
2753 int err;
2754
2755 err = nf_tables_expr_parse(ctx, nla, &info);
2756 if (err < 0)
2757 goto err1;
2758
2759 err = -ENOMEM;
2760 expr = kzalloc(info.ops->size, GFP_KERNEL);
2761 if (expr == NULL)
2762 goto err2;
2763
2764 err = nf_tables_newexpr(ctx, &info, expr);
2765 if (err < 0)
6cafaf47 2766 goto err3;
0b2d8a7b
PM
2767
2768 return expr;
6cafaf47
LZ
2769err3:
2770 kfree(expr);
0b2d8a7b 2771err2:
b8e20400
PNA
2772 owner = info.ops->type->owner;
2773 if (info.ops->type->release_ops)
2774 info.ops->type->release_ops(info.ops);
2775
2776 module_put(owner);
0b2d8a7b
PM
2777err1:
2778 return ERR_PTR(err);
2779}
2780
c604cc69
PNA
2781int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src)
2782{
2783 int err;
2784
2785 if (src->ops->clone) {
2786 dst->ops = src->ops;
2787 err = src->ops->clone(dst, src);
2788 if (err < 0)
2789 return err;
2790 } else {
2791 memcpy(dst, src, src->ops->size);
2792 }
2793
2794 __module_get(src->ops->type->owner);
2795
2796 return 0;
2797}
2798
0b2d8a7b
PM
2799void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
2800{
2801 nf_tables_expr_destroy(ctx, expr);
2802 kfree(expr);
2803}
2804
96518518
PM
2805/*
2806 * Rules
2807 */
2808
cac20fcd
PNA
2809static struct nft_rule *__nft_rule_lookup(const struct nft_chain *chain,
2810 u64 handle)
96518518
PM
2811{
2812 struct nft_rule *rule;
2813
2814 // FIXME: this sucks
d9adf22a 2815 list_for_each_entry_rcu(rule, &chain->rules, list) {
96518518
PM
2816 if (handle == rule->handle)
2817 return rule;
2818 }
2819
2820 return ERR_PTR(-ENOENT);
2821}
2822
cac20fcd
PNA
2823static struct nft_rule *nft_rule_lookup(const struct nft_chain *chain,
2824 const struct nlattr *nla)
96518518
PM
2825{
2826 if (nla == NULL)
2827 return ERR_PTR(-EINVAL);
2828
cac20fcd 2829 return __nft_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
96518518
PM
2830}
2831
2832static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
b2fbd044
LZ
2833 [NFTA_RULE_TABLE] = { .type = NLA_STRING,
2834 .len = NFT_TABLE_MAXNAMELEN - 1 },
96518518
PM
2835 [NFTA_RULE_CHAIN] = { .type = NLA_STRING,
2836 .len = NFT_CHAIN_MAXNAMELEN - 1 },
2837 [NFTA_RULE_HANDLE] = { .type = NLA_U64 },
2838 [NFTA_RULE_EXPRESSIONS] = { .type = NLA_NESTED },
0ca743a5 2839 [NFTA_RULE_COMPAT] = { .type = NLA_NESTED },
5e948466 2840 [NFTA_RULE_POSITION] = { .type = NLA_U64 },
0768b3b3
PNA
2841 [NFTA_RULE_USERDATA] = { .type = NLA_BINARY,
2842 .len = NFT_USERDATA_MAXLEN },
467697d2 2843 [NFTA_RULE_ID] = { .type = NLA_U32 },
0604628b 2844 [NFTA_RULE_POSITION_ID] = { .type = NLA_U32 },
837830a4 2845 [NFTA_RULE_CHAIN_ID] = { .type = NLA_U32 },
96518518
PM
2846};
2847
84d7fce6
PNA
2848static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
2849 u32 portid, u32 seq, int event,
2850 u32 flags, int family,
96518518
PM
2851 const struct nft_table *table,
2852 const struct nft_chain *chain,
2c82c7e7
FW
2853 const struct nft_rule *rule,
2854 const struct nft_rule *prule)
96518518
PM
2855{
2856 struct nlmsghdr *nlh;
96518518
PM
2857 const struct nft_expr *expr, *next;
2858 struct nlattr *list;
dedb67c4 2859 u16 type = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
96518518 2860
19c28b13
PNA
2861 nlh = nfnl_msg_put(skb, portid, seq, type, flags, family, NFNETLINK_V0,
2862 nft_base_seq(net));
2863 if (!nlh)
96518518
PM
2864 goto nla_put_failure;
2865
96518518
PM
2866 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
2867 goto nla_put_failure;
2868 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
2869 goto nla_put_failure;
b46f6ded
ND
2870 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle),
2871 NFTA_RULE_PAD))
96518518
PM
2872 goto nla_put_failure;
2873
2c82c7e7 2874 if (event != NFT_MSG_DELRULE && prule) {
5e948466 2875 if (nla_put_be64(skb, NFTA_RULE_POSITION,
b46f6ded
ND
2876 cpu_to_be64(prule->handle),
2877 NFTA_RULE_PAD))
5e948466
EL
2878 goto nla_put_failure;
2879 }
2880
b72920f6
PNA
2881 if (chain->flags & NFT_CHAIN_HW_OFFLOAD)
2882 nft_flow_rule_stats(chain, rule);
2883
ae0be8de 2884 list = nla_nest_start_noflag(skb, NFTA_RULE_EXPRESSIONS);
96518518
PM
2885 if (list == NULL)
2886 goto nla_put_failure;
2887 nft_rule_for_each_expr(expr, next, rule) {
0b2d8a7b 2888 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
96518518 2889 goto nla_put_failure;
96518518
PM
2890 }
2891 nla_nest_end(skb, list);
2892
86f1ec32
PM
2893 if (rule->udata) {
2894 struct nft_userdata *udata = nft_userdata(rule);
2895 if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
2896 udata->data) < 0)
2897 goto nla_put_failure;
2898 }
0768b3b3 2899
053c095a
JB
2900 nlmsg_end(skb, nlh);
2901 return 0;
96518518
PM
2902
2903nla_put_failure:
2904 nlmsg_trim(skb, nlh);
2905 return -1;
2906}
2907
25e94a99
PNA
2908static void nf_tables_rule_notify(const struct nft_ctx *ctx,
2909 const struct nft_rule *rule, int event)
96518518 2910{
0854db2a 2911 struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
96518518 2912 struct sk_buff *skb;
96518518
PM
2913 int err;
2914
128ad332
PNA
2915 if (!ctx->report &&
2916 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 2917 return;
96518518 2918
96518518
PM
2919 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2920 if (skb == NULL)
2921 goto err;
2922
84d7fce6 2923 err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
36596dad 2924 event, 0, ctx->family, ctx->table,
2c82c7e7 2925 ctx->chain, rule, NULL);
96518518
PM
2926 if (err < 0) {
2927 kfree_skb(skb);
2928 goto err;
2929 }
2930
0854db2a 2931 nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
25e94a99 2932 return;
96518518 2933err:
25e94a99 2934 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
2935}
2936
6e1f760e 2937struct nft_rule_dump_ctx {
e46abbcc 2938 char *table;
b7263e07 2939 char *chain;
6e1f760e
PNA
2940};
2941
241faece
PS
2942static int __nf_tables_dump_rules(struct sk_buff *skb,
2943 unsigned int *idx,
2944 struct netlink_callback *cb,
2945 const struct nft_table *table,
2946 const struct nft_chain *chain)
2947{
2948 struct net *net = sock_net(skb->sk);
2c82c7e7 2949 const struct nft_rule *rule, *prule;
241faece 2950 unsigned int s_idx = cb->args[0];
241faece 2951
2c82c7e7 2952 prule = NULL;
241faece
PS
2953 list_for_each_entry_rcu(rule, &chain->rules, list) {
2954 if (!nft_is_active(net, rule))
2c82c7e7 2955 goto cont_skip;
241faece
PS
2956 if (*idx < s_idx)
2957 goto cont;
2958 if (*idx > s_idx) {
2959 memset(&cb->args[1], 0,
2960 sizeof(cb->args) - sizeof(cb->args[0]));
2961 }
2962 if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
2963 cb->nlh->nlmsg_seq,
2964 NFT_MSG_NEWRULE,
2965 NLM_F_MULTI | NLM_F_APPEND,
2966 table->family,
2c82c7e7 2967 table, chain, rule, prule) < 0)
310529e6 2968 return 1;
241faece
PS
2969
2970 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
2971cont:
2c82c7e7
FW
2972 prule = rule;
2973cont_skip:
241faece
PS
2974 (*idx)++;
2975 }
310529e6 2976 return 0;
241faece
PS
2977}
2978
96518518
PM
2979static int nf_tables_dump_rules(struct sk_buff *skb,
2980 struct netlink_callback *cb)
2981{
2982 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
6e1f760e 2983 const struct nft_rule_dump_ctx *ctx = cb->data;
241faece 2984 struct nft_table *table;
96518518 2985 const struct nft_chain *chain;
241faece 2986 unsigned int idx = 0;
99633ab2 2987 struct net *net = sock_net(skb->sk);
96518518 2988 int family = nfmsg->nfgen_family;
0854db2a 2989 struct nftables_pernet *nft_net;
96518518 2990
e688a7f8 2991 rcu_read_lock();
0854db2a
FW
2992 nft_net = net_generic(net, nf_tables_net_id);
2993 cb->seq = nft_net->base_seq;
38e029f1 2994
0854db2a 2995 list_for_each_entry_rcu(table, &nft_net->tables, list) {
98319cb9 2996 if (family != NFPROTO_UNSPEC && family != table->family)
36596dad
PNA
2997 continue;
2998
2999 if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0)
96518518
PM
3000 continue;
3001
715849ab 3002 if (ctx && ctx->table && ctx->chain) {
241faece 3003 struct rhlist_head *list, *tmp;
6e1f760e 3004
241faece
PS
3005 list = rhltable_lookup(&table->chains_ht, ctx->chain,
3006 nft_chain_ht_params);
3007 if (!list)
3008 goto done;
3009
3010 rhl_for_each_entry_rcu(chain, tmp, list, rhlhead) {
3011 if (!nft_is_active(net, chain))
3012 continue;
3013 __nf_tables_dump_rules(skb, &idx,
3014 cb, table, chain);
3015 break;
96518518 3016 }
241faece 3017 goto done;
96518518 3018 }
241faece
PS
3019
3020 list_for_each_entry_rcu(chain, &table->chains, list) {
3021 if (__nf_tables_dump_rules(skb, &idx, cb, table, chain))
3022 goto done;
3023 }
3024
3025 if (ctx && ctx->table)
3026 break;
96518518
PM
3027 }
3028done:
e688a7f8 3029 rcu_read_unlock();
310529e6
PS
3030
3031 cb->args[0] = idx;
96518518
PM
3032 return skb->len;
3033}
3034
90fd131a
FW
3035static int nf_tables_dump_rules_start(struct netlink_callback *cb)
3036{
3037 const struct nlattr * const *nla = cb->data;
3038 struct nft_rule_dump_ctx *ctx = NULL;
3039
3040 if (nla[NFTA_RULE_TABLE] || nla[NFTA_RULE_CHAIN]) {
3041 ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
3042 if (!ctx)
3043 return -ENOMEM;
3044
3045 if (nla[NFTA_RULE_TABLE]) {
3046 ctx->table = nla_strdup(nla[NFTA_RULE_TABLE],
3047 GFP_ATOMIC);
3048 if (!ctx->table) {
3049 kfree(ctx);
3050 return -ENOMEM;
3051 }
3052 }
3053 if (nla[NFTA_RULE_CHAIN]) {
3054 ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN],
3055 GFP_ATOMIC);
3056 if (!ctx->chain) {
3057 kfree(ctx->table);
3058 kfree(ctx);
3059 return -ENOMEM;
3060 }
3061 }
3062 }
3063
3064 cb->data = ctx;
3065 return 0;
3066}
3067
6e1f760e
PNA
3068static int nf_tables_dump_rules_done(struct netlink_callback *cb)
3069{
e46abbcc
PS
3070 struct nft_rule_dump_ctx *ctx = cb->data;
3071
3072 if (ctx) {
3073 kfree(ctx->table);
b7263e07 3074 kfree(ctx->chain);
e46abbcc
PS
3075 kfree(ctx);
3076 }
6e1f760e
PNA
3077 return 0;
3078}
3079
d9adf22a 3080/* called with rcu_read_lock held */
7b8002a1
PNA
3081static int nf_tables_getrule(struct net *net, struct sock *nlsk,
3082 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3083 const struct nlattr * const nla[],
3084 struct netlink_ext_ack *extack)
96518518
PM
3085{
3086 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3087 u8 genmask = nft_genmask_cur(net);
96518518
PM
3088 const struct nft_chain *chain;
3089 const struct nft_rule *rule;
1b2470e5 3090 struct nft_table *table;
96518518
PM
3091 struct sk_buff *skb2;
3092 int family = nfmsg->nfgen_family;
3093 int err;
3094
3095 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3096 struct netlink_dump_control c = {
90fd131a 3097 .start= nf_tables_dump_rules_start,
96518518 3098 .dump = nf_tables_dump_rules,
6e1f760e 3099 .done = nf_tables_dump_rules_done,
d9adf22a 3100 .module = THIS_MODULE,
90fd131a 3101 .data = (void *)nla,
96518518 3102 };
6e1f760e 3103
d9adf22a 3104 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
96518518
PM
3105 }
3106
6001a930 3107 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask, 0);
36dd1bcc
PNA
3108 if (IS_ERR(table)) {
3109 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_TABLE]);
96518518 3110 return PTR_ERR(table);
36dd1bcc 3111 }
96518518 3112
f102d66b 3113 chain = nft_chain_lookup(net, table, nla[NFTA_RULE_CHAIN], genmask);
36dd1bcc
PNA
3114 if (IS_ERR(chain)) {
3115 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
96518518 3116 return PTR_ERR(chain);
36dd1bcc 3117 }
96518518 3118
cac20fcd 3119 rule = nft_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
36dd1bcc
PNA
3120 if (IS_ERR(rule)) {
3121 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
96518518 3122 return PTR_ERR(rule);
36dd1bcc 3123 }
96518518 3124
d9adf22a 3125 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
96518518
PM
3126 if (!skb2)
3127 return -ENOMEM;
3128
84d7fce6 3129 err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
96518518 3130 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
2c82c7e7 3131 family, table, chain, rule, NULL);
96518518 3132 if (err < 0)
ee921183 3133 goto err_fill_rule_info;
96518518 3134
ee921183 3135 return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
96518518 3136
ee921183 3137err_fill_rule_info:
96518518
PM
3138 kfree_skb(skb2);
3139 return err;
3140}
3141
62472bce
PM
3142static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
3143 struct nft_rule *rule)
96518518 3144{
29e38801 3145 struct nft_expr *expr, *next;
96518518
PM
3146
3147 /*
3148 * Careful: some expressions might not be initialized in case this
3149 * is called on error from nf_tables_newrule().
3150 */
3151 expr = nft_expr_first(rule);
31cc578a 3152 while (nft_expr_more(rule, expr)) {
29e38801 3153 next = nft_expr_next(expr);
62472bce 3154 nf_tables_expr_destroy(ctx, expr);
29e38801 3155 expr = next;
96518518
PM
3156 }
3157 kfree(rule);
3158}
3159
d0e2c7de 3160void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *rule)
bb7b40ae 3161{
f6ac8585 3162 nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
bb7b40ae
PNA
3163 nf_tables_rule_destroy(ctx, rule);
3164}
3165
a654de8f
PNA
3166int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
3167{
3168 struct nft_expr *expr, *last;
3169 const struct nft_data *data;
3170 struct nft_rule *rule;
3171 int err;
3172
26b2f552
TY
3173 if (ctx->level == NFT_JUMP_STACK_SIZE)
3174 return -EMLINK;
3175
a654de8f
PNA
3176 list_for_each_entry(rule, &chain->rules, list) {
3177 if (!nft_is_active_next(ctx->net, rule))
3178 continue;
3179
3180 nft_rule_for_each_expr(expr, last, rule) {
3181 if (!expr->ops->validate)
3182 continue;
3183
3184 err = expr->ops->validate(ctx, expr, &data);
3185 if (err < 0)
3186 return err;
3187 }
3188 }
3189
3190 return 0;
3191}
3192EXPORT_SYMBOL_GPL(nft_chain_validate);
3193
3194static int nft_table_validate(struct net *net, const struct nft_table *table)
3195{
3196 struct nft_chain *chain;
3197 struct nft_ctx ctx = {
3198 .net = net,
3199 .family = table->family,
3200 };
3201 int err;
3202
3203 list_for_each_entry(chain, &table->chains, list) {
3204 if (!nft_is_base_chain(chain))
3205 continue;
3206
3207 ctx.chain = chain;
3208 err = nft_chain_validate(&ctx, chain);
3209 if (err < 0)
3210 return err;
3211 }
3212
3213 return 0;
3214}
3215
75dd48e2
PS
3216static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
3217 const struct nlattr *nla);
3218
1081d11b
PNA
3219#define NFT_RULE_MAXEXPRS 128
3220
633c9a84
PNA
3221static int nf_tables_newrule(struct net *net, struct sock *nlsk,
3222 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3223 const struct nlattr * const nla[],
3224 struct netlink_ext_ack *extack)
96518518 3225{
0854db2a 3226 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
96518518 3227 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3228 u8 genmask = nft_genmask_next(net);
2a43ecf9 3229 struct nft_expr_info *info = NULL;
98319cb9 3230 int family = nfmsg->nfgen_family;
c9626a2c 3231 struct nft_flow_rule *flow;
96518518
PM
3232 struct nft_table *table;
3233 struct nft_chain *chain;
3234 struct nft_rule *rule, *old_rule = NULL;
86f1ec32 3235 struct nft_userdata *udata;
1081d11b 3236 struct nft_trans *trans = NULL;
96518518
PM
3237 struct nft_expr *expr;
3238 struct nft_ctx ctx;
3239 struct nlattr *tmp;
86f1ec32 3240 unsigned int size, i, n, ulen = 0, usize = 0;
96518518 3241 int err, rem;
5e948466 3242 u64 handle, pos_handle;
96518518 3243
0854db2a 3244 lockdep_assert_held(&nft_net->commit_mutex);
f102d66b 3245
6001a930
PNA
3246 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask,
3247 NETLINK_CB(skb).portid);
36dd1bcc
PNA
3248 if (IS_ERR(table)) {
3249 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_TABLE]);
96518518 3250 return PTR_ERR(table);
36dd1bcc 3251 }
96518518 3252
837830a4
PNA
3253 if (nla[NFTA_RULE_CHAIN]) {
3254 chain = nft_chain_lookup(net, table, nla[NFTA_RULE_CHAIN],
3255 genmask);
3256 if (IS_ERR(chain)) {
3257 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
3258 return PTR_ERR(chain);
3259 }
d0e2c7de
PNA
3260 if (nft_chain_is_bound(chain))
3261 return -EOPNOTSUPP;
3262
837830a4
PNA
3263 } else if (nla[NFTA_RULE_CHAIN_ID]) {
3264 chain = nft_chain_lookup_byid(net, nla[NFTA_RULE_CHAIN_ID]);
3265 if (IS_ERR(chain)) {
3266 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN_ID]);
3267 return PTR_ERR(chain);
3268 }
3269 } else {
3270 return -EINVAL;
36dd1bcc 3271 }
96518518
PM
3272
3273 if (nla[NFTA_RULE_HANDLE]) {
3274 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
cac20fcd 3275 rule = __nft_rule_lookup(chain, handle);
36dd1bcc
PNA
3276 if (IS_ERR(rule)) {
3277 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
96518518 3278 return PTR_ERR(rule);
36dd1bcc 3279 }
96518518 3280
36dd1bcc
PNA
3281 if (nlh->nlmsg_flags & NLM_F_EXCL) {
3282 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
96518518 3283 return -EEXIST;
36dd1bcc 3284 }
96518518
PM
3285 if (nlh->nlmsg_flags & NLM_F_REPLACE)
3286 old_rule = rule;
3287 else
3288 return -EOPNOTSUPP;
3289 } else {
445509eb
PNA
3290 if (!(nlh->nlmsg_flags & NLM_F_CREATE) ||
3291 nlh->nlmsg_flags & NLM_F_REPLACE)
96518518
PM
3292 return -EINVAL;
3293 handle = nf_tables_alloc_handle(table);
a0a7379e
PNA
3294
3295 if (chain->use == UINT_MAX)
3296 return -EOVERFLOW;
5e948466 3297
447750f2
FW
3298 if (nla[NFTA_RULE_POSITION]) {
3299 pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
3300 old_rule = __nft_rule_lookup(chain, pos_handle);
3301 if (IS_ERR(old_rule)) {
3302 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_POSITION]);
3303 return PTR_ERR(old_rule);
3304 }
75dd48e2
PS
3305 } else if (nla[NFTA_RULE_POSITION_ID]) {
3306 old_rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_POSITION_ID]);
3307 if (IS_ERR(old_rule)) {
3308 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_POSITION_ID]);
3309 return PTR_ERR(old_rule);
3310 }
36dd1bcc 3311 }
5e948466
EL
3312 }
3313
98319cb9 3314 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
0ca743a5 3315
96518518
PM
3316 n = 0;
3317 size = 0;
3318 if (nla[NFTA_RULE_EXPRESSIONS]) {
2a43ecf9
FW
3319 info = kvmalloc_array(NFT_RULE_MAXEXPRS,
3320 sizeof(struct nft_expr_info),
3321 GFP_KERNEL);
3322 if (!info)
3323 return -ENOMEM;
3324
96518518
PM
3325 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
3326 err = -EINVAL;
3327 if (nla_type(tmp) != NFTA_LIST_ELEM)
3328 goto err1;
3329 if (n == NFT_RULE_MAXEXPRS)
3330 goto err1;
0ca743a5 3331 err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
96518518
PM
3332 if (err < 0)
3333 goto err1;
3334 size += info[n].ops->size;
3335 n++;
3336 }
3337 }
9889840f
PM
3338 /* Check for overflow of dlen field */
3339 err = -EFBIG;
3340 if (size >= 1 << 12)
3341 goto err1;
96518518 3342
86f1ec32 3343 if (nla[NFTA_RULE_USERDATA]) {
0768b3b3 3344 ulen = nla_len(nla[NFTA_RULE_USERDATA]);
86f1ec32
PM
3345 if (ulen > 0)
3346 usize = sizeof(struct nft_userdata) + ulen;
3347 }
0768b3b3 3348
96518518 3349 err = -ENOMEM;
86f1ec32 3350 rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
96518518
PM
3351 if (rule == NULL)
3352 goto err1;
3353
889f7ee7 3354 nft_activate_next(net, rule);
0628b123 3355
96518518
PM
3356 rule->handle = handle;
3357 rule->dlen = size;
86f1ec32 3358 rule->udata = ulen ? 1 : 0;
0768b3b3 3359
86f1ec32
PM
3360 if (ulen) {
3361 udata = nft_userdata(rule);
3362 udata->len = ulen - 1;
3363 nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
3364 }
96518518 3365
96518518
PM
3366 expr = nft_expr_first(rule);
3367 for (i = 0; i < n; i++) {
3368 err = nf_tables_newexpr(&ctx, &info[i], expr);
83d9dcba
PNA
3369 if (err < 0) {
3370 NL_SET_BAD_ATTR(extack, info[i].attr);
96518518 3371 goto err2;
83d9dcba 3372 }
a654de8f
PNA
3373
3374 if (info[i].ops->validate)
3375 nft_validate_state_update(net, NFT_VALIDATE_NEED);
3376
ef1f7df9 3377 info[i].ops = NULL;
96518518
PM
3378 expr = nft_expr_next(expr);
3379 }
3380
96518518 3381 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
ca089878 3382 trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
569ccae6
FW
3383 if (trans == NULL) {
3384 err = -ENOMEM;
3385 goto err2;
3386 }
ca089878
TY
3387 err = nft_delrule(&ctx, old_rule);
3388 if (err < 0) {
3389 nft_trans_destroy(trans);
569ccae6
FW
3390 goto err2;
3391 }
3392
3393 list_add_tail_rcu(&rule->list, &old_rule->list);
3394 } else {
c9626a2c
PNA
3395 trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
3396 if (!trans) {
569ccae6
FW
3397 err = -ENOMEM;
3398 goto err2;
3399 }
3400
3401 if (nlh->nlmsg_flags & NLM_F_APPEND) {
3402 if (old_rule)
3403 list_add_rcu(&rule->list, &old_rule->list);
3404 else
3405 list_add_tail_rcu(&rule->list, &chain->rules);
3406 } else {
3407 if (old_rule)
3408 list_add_tail_rcu(&rule->list, &old_rule->list);
3409 else
3410 list_add_rcu(&rule->list, &chain->rules);
3411 }
0628b123 3412 }
2a43ecf9 3413 kvfree(info);
4fefee57 3414 chain->use++;
96518518 3415
0854db2a 3416 if (nft_net->validate_state == NFT_VALIDATE_DO)
a654de8f
PNA
3417 return nft_table_validate(net, table);
3418
c9626a2c 3419 if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
be2861dc 3420 flow = nft_flow_rule_create(net, rule);
c9626a2c
PNA
3421 if (IS_ERR(flow))
3422 return PTR_ERR(flow);
3423
3424 nft_trans_flow_rule(trans) = flow;
3425 }
3426
a654de8f 3427 return 0;
96518518 3428err2:
bb7b40ae 3429 nf_tables_rule_release(&ctx, rule);
96518518
PM
3430err1:
3431 for (i = 0; i < n; i++) {
b25a31bf 3432 if (info[i].ops) {
ef1f7df9 3433 module_put(info[i].ops->type->owner);
b25a31bf
TY
3434 if (info[i].ops->type->release_ops)
3435 info[i].ops->type->release_ops(info[i].ops);
3436 }
96518518 3437 }
2a43ecf9 3438 kvfree(info);
96518518
PM
3439 return err;
3440}
3441
1a94e38d
PNA
3442static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
3443 const struct nlattr *nla)
3444{
0854db2a 3445 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
1a94e38d
PNA
3446 u32 id = ntohl(nla_get_be32(nla));
3447 struct nft_trans *trans;
3448
0854db2a 3449 list_for_each_entry(trans, &nft_net->commit_list, list) {
1a94e38d
PNA
3450 struct nft_rule *rule = nft_trans_rule(trans);
3451
3452 if (trans->msg_type == NFT_MSG_NEWRULE &&
3453 id == nft_trans_rule_id(trans))
3454 return rule;
3455 }
3456 return ERR_PTR(-ENOENT);
3457}
3458
633c9a84
PNA
3459static int nf_tables_delrule(struct net *net, struct sock *nlsk,
3460 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3461 const struct nlattr * const nla[],
3462 struct netlink_ext_ack *extack)
96518518
PM
3463{
3464 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3465 u8 genmask = nft_genmask_next(net);
7c95f6d8 3466 struct nft_table *table;
cf9dc09d
PNA
3467 struct nft_chain *chain = NULL;
3468 struct nft_rule *rule;
0628b123
PNA
3469 int family = nfmsg->nfgen_family, err = 0;
3470 struct nft_ctx ctx;
96518518 3471
6001a930
PNA
3472 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask,
3473 NETLINK_CB(skb).portid);
36dd1bcc
PNA
3474 if (IS_ERR(table)) {
3475 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_TABLE]);
96518518 3476 return PTR_ERR(table);
36dd1bcc 3477 }
96518518 3478
cf9dc09d 3479 if (nla[NFTA_RULE_CHAIN]) {
f102d66b
FW
3480 chain = nft_chain_lookup(net, table, nla[NFTA_RULE_CHAIN],
3481 genmask);
36dd1bcc
PNA
3482 if (IS_ERR(chain)) {
3483 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
cf9dc09d 3484 return PTR_ERR(chain);
36dd1bcc 3485 }
d0e2c7de
PNA
3486 if (nft_chain_is_bound(chain))
3487 return -EOPNOTSUPP;
cf9dc09d 3488 }
96518518 3489
98319cb9 3490 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
0628b123 3491
cf9dc09d
PNA
3492 if (chain) {
3493 if (nla[NFTA_RULE_HANDLE]) {
cac20fcd 3494 rule = nft_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
36dd1bcc
PNA
3495 if (IS_ERR(rule)) {
3496 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
cf9dc09d 3497 return PTR_ERR(rule);
36dd1bcc 3498 }
96518518 3499
1a94e38d
PNA
3500 err = nft_delrule(&ctx, rule);
3501 } else if (nla[NFTA_RULE_ID]) {
3502 rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
36dd1bcc
PNA
3503 if (IS_ERR(rule)) {
3504 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_ID]);
1a94e38d 3505 return PTR_ERR(rule);
36dd1bcc 3506 }
1a94e38d 3507
5e266fe7 3508 err = nft_delrule(&ctx, rule);
cf9dc09d 3509 } else {
ce24b721 3510 err = nft_delrule_by_chain(&ctx);
cf9dc09d
PNA
3511 }
3512 } else {
3513 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
3514 if (!nft_is_active_next(net, chain))
3515 continue;
3516
cf9dc09d 3517 ctx.chain = chain;
ce24b721 3518 err = nft_delrule_by_chain(&ctx);
0628b123
PNA
3519 if (err < 0)
3520 break;
3521 }
3522 }
3523
3524 return err;
3525}
3526
20a69341
PM
3527/*
3528 * Sets
3529 */
e32a4dc6
FW
3530static const struct nft_set_type *nft_set_types[] = {
3531 &nft_set_hash_fast_type,
3532 &nft_set_hash_type,
3533 &nft_set_rhash_type,
3534 &nft_set_bitmap_type,
3535 &nft_set_rbtree_type,
e6abef61 3536#if defined(CONFIG_X86_64) && !defined(CONFIG_UML)
7400b063
SB
3537 &nft_set_pipapo_avx2_type,
3538#endif
e32a4dc6
FW
3539 &nft_set_pipapo_type,
3540};
20a69341 3541
2b664957 3542#define NFT_SET_FEATURES (NFT_SET_INTERVAL | NFT_SET_MAP | \
71cc0873
PS
3543 NFT_SET_TIMEOUT | NFT_SET_OBJECT | \
3544 NFT_SET_EVAL)
2b664957 3545
71cc0873 3546static bool nft_set_ops_candidate(const struct nft_set_type *type, u32 flags)
2b664957 3547{
71cc0873 3548 return (flags & type->features) == (flags & NFT_SET_FEATURES);
2b664957
PNA
3549}
3550
c50b960c
PM
3551/*
3552 * Select a set implementation based on the data characteristics and the
3553 * given policy. The total memory use might not be known if no size is
3554 * given, in that case the amount of memory per element is used.
3555 */
3556static const struct nft_set_ops *
2b664957
PNA
3557nft_select_set_ops(const struct nft_ctx *ctx,
3558 const struct nlattr * const nla[],
c50b960c
PM
3559 const struct nft_set_desc *desc,
3560 enum nft_set_policies policy)
20a69341 3561{
0854db2a 3562 struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
c50b960c
PM
3563 const struct nft_set_ops *ops, *bops;
3564 struct nft_set_estimate est, best;
2b664957
PNA
3565 const struct nft_set_type *type;
3566 u32 flags = 0;
e32a4dc6 3567 int i;
20a69341 3568
0854db2a 3569 lockdep_assert_held(&nft_net->commit_mutex);
f102d66b 3570 lockdep_nfnl_nft_mutex_not_held();
e32a4dc6 3571
2b664957
PNA
3572 if (nla[NFTA_SET_FLAGS] != NULL)
3573 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
20a69341 3574
55af753c
PNA
3575 bops = NULL;
3576 best.size = ~0;
3577 best.lookup = ~0;
0b5a7874 3578 best.space = ~0;
c50b960c 3579
e32a4dc6
FW
3580 for (i = 0; i < ARRAY_SIZE(nft_set_types); i++) {
3581 type = nft_set_types[i];
71cc0873 3582 ops = &type->ops;
2b664957 3583
71cc0873 3584 if (!nft_set_ops_candidate(type, flags))
20a69341 3585 continue;
2b664957 3586 if (!ops->estimate(desc, flags, &est))
c50b960c
PM
3587 continue;
3588
3589 switch (policy) {
3590 case NFT_SET_POL_PERFORMANCE:
55af753c 3591 if (est.lookup < best.lookup)
c50b960c 3592 break;
644e334e
PNA
3593 if (est.lookup == best.lookup &&
3594 est.space < best.space)
3595 break;
c50b960c
PM
3596 continue;
3597 case NFT_SET_POL_MEMORY:
0b5a7874
PNA
3598 if (!desc->size) {
3599 if (est.space < best.space)
3600 break;
3601 if (est.space == best.space &&
3602 est.lookup < best.lookup)
3603 break;
4f2921ca 3604 } else if (est.size < best.size || !bops) {
c50b960c 3605 break;
0b5a7874 3606 }
c50b960c
PM
3607 continue;
3608 default:
3609 break;
3610 }
3611
c50b960c
PM
3612 bops = ops;
3613 best = est;
20a69341
PM
3614 }
3615
c50b960c
PM
3616 if (bops != NULL)
3617 return bops;
3618
20a69341
PM
3619 return ERR_PTR(-EOPNOTSUPP);
3620}
3621
3622static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
b2fbd044
LZ
3623 [NFTA_SET_TABLE] = { .type = NLA_STRING,
3624 .len = NFT_TABLE_MAXNAMELEN - 1 },
a9bdd836 3625 [NFTA_SET_NAME] = { .type = NLA_STRING,
cb39ad8b 3626 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341
PM
3627 [NFTA_SET_FLAGS] = { .type = NLA_U32 },
3628 [NFTA_SET_KEY_TYPE] = { .type = NLA_U32 },
3629 [NFTA_SET_KEY_LEN] = { .type = NLA_U32 },
3630 [NFTA_SET_DATA_TYPE] = { .type = NLA_U32 },
3631 [NFTA_SET_DATA_LEN] = { .type = NLA_U32 },
c50b960c
PM
3632 [NFTA_SET_POLICY] = { .type = NLA_U32 },
3633 [NFTA_SET_DESC] = { .type = NLA_NESTED },
958bee14 3634 [NFTA_SET_ID] = { .type = NLA_U32 },
761da293
PM
3635 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
3636 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
e6d8ecac
CFG
3637 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
3638 .len = NFT_USERDATA_MAXLEN },
8aeff920 3639 [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },
3ecbfd65 3640 [NFTA_SET_HANDLE] = { .type = NLA_U64 },
65038428 3641 [NFTA_SET_EXPR] = { .type = NLA_NESTED },
48b0ae04 3642 [NFTA_SET_EXPRESSIONS] = { .type = NLA_NESTED },
c50b960c
PM
3643};
3644
3645static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
3646 [NFTA_SET_DESC_SIZE] = { .type = NLA_U32 },
f3a2181e 3647 [NFTA_SET_DESC_CONCAT] = { .type = NLA_NESTED },
20a69341
PM
3648};
3649
633c9a84 3650static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
3651 const struct sk_buff *skb,
3652 const struct nlmsghdr *nlh,
f2a6d766 3653 const struct nlattr * const nla[],
36dd1bcc 3654 struct netlink_ext_ack *extack,
6001a930 3655 u8 genmask, u32 nlpid)
20a69341
PM
3656{
3657 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
98319cb9 3658 int family = nfmsg->nfgen_family;
7c95f6d8 3659 struct nft_table *table = NULL;
20a69341 3660
20a69341 3661 if (nla[NFTA_SET_TABLE] != NULL) {
cac20fcd 3662 table = nft_table_lookup(net, nla[NFTA_SET_TABLE], family,
6001a930 3663 genmask, nlpid);
36dd1bcc
PNA
3664 if (IS_ERR(table)) {
3665 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_TABLE]);
20a69341 3666 return PTR_ERR(table);
36dd1bcc 3667 }
20a69341
PM
3668 }
3669
98319cb9 3670 nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla);
20a69341
PM
3671 return 0;
3672}
3673
cac20fcd
PNA
3674static struct nft_set *nft_set_lookup(const struct nft_table *table,
3675 const struct nlattr *nla, u8 genmask)
20a69341
PM
3676{
3677 struct nft_set *set;
3678
3679 if (nla == NULL)
3680 return ERR_PTR(-EINVAL);
3681
d9adf22a 3682 list_for_each_entry_rcu(set, &table->sets, list) {
37a9cc52
PNA
3683 if (!nla_strcmp(nla, set->name) &&
3684 nft_active_genmask(set, genmask))
20a69341
PM
3685 return set;
3686 }
3687 return ERR_PTR(-ENOENT);
3688}
3689
cac20fcd
PNA
3690static struct nft_set *nft_set_lookup_byhandle(const struct nft_table *table,
3691 const struct nlattr *nla,
3692 u8 genmask)
3ecbfd65
HS
3693{
3694 struct nft_set *set;
3695
3ecbfd65
HS
3696 list_for_each_entry(set, &table->sets, list) {
3697 if (be64_to_cpu(nla_get_be64(nla)) == set->handle &&
3698 nft_active_genmask(set, genmask))
3699 return set;
3700 }
3701 return ERR_PTR(-ENOENT);
3702}
3703
cac20fcd
PNA
3704static struct nft_set *nft_set_lookup_byid(const struct net *net,
3705 const struct nlattr *nla, u8 genmask)
958bee14 3706{
0854db2a 3707 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
958bee14
PNA
3708 struct nft_trans *trans;
3709 u32 id = ntohl(nla_get_be32(nla));
3710
0854db2a 3711 list_for_each_entry(trans, &nft_net->commit_list, list) {
9c7f96fd
AK
3712 if (trans->msg_type == NFT_MSG_NEWSET) {
3713 struct nft_set *set = nft_trans_set(trans);
37a9cc52 3714
9c7f96fd
AK
3715 if (id == nft_trans_set_id(trans) &&
3716 nft_active_genmask(set, genmask))
3717 return set;
3718 }
958bee14
PNA
3719 }
3720 return ERR_PTR(-ENOENT);
3721}
c7a72e3f 3722
10659cba
PNA
3723struct nft_set *nft_set_lookup_global(const struct net *net,
3724 const struct nft_table *table,
3725 const struct nlattr *nla_set_name,
3726 const struct nlattr *nla_set_id,
3727 u8 genmask)
c7a72e3f
PNA
3728{
3729 struct nft_set *set;
3730
cac20fcd 3731 set = nft_set_lookup(table, nla_set_name, genmask);
c7a72e3f
PNA
3732 if (IS_ERR(set)) {
3733 if (!nla_set_id)
3734 return set;
3735
cac20fcd 3736 set = nft_set_lookup_byid(net, nla_set_id, genmask);
c7a72e3f
PNA
3737 }
3738 return set;
3739}
10659cba 3740EXPORT_SYMBOL_GPL(nft_set_lookup_global);
958bee14 3741
20a69341
PM
3742static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
3743 const char *name)
3744{
3745 const struct nft_set *i;
3746 const char *p;
3747 unsigned long *inuse;
60eb1894 3748 unsigned int n = 0, min = 0;
20a69341 3749
38745490 3750 p = strchr(name, '%');
20a69341
PM
3751 if (p != NULL) {
3752 if (p[1] != 'd' || strchr(p + 2, '%'))
3753 return -EINVAL;
3754
3755 inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
3756 if (inuse == NULL)
3757 return -ENOMEM;
60eb1894 3758cont:
20a69341 3759 list_for_each_entry(i, &ctx->table->sets, list) {
14662917
DB
3760 int tmp;
3761
37a9cc52
PNA
3762 if (!nft_is_active_next(ctx->net, set))
3763 continue;
14662917 3764 if (!sscanf(i->name, name, &tmp))
20a69341 3765 continue;
60eb1894 3766 if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
20a69341 3767 continue;
14662917 3768
60eb1894 3769 set_bit(tmp - min, inuse);
20a69341
PM
3770 }
3771
53b70287 3772 n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
60eb1894
PM
3773 if (n >= BITS_PER_BYTE * PAGE_SIZE) {
3774 min += BITS_PER_BYTE * PAGE_SIZE;
3775 memset(inuse, 0, PAGE_SIZE);
3776 goto cont;
3777 }
20a69341
PM
3778 free_page((unsigned long)inuse);
3779 }
3780
38745490
PS
3781 set->name = kasprintf(GFP_KERNEL, name, min + n);
3782 if (!set->name)
3783 return -ENOMEM;
3784
20a69341 3785 list_for_each_entry(i, &ctx->table->sets, list) {
37a9cc52
PNA
3786 if (!nft_is_active_next(ctx->net, i))
3787 continue;
e63aaaa6
AY
3788 if (!strcmp(set->name, i->name)) {
3789 kfree(set->name);
7fb6f78d 3790 set->name = NULL;
20a69341 3791 return -ENFILE;
e63aaaa6 3792 }
20a69341
PM
3793 }
3794 return 0;
3795}
3796
917d80d3 3797int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result)
8e1102d5
FW
3798{
3799 u64 ms = be64_to_cpu(nla_get_be64(nla));
3800 u64 max = (u64)(~((u64)0));
3801
3802 max = div_u64(max, NSEC_PER_MSEC);
3803 if (ms >= max)
3804 return -ERANGE;
3805
3806 ms *= NSEC_PER_MSEC;
3807 *result = nsecs_to_jiffies64(ms);
3808 return 0;
3809}
3810
917d80d3 3811__be64 nf_jiffies64_to_msecs(u64 input)
8e1102d5 3812{
3b15d09f 3813 return cpu_to_be64(jiffies64_to_msecs(input));
8e1102d5
FW
3814}
3815
f3a2181e
SB
3816static int nf_tables_fill_set_concat(struct sk_buff *skb,
3817 const struct nft_set *set)
3818{
3819 struct nlattr *concat, *field;
3820 int i;
3821
3822 concat = nla_nest_start_noflag(skb, NFTA_SET_DESC_CONCAT);
3823 if (!concat)
3824 return -ENOMEM;
3825
3826 for (i = 0; i < set->field_count; i++) {
3827 field = nla_nest_start_noflag(skb, NFTA_LIST_ELEM);
3828 if (!field)
3829 return -ENOMEM;
3830
3831 if (nla_put_be32(skb, NFTA_SET_FIELD_LEN,
3832 htonl(set->field_len[i])))
3833 return -ENOMEM;
3834
3835 nla_nest_end(skb, field);
3836 }
3837
3838 nla_nest_end(skb, concat);
3839
3840 return 0;
3841}
3842
20a69341
PM
3843static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
3844 const struct nft_set *set, u16 event, u16 flags)
3845{
20a69341 3846 struct nlmsghdr *nlh;
128ad332 3847 u32 portid = ctx->portid;
65038428 3848 struct nlattr *nest;
128ad332 3849 u32 seq = ctx->seq;
48b0ae04 3850 int i;
20a69341 3851
dedb67c4 3852 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
19c28b13
PNA
3853 nlh = nfnl_msg_put(skb, portid, seq, event, flags, ctx->family,
3854 NFNETLINK_V0, nft_base_seq(ctx->net));
3855 if (!nlh)
20a69341
PM
3856 goto nla_put_failure;
3857
20a69341
PM
3858 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
3859 goto nla_put_failure;
3860 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
3861 goto nla_put_failure;
3ecbfd65
HS
3862 if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle),
3863 NFTA_SET_PAD))
3864 goto nla_put_failure;
20a69341
PM
3865 if (set->flags != 0)
3866 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
3867 goto nla_put_failure;
3868
3869 if (nla_put_be32(skb, NFTA_SET_KEY_TYPE, htonl(set->ktype)))
3870 goto nla_put_failure;
3871 if (nla_put_be32(skb, NFTA_SET_KEY_LEN, htonl(set->klen)))
3872 goto nla_put_failure;
3873 if (set->flags & NFT_SET_MAP) {
3874 if (nla_put_be32(skb, NFTA_SET_DATA_TYPE, htonl(set->dtype)))
3875 goto nla_put_failure;
3876 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
3877 goto nla_put_failure;
3878 }
8aeff920
PNA
3879 if (set->flags & NFT_SET_OBJECT &&
3880 nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
3881 goto nla_put_failure;
20a69341 3882
761da293 3883 if (set->timeout &&
d3e2a111 3884 nla_put_be64(skb, NFTA_SET_TIMEOUT,
8e1102d5 3885 nf_jiffies64_to_msecs(set->timeout),
b46f6ded 3886 NFTA_SET_PAD))
761da293
PM
3887 goto nla_put_failure;
3888 if (set->gc_int &&
3889 nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
3890 goto nla_put_failure;
3891
9363dc4b
AB
3892 if (set->policy != NFT_SET_POL_PERFORMANCE) {
3893 if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
3894 goto nla_put_failure;
3895 }
3896
6f03bf43
PNA
3897 if (set->udata &&
3898 nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata))
e6d8ecac
CFG
3899 goto nla_put_failure;
3900
65038428
PNA
3901 nest = nla_nest_start_noflag(skb, NFTA_SET_DESC);
3902 if (!nest)
c50b960c
PM
3903 goto nla_put_failure;
3904 if (set->size &&
3905 nla_put_be32(skb, NFTA_SET_DESC_SIZE, htonl(set->size)))
3906 goto nla_put_failure;
f3a2181e
SB
3907
3908 if (set->field_count > 1 &&
3909 nf_tables_fill_set_concat(skb, set))
3910 goto nla_put_failure;
3911
65038428
PNA
3912 nla_nest_end(skb, nest);
3913
8cfd9b0f 3914 if (set->num_exprs == 1) {
65038428 3915 nest = nla_nest_start_noflag(skb, NFTA_SET_EXPR);
8cfd9b0f 3916 if (nf_tables_fill_expr_info(skb, set->exprs[0]) < 0)
65038428
PNA
3917 goto nla_put_failure;
3918
3919 nla_nest_end(skb, nest);
48b0ae04
PNA
3920 } else if (set->num_exprs > 1) {
3921 nest = nla_nest_start_noflag(skb, NFTA_SET_EXPRESSIONS);
3922 if (nest == NULL)
65038428
PNA
3923 goto nla_put_failure;
3924
48b0ae04
PNA
3925 for (i = 0; i < set->num_exprs; i++) {
3926 if (nft_expr_dump(skb, NFTA_LIST_ELEM,
3927 set->exprs[i]) < 0)
3928 goto nla_put_failure;
3929 }
65038428
PNA
3930 nla_nest_end(skb, nest);
3931 }
c50b960c 3932
053c095a
JB
3933 nlmsg_end(skb, nlh);
3934 return 0;
20a69341
PM
3935
3936nla_put_failure:
3937 nlmsg_trim(skb, nlh);
3938 return -1;
3939}
3940
25e94a99
PNA
3941static void nf_tables_set_notify(const struct nft_ctx *ctx,
3942 const struct nft_set *set, int event,
3943 gfp_t gfp_flags)
20a69341 3944{
0854db2a 3945 struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
20a69341 3946 struct sk_buff *skb;
128ad332 3947 u32 portid = ctx->portid;
20a69341
PM
3948 int err;
3949
128ad332
PNA
3950 if (!ctx->report &&
3951 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 3952 return;
20a69341 3953
31f8441c 3954 skb = nlmsg_new(NLMSG_GOODSIZE, gfp_flags);
20a69341
PM
3955 if (skb == NULL)
3956 goto err;
3957
3958 err = nf_tables_fill_set(skb, ctx, set, event, 0);
3959 if (err < 0) {
3960 kfree_skb(skb);
3961 goto err;
3962 }
3963
0854db2a 3964 nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
25e94a99 3965 return;
20a69341 3966err:
25e94a99 3967 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
20a69341
PM
3968}
3969
5b96af77 3970static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
c9c8e485
PNA
3971{
3972 const struct nft_set *set;
3973 unsigned int idx, s_idx = cb->args[0];
c9c8e485
PNA
3974 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
3975 struct net *net = sock_net(skb->sk);
5b96af77 3976 struct nft_ctx *ctx = cb->data, ctx_set;
0854db2a 3977 struct nftables_pernet *nft_net;
c9c8e485
PNA
3978
3979 if (cb->args[1])
3980 return skb->len;
3981
e688a7f8 3982 rcu_read_lock();
0854db2a
FW
3983 nft_net = net_generic(net, nf_tables_net_id);
3984 cb->seq = nft_net->base_seq;
38e029f1 3985
0854db2a 3986 list_for_each_entry_rcu(table, &nft_net->tables, list) {
36596dad 3987 if (ctx->family != NFPROTO_UNSPEC &&
98319cb9 3988 ctx->family != table->family)
36596dad
PNA
3989 continue;
3990
3991 if (ctx->table && ctx->table != table)
5b96af77
PNA
3992 continue;
3993
36596dad
PNA
3994 if (cur_table) {
3995 if (cur_table != table)
c9c8e485
PNA
3996 continue;
3997
36596dad 3998 cur_table = NULL;
c9c8e485 3999 }
36596dad
PNA
4000 idx = 0;
4001 list_for_each_entry_rcu(set, &table->sets, list) {
4002 if (idx < s_idx)
4003 goto cont;
4004 if (!nft_is_active(net, set))
4005 goto cont;
5b96af77 4006
36596dad
PNA
4007 ctx_set = *ctx;
4008 ctx_set.table = table;
98319cb9 4009 ctx_set.family = table->family;
c9c8e485 4010
36596dad
PNA
4011 if (nf_tables_fill_set(skb, &ctx_set, set,
4012 NFT_MSG_NEWSET,
4013 NLM_F_MULTI) < 0) {
4014 cb->args[0] = idx;
4015 cb->args[2] = (unsigned long) table;
4016 goto done;
c9c8e485 4017 }
36596dad 4018 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
c9c8e485 4019cont:
36596dad 4020 idx++;
c9c8e485 4021 }
36596dad
PNA
4022 if (s_idx)
4023 s_idx = 0;
c9c8e485
PNA
4024 }
4025 cb->args[1] = 1;
4026done:
e688a7f8 4027 rcu_read_unlock();
c9c8e485
PNA
4028 return skb->len;
4029}
4030
90fd131a
FW
4031static int nf_tables_dump_sets_start(struct netlink_callback *cb)
4032{
4033 struct nft_ctx *ctx_dump = NULL;
4034
4035 ctx_dump = kmemdup(cb->data, sizeof(*ctx_dump), GFP_ATOMIC);
4036 if (ctx_dump == NULL)
4037 return -ENOMEM;
4038
4039 cb->data = ctx_dump;
4040 return 0;
4041}
4042
5b96af77 4043static int nf_tables_dump_sets_done(struct netlink_callback *cb)
20a69341 4044{
5b96af77
PNA
4045 kfree(cb->data);
4046 return 0;
20a69341
PM
4047}
4048
d9adf22a 4049/* called with rcu_read_lock held */
7b8002a1
PNA
4050static int nf_tables_getset(struct net *net, struct sock *nlsk,
4051 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4052 const struct nlattr * const nla[],
4053 struct netlink_ext_ack *extack)
20a69341 4054{
f2a6d766 4055 u8 genmask = nft_genmask_cur(net);
20a69341
PM
4056 const struct nft_set *set;
4057 struct nft_ctx ctx;
4058 struct sk_buff *skb2;
c9c8e485 4059 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
20a69341
PM
4060 int err;
4061
01cfa0a4 4062 /* Verify existence before starting dump */
36dd1bcc 4063 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, extack,
6001a930 4064 genmask, 0);
20a69341
PM
4065 if (err < 0)
4066 return err;
4067
4068 if (nlh->nlmsg_flags & NLM_F_DUMP) {
4069 struct netlink_dump_control c = {
90fd131a 4070 .start = nf_tables_dump_sets_start,
20a69341 4071 .dump = nf_tables_dump_sets,
5b96af77 4072 .done = nf_tables_dump_sets_done,
90fd131a 4073 .data = &ctx,
d9adf22a 4074 .module = THIS_MODULE,
20a69341 4075 };
5b96af77 4076
d9adf22a 4077 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
20a69341
PM
4078 }
4079
c9c8e485
PNA
4080 /* Only accept unspec with dump */
4081 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
4082 return -EAFNOSUPPORT;
eaa2bcd6
PT
4083 if (!nla[NFTA_SET_TABLE])
4084 return -EINVAL;
c9c8e485 4085
cac20fcd 4086 set = nft_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
4087 if (IS_ERR(set))
4088 return PTR_ERR(set);
4089
d9adf22a 4090 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
20a69341
PM
4091 if (skb2 == NULL)
4092 return -ENOMEM;
4093
4094 err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
4095 if (err < 0)
ee921183 4096 goto err_fill_set_info;
20a69341 4097
ee921183 4098 return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
20a69341 4099
ee921183 4100err_fill_set_info:
20a69341
PM
4101 kfree_skb(skb2);
4102 return err;
4103}
4104
f3a2181e
SB
4105static const struct nla_policy nft_concat_policy[NFTA_SET_FIELD_MAX + 1] = {
4106 [NFTA_SET_FIELD_LEN] = { .type = NLA_U32 },
4107};
4108
4109static int nft_set_desc_concat_parse(const struct nlattr *attr,
4110 struct nft_set_desc *desc)
4111{
4112 struct nlattr *tb[NFTA_SET_FIELD_MAX + 1];
4113 u32 len;
4114 int err;
4115
4116 err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr,
4117 nft_concat_policy, NULL);
4118 if (err < 0)
4119 return err;
4120
4121 if (!tb[NFTA_SET_FIELD_LEN])
4122 return -EINVAL;
4123
4124 len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN]));
4125
4126 if (len * BITS_PER_BYTE / 32 > NFT_REG32_COUNT)
4127 return -E2BIG;
4128
4129 desc->field_len[desc->field_count++] = len;
4130
4131 return 0;
4132}
4133
4134static int nft_set_desc_concat(struct nft_set_desc *desc,
4135 const struct nlattr *nla)
4136{
4137 struct nlattr *attr;
4138 int rem, err;
4139
4140 nla_for_each_nested(attr, nla, rem) {
4141 if (nla_type(attr) != NFTA_LIST_ELEM)
4142 return -EINVAL;
4143
4144 err = nft_set_desc_concat_parse(attr, desc);
4145 if (err < 0)
4146 return err;
4147 }
4148
4149 return 0;
4150}
4151
f7e840ee 4152static int nf_tables_set_desc_parse(struct nft_set_desc *desc,
c50b960c
PM
4153 const struct nlattr *nla)
4154{
4155 struct nlattr *da[NFTA_SET_DESC_MAX + 1];
4156 int err;
4157
8cb08174
JB
4158 err = nla_parse_nested_deprecated(da, NFTA_SET_DESC_MAX, nla,
4159 nft_set_desc_policy, NULL);
c50b960c
PM
4160 if (err < 0)
4161 return err;
4162
4163 if (da[NFTA_SET_DESC_SIZE] != NULL)
4164 desc->size = ntohl(nla_get_be32(da[NFTA_SET_DESC_SIZE]));
f3a2181e
SB
4165 if (da[NFTA_SET_DESC_CONCAT])
4166 err = nft_set_desc_concat(desc, da[NFTA_SET_DESC_CONCAT]);
c50b960c 4167
f3a2181e 4168 return err;
c50b960c
PM
4169}
4170
633c9a84
PNA
4171static int nf_tables_newset(struct net *net, struct sock *nlsk,
4172 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4173 const struct nlattr * const nla[],
4174 struct netlink_ext_ack *extack)
20a69341
PM
4175{
4176 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 4177 u8 genmask = nft_genmask_next(net);
98319cb9 4178 int family = nfmsg->nfgen_family;
20a69341 4179 const struct nft_set_ops *ops;
65038428 4180 struct nft_expr *expr = NULL;
20a69341
PM
4181 struct nft_table *table;
4182 struct nft_set *set;
4183 struct nft_ctx ctx;
38745490 4184 char *name;
4ef360dd 4185 u64 size;
761da293 4186 u64 timeout;
8aeff920 4187 u32 ktype, dtype, flags, policy, gc_int, objtype;
c50b960c 4188 struct nft_set_desc desc;
e6d8ecac
CFG
4189 unsigned char *udata;
4190 u16 udlen;
20a69341 4191 int err;
f3a2181e 4192 int i;
20a69341
PM
4193
4194 if (nla[NFTA_SET_TABLE] == NULL ||
4195 nla[NFTA_SET_NAME] == NULL ||
958bee14
PNA
4196 nla[NFTA_SET_KEY_LEN] == NULL ||
4197 nla[NFTA_SET_ID] == NULL)
20a69341
PM
4198 return -EINVAL;
4199
c50b960c
PM
4200 memset(&desc, 0, sizeof(desc));
4201
20a69341
PM
4202 ktype = NFT_DATA_VALUE;
4203 if (nla[NFTA_SET_KEY_TYPE] != NULL) {
4204 ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
4205 if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
4206 return -EINVAL;
4207 }
4208
c50b960c 4209 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
7d740264 4210 if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
4211 return -EINVAL;
4212
4213 flags = 0;
4214 if (nla[NFTA_SET_FLAGS] != NULL) {
4215 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
4216 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
7c6c6e95 4217 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
8aeff920 4218 NFT_SET_MAP | NFT_SET_EVAL |
b4e70d8d 4219 NFT_SET_OBJECT | NFT_SET_CONCAT | NFT_SET_EXPR))
d9583cdf 4220 return -EOPNOTSUPP;
8aeff920 4221 /* Only one of these operations is supported */
acab7131
FW
4222 if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
4223 (NFT_SET_MAP | NFT_SET_OBJECT))
4224 return -EOPNOTSUPP;
4225 if ((flags & (NFT_SET_EVAL | NFT_SET_OBJECT)) ==
4226 (NFT_SET_EVAL | NFT_SET_OBJECT))
7c6c6e95 4227 return -EOPNOTSUPP;
20a69341
PM
4228 }
4229
4230 dtype = 0;
20a69341
PM
4231 if (nla[NFTA_SET_DATA_TYPE] != NULL) {
4232 if (!(flags & NFT_SET_MAP))
4233 return -EINVAL;
4234
4235 dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
4236 if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
4237 dtype != NFT_DATA_VERDICT)
4238 return -EINVAL;
4239
4240 if (dtype != NFT_DATA_VERDICT) {
4241 if (nla[NFTA_SET_DATA_LEN] == NULL)
4242 return -EINVAL;
c50b960c 4243 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
7d740264 4244 if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
4245 return -EINVAL;
4246 } else
7d740264 4247 desc.dlen = sizeof(struct nft_verdict);
20a69341
PM
4248 } else if (flags & NFT_SET_MAP)
4249 return -EINVAL;
4250
8aeff920
PNA
4251 if (nla[NFTA_SET_OBJ_TYPE] != NULL) {
4252 if (!(flags & NFT_SET_OBJECT))
4253 return -EINVAL;
4254
4255 objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
4256 if (objtype == NFT_OBJECT_UNSPEC ||
4257 objtype > NFT_OBJECT_MAX)
d9583cdf 4258 return -EOPNOTSUPP;
8aeff920
PNA
4259 } else if (flags & NFT_SET_OBJECT)
4260 return -EINVAL;
4261 else
4262 objtype = NFT_OBJECT_UNSPEC;
4263
761da293
PM
4264 timeout = 0;
4265 if (nla[NFTA_SET_TIMEOUT] != NULL) {
4266 if (!(flags & NFT_SET_TIMEOUT))
4267 return -EINVAL;
8e1102d5
FW
4268
4269 err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &timeout);
4270 if (err)
4271 return err;
761da293
PM
4272 }
4273 gc_int = 0;
4274 if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
4275 if (!(flags & NFT_SET_TIMEOUT))
4276 return -EINVAL;
4277 gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
4278 }
4279
c50b960c
PM
4280 policy = NFT_SET_POL_PERFORMANCE;
4281 if (nla[NFTA_SET_POLICY] != NULL)
4282 policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
4283
4284 if (nla[NFTA_SET_DESC] != NULL) {
f7e840ee 4285 err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
c50b960c
PM
4286 if (err < 0)
4287 return err;
4288 }
4289
48b0ae04 4290 if (nla[NFTA_SET_EXPR] || nla[NFTA_SET_EXPRESSIONS])
d56aab26
PNA
4291 desc.expr = true;
4292
6001a930
PNA
4293 table = nft_table_lookup(net, nla[NFTA_SET_TABLE], family, genmask,
4294 NETLINK_CB(skb).portid);
36dd1bcc
PNA
4295 if (IS_ERR(table)) {
4296 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_TABLE]);
20a69341 4297 return PTR_ERR(table);
36dd1bcc 4298 }
20a69341 4299
98319cb9 4300 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
20a69341 4301
cac20fcd 4302 set = nft_set_lookup(table, nla[NFTA_SET_NAME], genmask);
20a69341 4303 if (IS_ERR(set)) {
36dd1bcc
PNA
4304 if (PTR_ERR(set) != -ENOENT) {
4305 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
20a69341 4306 return PTR_ERR(set);
36dd1bcc 4307 }
1a28ad74 4308 } else {
36dd1bcc
PNA
4309 if (nlh->nlmsg_flags & NLM_F_EXCL) {
4310 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
20a69341 4311 return -EEXIST;
36dd1bcc 4312 }
20a69341
PM
4313 if (nlh->nlmsg_flags & NLM_F_REPLACE)
4314 return -EOPNOTSUPP;
36dd1bcc 4315
20a69341
PM
4316 return 0;
4317 }
4318
4319 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
4320 return -ENOENT;
4321
2b664957 4322 ops = nft_select_set_ops(&ctx, nla, &desc, policy);
20a69341
PM
4323 if (IS_ERR(ops))
4324 return PTR_ERR(ops);
4325
e6d8ecac
CFG
4326 udlen = 0;
4327 if (nla[NFTA_SET_USERDATA])
4328 udlen = nla_len(nla[NFTA_SET_USERDATA]);
4329
20a69341
PM
4330 size = 0;
4331 if (ops->privsize != NULL)
347b408d 4332 size = ops->privsize(nla, &desc);
20a69341 4333
1ff75a3e 4334 set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
24d19826
FW
4335 if (!set)
4336 return -ENOMEM;
20a69341 4337
38745490
PS
4338 name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
4339 if (!name) {
4340 err = -ENOMEM;
65038428 4341 goto err_set_name;
38745490
PS
4342 }
4343
20a69341 4344 err = nf_tables_set_alloc_name(&ctx, set, name);
38745490 4345 kfree(name);
20a69341 4346 if (err < 0)
65038428
PNA
4347 goto err_set_alloc_name;
4348
4349 if (nla[NFTA_SET_EXPR]) {
4350 expr = nft_set_elem_expr_alloc(&ctx, set, nla[NFTA_SET_EXPR]);
4351 if (IS_ERR(expr)) {
4352 err = PTR_ERR(expr);
4353 goto err_set_alloc_name;
4354 }
8cfd9b0f
PNA
4355 set->exprs[0] = expr;
4356 set->num_exprs++;
48b0ae04
PNA
4357 } else if (nla[NFTA_SET_EXPRESSIONS]) {
4358 struct nft_expr *expr;
4359 struct nlattr *tmp;
4360 int left;
4361
b4e70d8d
PNA
4362 if (!(flags & NFT_SET_EXPR)) {
4363 err = -EINVAL;
4364 goto err_set_alloc_name;
4365 }
48b0ae04
PNA
4366 i = 0;
4367 nla_for_each_nested(tmp, nla[NFTA_SET_EXPRESSIONS], left) {
4368 if (i == NFT_SET_EXPR_MAX) {
4369 err = -E2BIG;
4370 goto err_set_init;
4371 }
4372 if (nla_type(tmp) != NFTA_LIST_ELEM) {
4373 err = -EINVAL;
4374 goto err_set_init;
4375 }
4376 expr = nft_set_elem_expr_alloc(&ctx, set, tmp);
4377 if (IS_ERR(expr)) {
4378 err = PTR_ERR(expr);
4379 goto err_set_init;
4380 }
4381 set->exprs[i++] = expr;
4382 set->num_exprs++;
4383 }
65038428 4384 }
20a69341 4385
e6d8ecac
CFG
4386 udata = NULL;
4387 if (udlen) {
4388 udata = set->data + size;
4389 nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
4390 }
4391
20a69341 4392 INIT_LIST_HEAD(&set->bindings);
3453c927
PNA
4393 set->table = table;
4394 write_pnet(&set->net, net);
20a69341
PM
4395 set->ops = ops;
4396 set->ktype = ktype;
c50b960c 4397 set->klen = desc.klen;
20a69341 4398 set->dtype = dtype;
8aeff920 4399 set->objtype = objtype;
c50b960c 4400 set->dlen = desc.dlen;
20a69341 4401 set->flags = flags;
c50b960c 4402 set->size = desc.size;
9363dc4b 4403 set->policy = policy;
e6d8ecac
CFG
4404 set->udlen = udlen;
4405 set->udata = udata;
761da293
PM
4406 set->timeout = timeout;
4407 set->gc_int = gc_int;
3ecbfd65 4408 set->handle = nf_tables_alloc_handle(table);
20a69341 4409
f3a2181e
SB
4410 set->field_count = desc.field_count;
4411 for (i = 0; i < desc.field_count; i++)
4412 set->field_len[i] = desc.field_len[i];
4413
c50b960c 4414 err = ops->init(set, &desc, nla);
20a69341 4415 if (err < 0)
65038428 4416 goto err_set_init;
20a69341 4417
958bee14 4418 err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
20a69341 4419 if (err < 0)
65038428 4420 goto err_set_trans;
20a69341 4421
e688a7f8 4422 list_add_tail_rcu(&set->list, &table->sets);
4fefee57 4423 table->use++;
20a69341
PM
4424 return 0;
4425
65038428 4426err_set_trans:
c17c3cdf 4427 ops->destroy(set);
65038428 4428err_set_init:
8cfd9b0f
PNA
4429 for (i = 0; i < set->num_exprs; i++)
4430 nft_expr_destroy(&ctx, set->exprs[i]);
65038428 4431err_set_alloc_name:
2f6adf48 4432 kfree(set->name);
65038428 4433err_set_name:
1ff75a3e 4434 kvfree(set);
20a69341
PM
4435 return err;
4436}
4437
0c2a85ed 4438static void nft_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
20a69341 4439{
8cfd9b0f
PNA
4440 int i;
4441
273fe3f1
PNA
4442 if (WARN_ON(set->use > 0))
4443 return;
4444
8cfd9b0f
PNA
4445 for (i = 0; i < set->num_exprs; i++)
4446 nft_expr_destroy(ctx, set->exprs[i]);
65038428 4447
20a69341 4448 set->ops->destroy(set);
38745490 4449 kfree(set->name);
1ff75a3e 4450 kvfree(set);
20a69341
PM
4451}
4452
633c9a84
PNA
4453static int nf_tables_delset(struct net *net, struct sock *nlsk,
4454 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4455 const struct nlattr * const nla[],
4456 struct netlink_ext_ack *extack)
20a69341 4457{
c9c8e485 4458 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 4459 u8 genmask = nft_genmask_next(net);
36dd1bcc 4460 const struct nlattr *attr;
20a69341
PM
4461 struct nft_set *set;
4462 struct nft_ctx ctx;
4463 int err;
4464
ec2c9935
PM
4465 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
4466 return -EAFNOSUPPORT;
20a69341
PM
4467 if (nla[NFTA_SET_TABLE] == NULL)
4468 return -EINVAL;
4469
36dd1bcc 4470 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, extack,
6001a930 4471 genmask, NETLINK_CB(skb).portid);
20a69341
PM
4472 if (err < 0)
4473 return err;
4474
36dd1bcc
PNA
4475 if (nla[NFTA_SET_HANDLE]) {
4476 attr = nla[NFTA_SET_HANDLE];
4477 set = nft_set_lookup_byhandle(ctx.table, attr, genmask);
4478 } else {
4479 attr = nla[NFTA_SET_NAME];
4480 set = nft_set_lookup(ctx.table, attr, genmask);
4481 }
a8278400 4482
36dd1bcc
PNA
4483 if (IS_ERR(set)) {
4484 NL_SET_BAD_ATTR(extack, attr);
4485 return PTR_ERR(set);
4486 }
273fe3f1 4487 if (set->use ||
36dd1bcc
PNA
4488 (nlh->nlmsg_flags & NLM_F_NONREC && atomic_read(&set->nelems) > 0)) {
4489 NL_SET_BAD_ATTR(extack, attr);
20a69341 4490 return -EBUSY;
36dd1bcc 4491 }
20a69341 4492
ee01d542 4493 return nft_delset(&ctx, set);
20a69341
PM
4494}
4495
345023b0
PNA
4496static int nft_validate_register_store(const struct nft_ctx *ctx,
4497 enum nft_registers reg,
4498 const struct nft_data *data,
4499 enum nft_data_types type,
4500 unsigned int len);
4501
20a69341 4502static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
de70185d 4503 struct nft_set *set,
20a69341 4504 const struct nft_set_iter *iter,
de70185d 4505 struct nft_set_elem *elem)
20a69341 4506{
fe2811eb 4507 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
4508 enum nft_registers dreg;
4509
4510 dreg = nft_type_to_reg(set->dtype);
1ec10212
PM
4511 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
4512 set->dtype == NFT_DATA_VERDICT ?
4513 NFT_DATA_VERDICT : NFT_DATA_VALUE,
4514 set->dlen);
20a69341
PM
4515}
4516
4517int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
4518 struct nft_set_binding *binding)
4519{
4520 struct nft_set_binding *i;
4521 struct nft_set_iter iter;
4522
273fe3f1
PNA
4523 if (set->use == UINT_MAX)
4524 return -EOVERFLOW;
4525
408070d6 4526 if (!list_empty(&set->bindings) && nft_set_is_anonymous(set))
20a69341
PM
4527 return -EBUSY;
4528
11113e19 4529 if (binding->flags & NFT_SET_MAP) {
20a69341
PM
4530 /* If the set is already bound to the same chain all
4531 * jumps are already validated for that chain.
4532 */
4533 list_for_each_entry(i, &set->bindings, list) {
a4684402 4534 if (i->flags & NFT_SET_MAP &&
11113e19 4535 i->chain == binding->chain)
20a69341
PM
4536 goto bind;
4537 }
4538
8588ac09 4539 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
4540 iter.skip = 0;
4541 iter.count = 0;
4542 iter.err = 0;
4543 iter.fn = nf_tables_bind_check_setelem;
4544
4545 set->ops->walk(ctx, set, &iter);
a02f4248 4546 if (iter.err < 0)
20a69341 4547 return iter.err;
20a69341
PM
4548 }
4549bind:
4550 binding->chain = ctx->chain;
e688a7f8 4551 list_add_tail_rcu(&binding->list, &set->bindings);
f6ac8585 4552 nft_set_trans_bind(ctx, set);
273fe3f1 4553 set->use++;
f6ac8585 4554
20a69341
PM
4555 return 0;
4556}
63aea290 4557EXPORT_SYMBOL_GPL(nf_tables_bind_set);
20a69341 4558
3b0a081d
FW
4559static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
4560 struct nft_set_binding *binding, bool event)
20a69341 4561{
e688a7f8 4562 list_del_rcu(&binding->list);
20a69341 4563
f6ac8585 4564 if (list_empty(&set->bindings) && nft_set_is_anonymous(set)) {
cd5125d8 4565 list_del_rcu(&set->list);
f6ac8585
PNA
4566 if (event)
4567 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET,
4568 GFP_KERNEL);
4569 }
20a69341
PM
4570}
4571
273fe3f1
PNA
4572void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
4573 struct nft_set_binding *binding,
4574 enum nft_trans_phase phase)
4575{
4576 switch (phase) {
4577 case NFT_TRANS_PREPARE:
4578 set->use--;
4579 return;
4580 case NFT_TRANS_ABORT:
4581 case NFT_TRANS_RELEASE:
4582 set->use--;
954d8297 4583 fallthrough;
273fe3f1
PNA
4584 default:
4585 nf_tables_unbind_set(ctx, set, binding,
4586 phase == NFT_TRANS_COMMIT);
4587 }
4588}
4589EXPORT_SYMBOL_GPL(nf_tables_deactivate_set);
4590
cd5125d8
FW
4591void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set)
4592{
f6ac8585 4593 if (list_empty(&set->bindings) && nft_set_is_anonymous(set))
0c2a85ed 4594 nft_set_destroy(ctx, set);
cd5125d8
FW
4595}
4596EXPORT_SYMBOL_GPL(nf_tables_destroy_set);
4597
3ac4c07a
PM
4598const struct nft_set_ext_type nft_set_ext_types[] = {
4599 [NFT_SET_EXT_KEY] = {
7d740264 4600 .align = __alignof__(u32),
3ac4c07a
PM
4601 },
4602 [NFT_SET_EXT_DATA] = {
7d740264 4603 .align = __alignof__(u32),
3ac4c07a 4604 },
563125a7
PNA
4605 [NFT_SET_EXT_EXPRESSIONS] = {
4606 .align = __alignof__(struct nft_set_elem_expr),
f25ad2e9 4607 },
8aeff920
PNA
4608 [NFT_SET_EXT_OBJREF] = {
4609 .len = sizeof(struct nft_object *),
4610 .align = __alignof__(struct nft_object *),
4611 },
3ac4c07a
PM
4612 [NFT_SET_EXT_FLAGS] = {
4613 .len = sizeof(u8),
4614 .align = __alignof__(u8),
4615 },
c3e1b005
PM
4616 [NFT_SET_EXT_TIMEOUT] = {
4617 .len = sizeof(u64),
4618 .align = __alignof__(u64),
4619 },
4620 [NFT_SET_EXT_EXPIRATION] = {
8e1102d5
FW
4621 .len = sizeof(u64),
4622 .align = __alignof__(u64),
c3e1b005 4623 },
68e942e8
PM
4624 [NFT_SET_EXT_USERDATA] = {
4625 .len = sizeof(struct nft_userdata),
4626 .align = __alignof__(struct nft_userdata),
4627 },
7b225d0b
PNA
4628 [NFT_SET_EXT_KEY_END] = {
4629 .align = __alignof__(u32),
4630 },
3ac4c07a 4631};
3ac4c07a 4632
20a69341
PM
4633/*
4634 * Set elements
4635 */
4636
4637static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
4638 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
4639 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
4640 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
c3e1b005 4641 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
79ebb5bb 4642 [NFTA_SET_ELEM_EXPIRATION] = { .type = NLA_U64 },
68e942e8
PM
4643 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY,
4644 .len = NFT_USERDATA_MAXLEN },
467697d2 4645 [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED },
9332d27d
FW
4646 [NFTA_SET_ELEM_OBJREF] = { .type = NLA_STRING,
4647 .len = NFT_OBJ_MAXNAMELEN - 1 },
7b225d0b 4648 [NFTA_SET_ELEM_KEY_END] = { .type = NLA_NESTED },
48b0ae04 4649 [NFTA_SET_ELEM_EXPRESSIONS] = { .type = NLA_NESTED },
20a69341
PM
4650};
4651
4652static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
b2fbd044
LZ
4653 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING,
4654 .len = NFT_TABLE_MAXNAMELEN - 1 },
4655 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING,
4656 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341 4657 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
958bee14 4658 [NFTA_SET_ELEM_LIST_SET_ID] = { .type = NLA_U32 },
20a69341
PM
4659};
4660
633c9a84 4661static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
4662 const struct sk_buff *skb,
4663 const struct nlmsghdr *nlh,
f2a6d766 4664 const struct nlattr * const nla[],
36dd1bcc 4665 struct netlink_ext_ack *extack,
6001a930 4666 u8 genmask, u32 nlpid)
20a69341
PM
4667{
4668 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
98319cb9 4669 int family = nfmsg->nfgen_family;
7c95f6d8 4670 struct nft_table *table;
20a69341 4671
cac20fcd 4672 table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family,
6001a930 4673 genmask, nlpid);
36dd1bcc
PNA
4674 if (IS_ERR(table)) {
4675 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]);
20a69341 4676 return PTR_ERR(table);
36dd1bcc 4677 }
20a69341 4678
98319cb9 4679 nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla);
20a69341
PM
4680 return 0;
4681}
4682
563125a7
PNA
4683static int nft_set_elem_expr_dump(struct sk_buff *skb,
4684 const struct nft_set *set,
4685 const struct nft_set_ext *ext)
4686{
4687 struct nft_set_elem_expr *elem_expr;
4688 u32 size, num_exprs = 0;
4689 struct nft_expr *expr;
48b0ae04 4690 struct nlattr *nest;
563125a7
PNA
4691
4692 elem_expr = nft_set_ext_expr(ext);
4693 nft_setelem_expr_foreach(expr, elem_expr, size)
4694 num_exprs++;
4695
4696 if (num_exprs == 1) {
4697 expr = nft_setelem_expr_at(elem_expr, 0);
4698 if (nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, expr) < 0)
4699 return -1;
4700
4701 return 0;
48b0ae04
PNA
4702 } else if (num_exprs > 1) {
4703 nest = nla_nest_start_noflag(skb, NFTA_SET_ELEM_EXPRESSIONS);
4704 if (nest == NULL)
4705 goto nla_put_failure;
563125a7 4706
48b0ae04
PNA
4707 nft_setelem_expr_foreach(expr, elem_expr, size) {
4708 expr = nft_setelem_expr_at(elem_expr, size);
4709 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
4710 goto nla_put_failure;
4711 }
4712 nla_nest_end(skb, nest);
4713 }
563125a7 4714 return 0;
48b0ae04
PNA
4715
4716nla_put_failure:
4717 return -1;
563125a7
PNA
4718}
4719
20a69341
PM
4720static int nf_tables_fill_setelem(struct sk_buff *skb,
4721 const struct nft_set *set,
4722 const struct nft_set_elem *elem)
4723{
fe2811eb 4724 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
4725 unsigned char *b = skb_tail_pointer(skb);
4726 struct nlattr *nest;
4727
ae0be8de 4728 nest = nla_nest_start_noflag(skb, NFTA_LIST_ELEM);
20a69341
PM
4729 if (nest == NULL)
4730 goto nla_put_failure;
4731
fe2811eb
PM
4732 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, nft_set_ext_key(ext),
4733 NFT_DATA_VALUE, set->klen) < 0)
20a69341
PM
4734 goto nla_put_failure;
4735
7b225d0b
PNA
4736 if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END) &&
4737 nft_data_dump(skb, NFTA_SET_ELEM_KEY_END, nft_set_ext_key_end(ext),
4738 NFT_DATA_VALUE, set->klen) < 0)
4739 goto nla_put_failure;
4740
fe2811eb
PM
4741 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
4742 nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
20a69341
PM
4743 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
4744 set->dlen) < 0)
4745 goto nla_put_failure;
4746
563125a7
PNA
4747 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS) &&
4748 nft_set_elem_expr_dump(skb, set, ext))
f25ad2e9
PM
4749 goto nla_put_failure;
4750
8aeff920
PNA
4751 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
4752 nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
d152159b 4753 (*nft_set_ext_obj(ext))->key.name) < 0)
8aeff920
PNA
4754 goto nla_put_failure;
4755
fe2811eb
PM
4756 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
4757 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
4758 htonl(*nft_set_ext_flags(ext))))
4759 goto nla_put_failure;
20a69341 4760
c3e1b005
PM
4761 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
4762 nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
8e1102d5 4763 nf_jiffies64_to_msecs(*nft_set_ext_timeout(ext)),
b46f6ded 4764 NFTA_SET_ELEM_PAD))
c3e1b005
PM
4765 goto nla_put_failure;
4766
4767 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
8e1102d5 4768 u64 expires, now = get_jiffies_64();
c3e1b005
PM
4769
4770 expires = *nft_set_ext_expiration(ext);
8e1102d5 4771 if (time_before64(now, expires))
c3e1b005
PM
4772 expires -= now;
4773 else
4774 expires = 0;
4775
4776 if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
8e1102d5 4777 nf_jiffies64_to_msecs(expires),
b46f6ded 4778 NFTA_SET_ELEM_PAD))
c3e1b005
PM
4779 goto nla_put_failure;
4780 }
4781
68e942e8
PM
4782 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
4783 struct nft_userdata *udata;
4784
4785 udata = nft_set_ext_userdata(ext);
4786 if (nla_put(skb, NFTA_SET_ELEM_USERDATA,
4787 udata->len + 1, udata->data))
4788 goto nla_put_failure;
4789 }
4790
20a69341
PM
4791 nla_nest_end(skb, nest);
4792 return 0;
4793
4794nla_put_failure:
4795 nlmsg_trim(skb, b);
4796 return -EMSGSIZE;
4797}
4798
4799struct nft_set_dump_args {
4800 const struct netlink_callback *cb;
4801 struct nft_set_iter iter;
4802 struct sk_buff *skb;
4803};
4804
4805static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
de70185d 4806 struct nft_set *set,
20a69341 4807 const struct nft_set_iter *iter,
de70185d 4808 struct nft_set_elem *elem)
20a69341
PM
4809{
4810 struct nft_set_dump_args *args;
4811
4812 args = container_of(iter, struct nft_set_dump_args, iter);
4813 return nf_tables_fill_setelem(args->skb, set, elem);
4814}
4815
fa803605
LZ
4816struct nft_set_dump_ctx {
4817 const struct nft_set *set;
4818 struct nft_ctx ctx;
4819};
4820
20a69341
PM
4821static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
4822{
fa803605 4823 struct nft_set_dump_ctx *dump_ctx = cb->data;
633c9a84 4824 struct net *net = sock_net(skb->sk);
0854db2a 4825 struct nftables_pernet *nft_net;
fa803605 4826 struct nft_table *table;
de70185d 4827 struct nft_set *set;
20a69341 4828 struct nft_set_dump_args args;
fa803605 4829 bool set_found = false;
20a69341
PM
4830 struct nlmsghdr *nlh;
4831 struct nlattr *nest;
4832 u32 portid, seq;
fa803605 4833 int event;
20a69341 4834
fa803605 4835 rcu_read_lock();
0854db2a
FW
4836 nft_net = net_generic(net, nf_tables_net_id);
4837 list_for_each_entry_rcu(table, &nft_net->tables, list) {
36596dad 4838 if (dump_ctx->ctx.family != NFPROTO_UNSPEC &&
98319cb9 4839 dump_ctx->ctx.family != table->family)
fa803605 4840 continue;
20a69341 4841
36596dad
PNA
4842 if (table != dump_ctx->ctx.table)
4843 continue;
20a69341 4844
36596dad
PNA
4845 list_for_each_entry_rcu(set, &table->sets, list) {
4846 if (set == dump_ctx->set) {
4847 set_found = true;
4848 break;
fa803605 4849 }
fa803605
LZ
4850 }
4851 break;
4852 }
4853
4854 if (!set_found) {
4855 rcu_read_unlock();
4856 return -ENOENT;
4857 }
20a69341 4858
dedb67c4 4859 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSETELEM);
20a69341
PM
4860 portid = NETLINK_CB(cb->skb).portid;
4861 seq = cb->nlh->nlmsg_seq;
4862
19c28b13
PNA
4863 nlh = nfnl_msg_put(skb, portid, seq, event, NLM_F_MULTI,
4864 table->family, NFNETLINK_V0, nft_base_seq(net));
4865 if (!nlh)
20a69341
PM
4866 goto nla_put_failure;
4867
fa803605 4868 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, table->name))
20a69341
PM
4869 goto nla_put_failure;
4870 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
4871 goto nla_put_failure;
4872
ae0be8de 4873 nest = nla_nest_start_noflag(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
20a69341
PM
4874 if (nest == NULL)
4875 goto nla_put_failure;
4876
8588ac09
PNA
4877 args.cb = cb;
4878 args.skb = skb;
fa803605 4879 args.iter.genmask = nft_genmask_cur(net);
8588ac09
PNA
4880 args.iter.skip = cb->args[0];
4881 args.iter.count = 0;
4882 args.iter.err = 0;
4883 args.iter.fn = nf_tables_dump_setelem;
fa803605
LZ
4884 set->ops->walk(&dump_ctx->ctx, set, &args.iter);
4885 rcu_read_unlock();
20a69341
PM
4886
4887 nla_nest_end(skb, nest);
4888 nlmsg_end(skb, nlh);
4889
4890 if (args.iter.err && args.iter.err != -EMSGSIZE)
4891 return args.iter.err;
4892 if (args.iter.count == cb->args[0])
4893 return 0;
4894
4895 cb->args[0] = args.iter.count;
4896 return skb->len;
4897
4898nla_put_failure:
fa803605 4899 rcu_read_unlock();
20a69341
PM
4900 return -ENOSPC;
4901}
4902
90fd131a
FW
4903static int nf_tables_dump_set_start(struct netlink_callback *cb)
4904{
4905 struct nft_set_dump_ctx *dump_ctx = cb->data;
4906
4907 cb->data = kmemdup(dump_ctx, sizeof(*dump_ctx), GFP_ATOMIC);
4908
4909 return cb->data ? 0 : -ENOMEM;
4910}
4911
fa803605
LZ
4912static int nf_tables_dump_set_done(struct netlink_callback *cb)
4913{
4914 kfree(cb->data);
4915 return 0;
4916}
4917
d60ce62f
AB
4918static int nf_tables_fill_setelem_info(struct sk_buff *skb,
4919 const struct nft_ctx *ctx, u32 seq,
4920 u32 portid, int event, u16 flags,
4921 const struct nft_set *set,
4922 const struct nft_set_elem *elem)
4923{
d60ce62f
AB
4924 struct nlmsghdr *nlh;
4925 struct nlattr *nest;
4926 int err;
4927
dedb67c4 4928 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
19c28b13
PNA
4929 nlh = nfnl_msg_put(skb, portid, seq, event, flags, ctx->family,
4930 NFNETLINK_V0, nft_base_seq(ctx->net));
4931 if (!nlh)
d60ce62f
AB
4932 goto nla_put_failure;
4933
d60ce62f
AB
4934 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
4935 goto nla_put_failure;
4936 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
4937 goto nla_put_failure;
4938
ae0be8de 4939 nest = nla_nest_start_noflag(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
d60ce62f
AB
4940 if (nest == NULL)
4941 goto nla_put_failure;
4942
4943 err = nf_tables_fill_setelem(skb, set, elem);
4944 if (err < 0)
4945 goto nla_put_failure;
4946
4947 nla_nest_end(skb, nest);
4948
053c095a
JB
4949 nlmsg_end(skb, nlh);
4950 return 0;
d60ce62f
AB
4951
4952nla_put_failure:
4953 nlmsg_trim(skb, nlh);
4954 return -1;
4955}
4956
ba0e4d99
PNA
4957static int nft_setelem_parse_flags(const struct nft_set *set,
4958 const struct nlattr *attr, u32 *flags)
4959{
4960 if (attr == NULL)
4961 return 0;
4962
4963 *flags = ntohl(nla_get_be32(attr));
4964 if (*flags & ~NFT_SET_ELEM_INTERVAL_END)
4965 return -EINVAL;
4966 if (!(set->flags & NFT_SET_INTERVAL) &&
4967 *flags & NFT_SET_ELEM_INTERVAL_END)
4968 return -EINVAL;
4969
4970 return 0;
4971}
4972
20a1452c
PNA
4973static int nft_setelem_parse_key(struct nft_ctx *ctx, struct nft_set *set,
4974 struct nft_data *key, struct nlattr *attr)
4975{
4976 struct nft_data_desc desc;
4977 int err;
4978
4979 err = nft_data_init(ctx, key, NFT_DATA_VALUE_MAXLEN, &desc, attr);
4980 if (err < 0)
4981 return err;
4982
4983 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) {
4984 nft_data_release(key, desc.type);
4985 return -EINVAL;
4986 }
4987
4988 return 0;
4989}
4990
fdb9c405
PNA
4991static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,
4992 struct nft_data_desc *desc,
4993 struct nft_data *data,
4994 struct nlattr *attr)
4995{
4996 int err;
4997
4998 err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr);
4999 if (err < 0)
5000 return err;
5001
5002 if (desc->type != NFT_DATA_VERDICT && desc->len != set->dlen) {
5003 nft_data_release(data, desc->type);
5004 return -EINVAL;
5005 }
5006
5007 return 0;
5008}
5009
ba0e4d99
PNA
5010static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
5011 const struct nlattr *attr)
5012{
5013 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
ba0e4d99
PNA
5014 struct nft_set_elem elem;
5015 struct sk_buff *skb;
5016 uint32_t flags = 0;
5017 void *priv;
5018 int err;
5019
8cb08174
JB
5020 err = nla_parse_nested_deprecated(nla, NFTA_SET_ELEM_MAX, attr,
5021 nft_set_elem_policy, NULL);
ba0e4d99
PNA
5022 if (err < 0)
5023 return err;
5024
5025 if (!nla[NFTA_SET_ELEM_KEY])
5026 return -EINVAL;
5027
5028 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
5029 if (err < 0)
5030 return err;
5031
20a1452c
PNA
5032 err = nft_setelem_parse_key(ctx, set, &elem.key.val,
5033 nla[NFTA_SET_ELEM_KEY]);
ba0e4d99
PNA
5034 if (err < 0)
5035 return err;
5036
7b225d0b
PNA
5037 if (nla[NFTA_SET_ELEM_KEY_END]) {
5038 err = nft_setelem_parse_key(ctx, set, &elem.key_end.val,
5039 nla[NFTA_SET_ELEM_KEY_END]);
5040 if (err < 0)
5041 return err;
5042 }
5043
ba0e4d99
PNA
5044 priv = set->ops->get(ctx->net, set, &elem, flags);
5045 if (IS_ERR(priv))
5046 return PTR_ERR(priv);
5047
5048 elem.priv = priv;
ba0e4d99
PNA
5049
5050 err = -ENOMEM;
d9adf22a 5051 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
ba0e4d99 5052 if (skb == NULL)
ee921183 5053 return err;
ba0e4d99
PNA
5054
5055 err = nf_tables_fill_setelem_info(skb, ctx, ctx->seq, ctx->portid,
5056 NFT_MSG_NEWSETELEM, 0, set, &elem);
5057 if (err < 0)
ee921183 5058 goto err_fill_setelem;
ba0e4d99 5059
ee921183 5060 return nfnetlink_unicast(skb, ctx->net, ctx->portid);
ba0e4d99 5061
ee921183 5062err_fill_setelem:
ba0e4d99 5063 kfree_skb(skb);
ee921183 5064 return err;
ba0e4d99
PNA
5065}
5066
d9adf22a 5067/* called with rcu_read_lock held */
ba0e4d99
PNA
5068static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
5069 struct sk_buff *skb, const struct nlmsghdr *nlh,
5070 const struct nlattr * const nla[],
5071 struct netlink_ext_ack *extack)
5072{
5073 u8 genmask = nft_genmask_cur(net);
5074 struct nft_set *set;
5075 struct nlattr *attr;
5076 struct nft_ctx ctx;
5077 int rem, err = 0;
5078
36dd1bcc 5079 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
6001a930 5080 genmask, NETLINK_CB(skb).portid);
ba0e4d99
PNA
5081 if (err < 0)
5082 return err;
5083
cac20fcd 5084 set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
ba0e4d99
PNA
5085 if (IS_ERR(set))
5086 return PTR_ERR(set);
5087
5088 if (nlh->nlmsg_flags & NLM_F_DUMP) {
5089 struct netlink_dump_control c = {
90fd131a 5090 .start = nf_tables_dump_set_start,
ba0e4d99
PNA
5091 .dump = nf_tables_dump_set,
5092 .done = nf_tables_dump_set_done,
d9adf22a 5093 .module = THIS_MODULE,
ba0e4d99 5094 };
90fd131a
FW
5095 struct nft_set_dump_ctx dump_ctx = {
5096 .set = set,
5097 .ctx = ctx,
5098 };
ba0e4d99 5099
90fd131a 5100 c.data = &dump_ctx;
d9adf22a 5101 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
ba0e4d99
PNA
5102 }
5103
5104 if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
5105 return -EINVAL;
5106
5107 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
5108 err = nft_get_set_elem(&ctx, set, attr);
5109 if (err < 0)
5110 break;
5111 }
5112
5113 return err;
5114}
5115
25e94a99
PNA
5116static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
5117 const struct nft_set *set,
5118 const struct nft_set_elem *elem,
5119 int event, u16 flags)
d60ce62f 5120{
0854db2a 5121 struct nftables_pernet *nft_net;
128ad332
PNA
5122 struct net *net = ctx->net;
5123 u32 portid = ctx->portid;
d60ce62f
AB
5124 struct sk_buff *skb;
5125 int err;
5126
128ad332 5127 if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 5128 return;
d60ce62f 5129
d60ce62f
AB
5130 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
5131 if (skb == NULL)
5132 goto err;
5133
5134 err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
5135 set, elem);
5136 if (err < 0) {
5137 kfree_skb(skb);
5138 goto err;
5139 }
5140
0854db2a
FW
5141 nft_net = net_generic(net, nf_tables_net_id);
5142 nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
25e94a99 5143 return;
d60ce62f 5144err:
25e94a99 5145 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
d60ce62f
AB
5146}
5147
60319eb1
PNA
5148static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
5149 int msg_type,
5150 struct nft_set *set)
5151{
5152 struct nft_trans *trans;
5153
5154 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_elem));
5155 if (trans == NULL)
5156 return NULL;
5157
5158 nft_trans_elem_set(trans) = set;
5159 return trans;
5160}
5161
a7fc9368
PNA
5162struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
5163 const struct nft_set *set,
5164 const struct nlattr *attr)
5165{
5166 struct nft_expr *expr;
5167 int err;
5168
5169 expr = nft_expr_init(ctx, attr);
5170 if (IS_ERR(expr))
5171 return expr;
5172
5173 err = -EOPNOTSUPP;
5174 if (!(expr->ops->type->flags & NFT_EXPR_STATEFUL))
5175 goto err_set_elem_expr;
5176
5177 if (expr->ops->type->flags & NFT_EXPR_GC) {
5178 if (set->flags & NFT_SET_TIMEOUT)
5179 goto err_set_elem_expr;
5180 if (!set->ops->gc_init)
5181 goto err_set_elem_expr;
5182 set->ops->gc_init(set);
5183 }
5184
5185 return expr;
5186
5187err_set_elem_expr:
5188 nft_expr_destroy(ctx, expr);
5189 return ERR_PTR(err);
5190}
5191
22fe54d5
PM
5192void *nft_set_elem_init(const struct nft_set *set,
5193 const struct nft_set_ext_tmpl *tmpl,
7b225d0b
PNA
5194 const u32 *key, const u32 *key_end,
5195 const u32 *data, u64 timeout, u64 expiration, gfp_t gfp)
fe2811eb
PM
5196{
5197 struct nft_set_ext *ext;
5198 void *elem;
5199
5200 elem = kzalloc(set->ops->elemsize + tmpl->len, gfp);
5201 if (elem == NULL)
5202 return NULL;
5203
5204 ext = nft_set_elem_ext(set, elem);
5205 nft_set_ext_init(ext, tmpl);
5206
5207 memcpy(nft_set_ext_key(ext), key, set->klen);
7b225d0b
PNA
5208 if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END))
5209 memcpy(nft_set_ext_key_end(ext), key_end, set->klen);
fe2811eb
PM
5210 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
5211 memcpy(nft_set_ext_data(ext), data, set->dlen);
79ebb5bb
LGL
5212 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
5213 *nft_set_ext_expiration(ext) = get_jiffies_64() + expiration;
5214 if (expiration == 0)
5215 *nft_set_ext_expiration(ext) += timeout;
5216 }
c3e1b005
PM
5217 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
5218 *nft_set_ext_timeout(ext) = timeout;
fe2811eb
PM
5219
5220 return elem;
5221}
5222
563125a7
PNA
5223static void __nft_set_elem_expr_destroy(const struct nft_ctx *ctx,
5224 struct nft_expr *expr)
475beb9c
PNA
5225{
5226 if (expr->ops->destroy_clone) {
5227 expr->ops->destroy_clone(ctx, expr);
5228 module_put(expr->ops->type->owner);
5229 } else {
5230 nf_tables_expr_destroy(ctx, expr);
5231 }
5232}
5233
563125a7
PNA
5234static void nft_set_elem_expr_destroy(const struct nft_ctx *ctx,
5235 struct nft_set_elem_expr *elem_expr)
5236{
5237 struct nft_expr *expr;
5238 u32 size;
5239
5240 nft_setelem_expr_foreach(expr, elem_expr, size)
5241 __nft_set_elem_expr_destroy(ctx, expr);
5242}
5243
61f9e292
LZ
5244void nft_set_elem_destroy(const struct nft_set *set, void *elem,
5245 bool destroy_expr)
61edafbb
PM
5246{
5247 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3453c927
PNA
5248 struct nft_ctx ctx = {
5249 .net = read_pnet(&set->net),
5250 .family = set->table->family,
5251 };
61edafbb 5252
59105446 5253 nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
61edafbb 5254 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
59105446 5255 nft_data_release(nft_set_ext_data(ext), set->dtype);
563125a7 5256 if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS))
475beb9c 5257 nft_set_elem_expr_destroy(&ctx, nft_set_ext_expr(ext));
371ebcbb 5258
8aeff920
PNA
5259 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
5260 (*nft_set_ext_obj(ext))->use--;
61edafbb
PM
5261 kfree(elem);
5262}
5263EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
5264
59105446
PNA
5265/* Only called from commit path, nft_set_elem_deactivate() already deals with
5266 * the refcounting from the preparation phase.
5267 */
3453c927
PNA
5268static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
5269 const struct nft_set *set, void *elem)
59105446
PNA
5270{
5271 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
5272
563125a7 5273 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPRESSIONS))
475beb9c
PNA
5274 nft_set_elem_expr_destroy(ctx, nft_set_ext_expr(ext));
5275
59105446
PNA
5276 kfree(elem);
5277}
5278
fca05d4d
PNA
5279int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set,
5280 struct nft_expr *expr_array[])
8cfd9b0f
PNA
5281{
5282 struct nft_expr *expr;
5283 int err, i, k;
5284
5285 for (i = 0; i < set->num_exprs; i++) {
5286 expr = kzalloc(set->exprs[i]->ops->size, GFP_KERNEL);
5287 if (!expr)
5288 goto err_expr;
5289
5290 err = nft_expr_clone(expr, set->exprs[i]);
5291 if (err < 0) {
5292 nft_expr_destroy(ctx, expr);
5293 goto err_expr;
5294 }
5295 expr_array[i] = expr;
5296 }
5297
5298 return 0;
5299
5300err_expr:
161b838e
CIK
5301 for (k = i - 1; k >= 0; k--)
5302 nft_expr_destroy(ctx, expr_array[k]);
8cfd9b0f
PNA
5303
5304 return -ENOMEM;
5305}
5306
4d8f9065
PNA
5307static int nft_set_elem_expr_setup(struct nft_ctx *ctx,
5308 const struct nft_set_ext *ext,
5309 struct nft_expr *expr_array[],
5310 u32 num_exprs)
563125a7
PNA
5311{
5312 struct nft_set_elem_expr *elem_expr = nft_set_ext_expr(ext);
4d8f9065
PNA
5313 struct nft_expr *expr;
5314 int i, err;
5315
5316 for (i = 0; i < num_exprs; i++) {
5317 expr = nft_setelem_expr_at(elem_expr, elem_expr->size);
5318 err = nft_expr_clone(expr, expr_array[i]);
5319 if (err < 0)
5320 goto err_elem_expr_setup;
5321
5322 elem_expr->size += expr_array[i]->ops->size;
5323 nft_expr_destroy(ctx, expr_array[i]);
5324 expr_array[i] = NULL;
5325 }
5326
5327 return 0;
5328
5329err_elem_expr_setup:
5330 for (; i < num_exprs; i++) {
5331 nft_expr_destroy(ctx, expr_array[i]);
5332 expr_array[i] = NULL;
5333 }
563125a7 5334
4d8f9065 5335 return -ENOMEM;
563125a7
PNA
5336}
5337
60319eb1 5338static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
c016c7e4 5339 const struct nlattr *attr, u32 nlmsg_flags)
20a69341 5340{
8cfd9b0f 5341 struct nft_expr *expr_array[NFT_SET_EXPR_MAX] = {};
20a69341 5342 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
8aeff920 5343 u8 genmask = nft_genmask_next(ctx->net);
664899e8 5344 u32 flags = 0, size = 0, num_exprs = 0;
fe2811eb 5345 struct nft_set_ext_tmpl tmpl;
c016c7e4 5346 struct nft_set_ext *ext, *ext2;
20a69341
PM
5347 struct nft_set_elem elem;
5348 struct nft_set_binding *binding;
8aeff920 5349 struct nft_object *obj = NULL;
68e942e8 5350 struct nft_userdata *udata;
20a1452c 5351 struct nft_data_desc desc;
20a69341 5352 enum nft_registers dreg;
60319eb1 5353 struct nft_trans *trans;
c3e1b005 5354 u64 timeout;
79ebb5bb 5355 u64 expiration;
8cfd9b0f 5356 int err, i;
68e942e8 5357 u8 ulen;
20a69341 5358
8cb08174
JB
5359 err = nla_parse_nested_deprecated(nla, NFTA_SET_ELEM_MAX, attr,
5360 nft_set_elem_policy, NULL);
20a69341
PM
5361 if (err < 0)
5362 return err;
5363
5364 if (nla[NFTA_SET_ELEM_KEY] == NULL)
5365 return -EINVAL;
5366
fe2811eb
PM
5367 nft_set_ext_prepare(&tmpl);
5368
0e9091d6
PNA
5369 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
5370 if (err < 0)
5371 return err;
5372 if (flags != 0)
5373 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
20a69341
PM
5374
5375 if (set->flags & NFT_SET_MAP) {
5376 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
fe2811eb 5377 !(flags & NFT_SET_ELEM_INTERVAL_END))
20a69341
PM
5378 return -EINVAL;
5379 } else {
5380 if (nla[NFTA_SET_ELEM_DATA] != NULL)
5381 return -EINVAL;
5382 }
5383
bffc124b
PNA
5384 if ((flags & NFT_SET_ELEM_INTERVAL_END) &&
5385 (nla[NFTA_SET_ELEM_DATA] ||
5386 nla[NFTA_SET_ELEM_OBJREF] ||
5387 nla[NFTA_SET_ELEM_TIMEOUT] ||
5388 nla[NFTA_SET_ELEM_EXPIRATION] ||
5389 nla[NFTA_SET_ELEM_USERDATA] ||
48b0ae04
PNA
5390 nla[NFTA_SET_ELEM_EXPR] ||
5391 nla[NFTA_SET_ELEM_EXPRESSIONS]))
bffc124b
PNA
5392 return -EINVAL;
5393
c3e1b005
PM
5394 timeout = 0;
5395 if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
5396 if (!(set->flags & NFT_SET_TIMEOUT))
5397 return -EINVAL;
8e1102d5
FW
5398 err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_TIMEOUT],
5399 &timeout);
5400 if (err)
5401 return err;
c3e1b005
PM
5402 } else if (set->flags & NFT_SET_TIMEOUT) {
5403 timeout = set->timeout;
5404 }
5405
79ebb5bb
LGL
5406 expiration = 0;
5407 if (nla[NFTA_SET_ELEM_EXPIRATION] != NULL) {
5408 if (!(set->flags & NFT_SET_TIMEOUT))
5409 return -EINVAL;
5410 err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_EXPIRATION],
5411 &expiration);
5412 if (err)
5413 return err;
5414 }
5415
8cfd9b0f
PNA
5416 if (nla[NFTA_SET_ELEM_EXPR]) {
5417 struct nft_expr *expr;
5418
664899e8 5419 if (set->num_exprs && set->num_exprs != 1)
8cfd9b0f
PNA
5420 return -EOPNOTSUPP;
5421
40944452
PNA
5422 expr = nft_set_elem_expr_alloc(ctx, set,
5423 nla[NFTA_SET_ELEM_EXPR]);
5424 if (IS_ERR(expr))
5425 return PTR_ERR(expr);
65038428 5426
8cfd9b0f 5427 expr_array[0] = expr;
664899e8 5428 num_exprs = 1;
65038428 5429
664899e8 5430 if (set->num_exprs && set->exprs[0]->ops != expr->ops) {
8cfd9b0f 5431 err = -EOPNOTSUPP;
65038428 5432 goto err_set_elem_expr;
8cfd9b0f 5433 }
48b0ae04
PNA
5434 } else if (nla[NFTA_SET_ELEM_EXPRESSIONS]) {
5435 struct nft_expr *expr;
5436 struct nlattr *tmp;
5437 int left;
65038428 5438
48b0ae04
PNA
5439 i = 0;
5440 nla_for_each_nested(tmp, nla[NFTA_SET_ELEM_EXPRESSIONS], left) {
664899e8
PNA
5441 if (i == NFT_SET_EXPR_MAX ||
5442 (set->num_exprs && set->num_exprs == i)) {
48b0ae04
PNA
5443 err = -E2BIG;
5444 goto err_set_elem_expr;
5445 }
5446 if (nla_type(tmp) != NFTA_LIST_ELEM) {
5447 err = -EINVAL;
5448 goto err_set_elem_expr;
5449 }
5450 expr = nft_set_elem_expr_alloc(ctx, set, tmp);
5451 if (IS_ERR(expr)) {
5452 err = PTR_ERR(expr);
5453 goto err_set_elem_expr;
5454 }
5455 expr_array[i] = expr;
664899e8 5456 num_exprs++;
48b0ae04 5457
664899e8 5458 if (set->num_exprs && expr->ops != set->exprs[i]->ops) {
48b0ae04
PNA
5459 err = -EOPNOTSUPP;
5460 goto err_set_elem_expr;
5461 }
5462 i++;
5463 }
664899e8 5464 if (set->num_exprs && set->num_exprs != i) {
48b0ae04 5465 err = -EOPNOTSUPP;
65038428 5466 goto err_set_elem_expr;
48b0ae04 5467 }
8cfd9b0f
PNA
5468 } else if (set->num_exprs > 0) {
5469 err = nft_set_elem_expr_clone(ctx, set, expr_array);
5470 if (err < 0)
5471 goto err_set_elem_expr_clone;
664899e8
PNA
5472
5473 num_exprs = set->num_exprs;
40944452
PNA
5474 }
5475
20a1452c
PNA
5476 err = nft_setelem_parse_key(ctx, set, &elem.key.val,
5477 nla[NFTA_SET_ELEM_KEY]);
20a69341 5478 if (err < 0)
40944452 5479 goto err_set_elem_expr;
20a69341 5480
20a1452c 5481 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
7b225d0b
PNA
5482
5483 if (nla[NFTA_SET_ELEM_KEY_END]) {
5484 err = nft_setelem_parse_key(ctx, set, &elem.key_end.val,
5485 nla[NFTA_SET_ELEM_KEY_END]);
5486 if (err < 0)
5487 goto err_parse_key;
5488
5489 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY_END, set->klen);
5490 }
5491
c3e1b005
PM
5492 if (timeout > 0) {
5493 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
5494 if (timeout != set->timeout)
5495 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
5496 }
fe2811eb 5497
664899e8
PNA
5498 if (num_exprs) {
5499 for (i = 0; i < num_exprs; i++)
563125a7
PNA
5500 size += expr_array[i]->ops->size;
5501
5502 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_EXPRESSIONS,
5503 sizeof(struct nft_set_elem_expr) +
5504 size);
5505 }
40944452 5506
8aeff920
PNA
5507 if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
5508 if (!(set->flags & NFT_SET_OBJECT)) {
5509 err = -EINVAL;
7b225d0b 5510 goto err_parse_key_end;
8aeff920 5511 }
4d44175a
FW
5512 obj = nft_obj_lookup(ctx->net, ctx->table,
5513 nla[NFTA_SET_ELEM_OBJREF],
cac20fcd 5514 set->objtype, genmask);
8aeff920
PNA
5515 if (IS_ERR(obj)) {
5516 err = PTR_ERR(obj);
7b225d0b 5517 goto err_parse_key_end;
8aeff920
PNA
5518 }
5519 nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
5520 }
5521
20a69341 5522 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
fdb9c405
PNA
5523 err = nft_setelem_parse_data(ctx, set, &desc, &elem.data.val,
5524 nla[NFTA_SET_ELEM_DATA]);
20a69341 5525 if (err < 0)
7b225d0b 5526 goto err_parse_key_end;
20a69341 5527
20a69341
PM
5528 dreg = nft_type_to_reg(set->dtype);
5529 list_for_each_entry(binding, &set->bindings, list) {
5530 struct nft_ctx bind_ctx = {
58c78e10 5531 .net = ctx->net,
36596dad 5532 .family = ctx->family,
20a69341 5533 .table = ctx->table,
7c95f6d8 5534 .chain = (struct nft_chain *)binding->chain,
20a69341
PM
5535 };
5536
11113e19
PM
5537 if (!(binding->flags & NFT_SET_MAP))
5538 continue;
5539
1ec10212 5540 err = nft_validate_register_store(&bind_ctx, dreg,
fdb9c405 5541 &elem.data.val,
20a1452c 5542 desc.type, desc.len);
20a69341 5543 if (err < 0)
7b225d0b 5544 goto err_parse_data;
a654de8f 5545
20a1452c 5546 if (desc.type == NFT_DATA_VERDICT &&
fdb9c405
PNA
5547 (elem.data.val.verdict.code == NFT_GOTO ||
5548 elem.data.val.verdict.code == NFT_JUMP))
a654de8f
PNA
5549 nft_validate_state_update(ctx->net,
5550 NFT_VALIDATE_NEED);
20a69341 5551 }
fe2811eb 5552
20a1452c 5553 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, desc.len);
20a69341
PM
5554 }
5555
68e942e8
PM
5556 /* The full maximum length of userdata can exceed the maximum
5557 * offset value (U8_MAX) for following extensions, therefor it
5558 * must be the last extension added.
5559 */
5560 ulen = 0;
5561 if (nla[NFTA_SET_ELEM_USERDATA] != NULL) {
5562 ulen = nla_len(nla[NFTA_SET_ELEM_USERDATA]);
5563 if (ulen > 0)
5564 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_USERDATA,
5565 ulen);
5566 }
5567
fe2811eb 5568 err = -ENOMEM;
7b225d0b 5569 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data,
fdb9c405 5570 elem.key_end.val.data, elem.data.val.data,
79ebb5bb 5571 timeout, expiration, GFP_KERNEL);
fe2811eb 5572 if (elem.priv == NULL)
7b225d0b 5573 goto err_parse_data;
fe2811eb
PM
5574
5575 ext = nft_set_elem_ext(set, elem.priv);
5576 if (flags)
5577 *nft_set_ext_flags(ext) = flags;
68e942e8
PM
5578 if (ulen > 0) {
5579 udata = nft_set_ext_userdata(ext);
5580 udata->len = ulen - 1;
5581 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
5582 }
8aeff920
PNA
5583 if (obj) {
5584 *nft_set_ext_obj(ext) = obj;
5585 obj->use++;
5586 }
4d8f9065
PNA
5587 err = nft_set_elem_expr_setup(ctx, ext, expr_array, num_exprs);
5588 if (err < 0)
5589 goto err_elem_expr;
fe2811eb 5590
60319eb1 5591 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
4d8f9065
PNA
5592 if (trans == NULL) {
5593 err = -ENOMEM;
5594 goto err_elem_expr;
5595 }
60319eb1 5596
69086658 5597 ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
c016c7e4
PNA
5598 err = set->ops->insert(ctx->net, set, &elem, &ext2);
5599 if (err) {
5600 if (err == -EEXIST) {
9744a6fc
PNA
5601 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
5602 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
5603 nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
77a92189 5604 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF))
7b225d0b 5605 goto err_element_clash;
8aeff920
PNA
5606 if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
5607 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
5608 memcmp(nft_set_ext_data(ext),
5609 nft_set_ext_data(ext2), set->dlen) != 0) ||
5610 (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
5611 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
5612 *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
77a92189 5613 goto err_element_clash;
c016c7e4
PNA
5614 else if (!(nlmsg_flags & NLM_F_EXCL))
5615 err = 0;
8c2d45b2
PNA
5616 } else if (err == -ENOTEMPTY) {
5617 /* ENOTEMPTY reports overlapping between this element
5618 * and an existing one.
5619 */
5620 err = -EEXIST;
c016c7e4 5621 }
7b225d0b 5622 goto err_element_clash;
c016c7e4 5623 }
20a69341 5624
35d0ac90
PNA
5625 if (set->size &&
5626 !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) {
5627 err = -ENFILE;
7b225d0b 5628 goto err_set_full;
35d0ac90
PNA
5629 }
5630
60319eb1 5631 nft_trans_elem(trans) = elem;
0854db2a 5632 nft_trans_commit_list_add_tail(ctx->net, trans);
20a69341
PM
5633 return 0;
5634
7b225d0b 5635err_set_full:
5cb82a38 5636 set->ops->remove(ctx->net, set, &elem);
7b225d0b 5637err_element_clash:
60319eb1 5638 kfree(trans);
4d8f9065 5639err_elem_expr:
b91d9036
TY
5640 if (obj)
5641 obj->use--;
475beb9c
PNA
5642
5643 nf_tables_set_elem_destroy(ctx, set, elem.priv);
7b225d0b 5644err_parse_data:
20a69341 5645 if (nla[NFTA_SET_ELEM_DATA] != NULL)
fdb9c405 5646 nft_data_release(&elem.data.val, desc.type);
7b225d0b
PNA
5647err_parse_key_end:
5648 nft_data_release(&elem.key_end.val, NFT_DATA_VALUE);
5649err_parse_key:
20a1452c 5650 nft_data_release(&elem.key.val, NFT_DATA_VALUE);
40944452 5651err_set_elem_expr:
664899e8 5652 for (i = 0; i < num_exprs && expr_array[i]; i++)
8cfd9b0f
PNA
5653 nft_expr_destroy(ctx, expr_array[i]);
5654err_set_elem_expr_clone:
20a69341
PM
5655 return err;
5656}
5657
633c9a84
PNA
5658static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
5659 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
5660 const struct nlattr * const nla[],
5661 struct netlink_ext_ack *extack)
20a69341 5662{
0854db2a 5663 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
f2a6d766 5664 u8 genmask = nft_genmask_next(net);
20a69341
PM
5665 const struct nlattr *attr;
5666 struct nft_set *set;
5667 struct nft_ctx ctx;
a654de8f 5668 int rem, err;
20a69341 5669
7d5570ca
PNA
5670 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
5671 return -EINVAL;
5672
36dd1bcc 5673 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
6001a930 5674 genmask, NETLINK_CB(skb).portid);
20a69341
PM
5675 if (err < 0)
5676 return err;
5677
a3073c17
PNA
5678 set = nft_set_lookup_global(net, ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
5679 nla[NFTA_SET_ELEM_LIST_SET_ID], genmask);
5680 if (IS_ERR(set))
5681 return PTR_ERR(set);
958bee14 5682
20a69341
PM
5683 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
5684 return -EBUSY;
5685
5686 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
c016c7e4 5687 err = nft_add_set_elem(&ctx, set, attr, nlh->nlmsg_flags);
35d0ac90 5688 if (err < 0)
a654de8f 5689 return err;
20a69341 5690 }
a654de8f 5691
0854db2a 5692 if (nft_net->validate_state == NFT_VALIDATE_DO)
a654de8f
PNA
5693 return nft_table_validate(net, ctx.table);
5694
5695 return 0;
20a69341
PM
5696}
5697
59105446
PNA
5698/**
5699 * nft_data_hold - hold a nft_data item
5700 *
5701 * @data: struct nft_data to release
5702 * @type: type of data
5703 *
5704 * Hold a nft_data item. NFT_DATA_VALUE types can be silently discarded,
5705 * NFT_DATA_VERDICT bumps the reference to chains in case of NFT_JUMP and
5706 * NFT_GOTO verdicts. This function must be called on active data objects
5707 * from the second phase of the commit protocol.
5708 */
bb7b40ae 5709void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
59105446 5710{
d0e2c7de
PNA
5711 struct nft_chain *chain;
5712 struct nft_rule *rule;
5713
59105446
PNA
5714 if (type == NFT_DATA_VERDICT) {
5715 switch (data->verdict.code) {
5716 case NFT_JUMP:
5717 case NFT_GOTO:
d0e2c7de
PNA
5718 chain = data->verdict.chain;
5719 chain->use++;
5720
5721 if (!nft_chain_is_bound(chain))
5722 break;
5723
5724 chain->table->use++;
5725 list_for_each_entry(rule, &chain->rules, list)
5726 chain->use++;
5727
5728 nft_chain_add(chain->table, chain);
59105446
PNA
5729 break;
5730 }
5731 }
5732}
5733
5734static void nft_set_elem_activate(const struct net *net,
5735 const struct nft_set *set,
5736 struct nft_set_elem *elem)
5737{
5738 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
5739
5740 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
5741 nft_data_hold(nft_set_ext_data(ext), set->dtype);
5742 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
5743 (*nft_set_ext_obj(ext))->use++;
5744}
5745
5746static void nft_set_elem_deactivate(const struct net *net,
5747 const struct nft_set *set,
5748 struct nft_set_elem *elem)
5749{
5750 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
5751
5752 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
5753 nft_data_release(nft_set_ext_data(ext), set->dtype);
5754 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
5755 (*nft_set_ext_obj(ext))->use--;
5756}
5757
60319eb1 5758static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
20a69341
PM
5759 const struct nlattr *attr)
5760{
5761 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3971ca14 5762 struct nft_set_ext_tmpl tmpl;
20a69341 5763 struct nft_set_elem elem;
3971ca14 5764 struct nft_set_ext *ext;
60319eb1 5765 struct nft_trans *trans;
3971ca14
PNA
5766 u32 flags = 0;
5767 void *priv;
20a69341
PM
5768 int err;
5769
8cb08174
JB
5770 err = nla_parse_nested_deprecated(nla, NFTA_SET_ELEM_MAX, attr,
5771 nft_set_elem_policy, NULL);
20a69341 5772 if (err < 0)
20a1452c 5773 return err;
20a69341 5774
20a69341 5775 if (nla[NFTA_SET_ELEM_KEY] == NULL)
20a1452c 5776 return -EINVAL;
20a69341 5777
3971ca14
PNA
5778 nft_set_ext_prepare(&tmpl);
5779
5780 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
5781 if (err < 0)
5782 return err;
5783 if (flags != 0)
5784 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
5785
20a1452c
PNA
5786 err = nft_setelem_parse_key(ctx, set, &elem.key.val,
5787 nla[NFTA_SET_ELEM_KEY]);
20a69341 5788 if (err < 0)
20a1452c 5789 return err;
20a69341 5790
20a1452c 5791 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
3971ca14 5792
7b225d0b
PNA
5793 if (nla[NFTA_SET_ELEM_KEY_END]) {
5794 err = nft_setelem_parse_key(ctx, set, &elem.key_end.val,
5795 nla[NFTA_SET_ELEM_KEY_END]);
5796 if (err < 0)
5797 return err;
5798
5799 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY_END, set->klen);
5800 }
5801
3971ca14 5802 err = -ENOMEM;
7b225d0b
PNA
5803 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data,
5804 elem.key_end.val.data, NULL, 0, 0,
5805 GFP_KERNEL);
3971ca14 5806 if (elem.priv == NULL)
20a1452c 5807 goto fail_elem;
3971ca14
PNA
5808
5809 ext = nft_set_elem_ext(set, elem.priv);
5810 if (flags)
5811 *nft_set_ext_flags(ext) = flags;
5812
60319eb1 5813 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
20a1452c
PNA
5814 if (trans == NULL)
5815 goto fail_trans;
20a69341 5816
42a55769 5817 priv = set->ops->deactivate(ctx->net, set, &elem);
3971ca14 5818 if (priv == NULL) {
cc02e457 5819 err = -ENOENT;
20a1452c 5820 goto fail_ops;
cc02e457 5821 }
3971ca14
PNA
5822 kfree(elem.priv);
5823 elem.priv = priv;
cc02e457 5824
59105446
PNA
5825 nft_set_elem_deactivate(ctx->net, set, &elem);
5826
60319eb1 5827 nft_trans_elem(trans) = elem;
0854db2a 5828 nft_trans_commit_list_add_tail(ctx->net, trans);
0dc13625 5829 return 0;
cc02e457 5830
20a1452c 5831fail_ops:
cc02e457 5832 kfree(trans);
20a1452c 5833fail_trans:
3971ca14 5834 kfree(elem.priv);
20a1452c
PNA
5835fail_elem:
5836 nft_data_release(&elem.key.val, NFT_DATA_VALUE);
20a69341
PM
5837 return err;
5838}
5839
8411b644 5840static int nft_flush_set(const struct nft_ctx *ctx,
de70185d 5841 struct nft_set *set,
8411b644 5842 const struct nft_set_iter *iter,
de70185d 5843 struct nft_set_elem *elem)
8411b644
PNA
5844{
5845 struct nft_trans *trans;
5846 int err;
5847
5848 trans = nft_trans_alloc_gfp(ctx, NFT_MSG_DELSETELEM,
5849 sizeof(struct nft_trans_elem), GFP_ATOMIC);
5850 if (!trans)
5851 return -ENOMEM;
5852
1ba1c414 5853 if (!set->ops->flush(ctx->net, set, elem->priv)) {
8411b644
PNA
5854 err = -ENOENT;
5855 goto err1;
5856 }
b2c11e4b 5857 set->ndeact++;
8411b644 5858
7acfda53 5859 nft_set_elem_deactivate(ctx->net, set, elem);
de70185d
PNA
5860 nft_trans_elem_set(trans) = set;
5861 nft_trans_elem(trans) = *elem;
0854db2a 5862 nft_trans_commit_list_add_tail(ctx->net, trans);
8411b644
PNA
5863
5864 return 0;
5865err1:
5866 kfree(trans);
5867 return err;
5868}
5869
633c9a84
PNA
5870static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
5871 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
5872 const struct nlattr * const nla[],
5873 struct netlink_ext_ack *extack)
20a69341 5874{
f2a6d766 5875 u8 genmask = nft_genmask_next(net);
20a69341
PM
5876 const struct nlattr *attr;
5877 struct nft_set *set;
5878 struct nft_ctx ctx;
60319eb1 5879 int rem, err = 0;
20a69341 5880
36dd1bcc 5881 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
6001a930 5882 genmask, NETLINK_CB(skb).portid);
20a69341
PM
5883 if (err < 0)
5884 return err;
5885
cac20fcd 5886 set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
20a69341
PM
5887 if (IS_ERR(set))
5888 return PTR_ERR(set);
5889 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
5890 return -EBUSY;
5891
8411b644 5892 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
baa2d42c
PNA
5893 struct nft_set_iter iter = {
5894 .genmask = genmask,
5895 .fn = nft_flush_set,
8411b644 5896 };
baa2d42c 5897 set->ops->walk(&ctx, set, &iter);
8411b644 5898
baa2d42c 5899 return iter.err;
8411b644
PNA
5900 }
5901
20a69341
PM
5902 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
5903 err = nft_del_setelem(&ctx, set, attr);
5904 if (err < 0)
60319eb1 5905 break;
4fefee57 5906
3dd0673a 5907 set->ndeact++;
20a69341 5908 }
60319eb1 5909 return err;
20a69341
PM
5910}
5911
cfed7e1b
PM
5912void nft_set_gc_batch_release(struct rcu_head *rcu)
5913{
5914 struct nft_set_gc_batch *gcb;
5915 unsigned int i;
5916
5917 gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
5918 for (i = 0; i < gcb->head.cnt; i++)
61f9e292 5919 nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
cfed7e1b
PM
5920 kfree(gcb);
5921}
cfed7e1b
PM
5922
5923struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
5924 gfp_t gfp)
5925{
5926 struct nft_set_gc_batch *gcb;
5927
5928 gcb = kzalloc(sizeof(*gcb), gfp);
5929 if (gcb == NULL)
5930 return gcb;
5931 gcb->head.set = set;
5932 return gcb;
5933}
cfed7e1b 5934
e5009240
PNA
5935/*
5936 * Stateful objects
5937 */
5938
5939/**
5940 * nft_register_obj- register nf_tables stateful object type
3db86c39 5941 * @obj_type: object type
e5009240
PNA
5942 *
5943 * Registers the object type for use with nf_tables. Returns zero on
5944 * success or a negative errno code otherwise.
5945 */
5946int nft_register_obj(struct nft_object_type *obj_type)
5947{
5948 if (obj_type->type == NFT_OBJECT_UNSPEC)
5949 return -EINVAL;
5950
5951 nfnl_lock(NFNL_SUBSYS_NFTABLES);
5952 list_add_rcu(&obj_type->list, &nf_tables_objects);
5953 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5954 return 0;
5955}
5956EXPORT_SYMBOL_GPL(nft_register_obj);
5957
5958/**
5959 * nft_unregister_obj - unregister nf_tables object type
3db86c39 5960 * @obj_type: object type
e5009240
PNA
5961 *
5962 * Unregisters the object type for use with nf_tables.
5963 */
5964void nft_unregister_obj(struct nft_object_type *obj_type)
5965{
5966 nfnl_lock(NFNL_SUBSYS_NFTABLES);
5967 list_del_rcu(&obj_type->list);
5968 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5969}
5970EXPORT_SYMBOL_GPL(nft_unregister_obj);
5971
4d44175a
FW
5972struct nft_object *nft_obj_lookup(const struct net *net,
5973 const struct nft_table *table,
cac20fcd
PNA
5974 const struct nlattr *nla, u32 objtype,
5975 u8 genmask)
e5009240 5976{
4d44175a
FW
5977 struct nft_object_hash_key k = { .table = table };
5978 char search[NFT_OBJ_MAXNAMELEN];
5979 struct rhlist_head *tmp, *list;
e5009240
PNA
5980 struct nft_object *obj;
5981
872f6903 5982 nla_strscpy(search, nla, sizeof(search));
4d44175a
FW
5983 k.name = search;
5984
5985 WARN_ON_ONCE(!rcu_read_lock_held() &&
5986 !lockdep_commit_lock_is_held(net));
5987
5988 rcu_read_lock();
5989 list = rhltable_lookup(&nft_objname_ht, &k, nft_objname_ht_params);
5990 if (!list)
5991 goto out;
5992
5993 rhl_for_each_entry_rcu(obj, tmp, list, rhlhead) {
5994 if (objtype == obj->ops->type->type &&
5995 nft_active_genmask(obj, genmask)) {
5996 rcu_read_unlock();
e5009240 5997 return obj;
4d44175a 5998 }
e5009240 5999 }
4d44175a
FW
6000out:
6001 rcu_read_unlock();
e5009240
PNA
6002 return ERR_PTR(-ENOENT);
6003}
cac20fcd 6004EXPORT_SYMBOL_GPL(nft_obj_lookup);
e5009240 6005
cac20fcd
PNA
6006static struct nft_object *nft_obj_lookup_byhandle(const struct nft_table *table,
6007 const struct nlattr *nla,
6008 u32 objtype, u8 genmask)
3ecbfd65
HS
6009{
6010 struct nft_object *obj;
6011
6012 list_for_each_entry(obj, &table->objects, list) {
6013 if (be64_to_cpu(nla_get_be64(nla)) == obj->handle &&
6014 objtype == obj->ops->type->type &&
6015 nft_active_genmask(obj, genmask))
6016 return obj;
6017 }
6018 return ERR_PTR(-ENOENT);
6019}
6020
e5009240 6021static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
b2fbd044
LZ
6022 [NFTA_OBJ_TABLE] = { .type = NLA_STRING,
6023 .len = NFT_TABLE_MAXNAMELEN - 1 },
6024 [NFTA_OBJ_NAME] = { .type = NLA_STRING,
6025 .len = NFT_OBJ_MAXNAMELEN - 1 },
e5009240
PNA
6026 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
6027 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
3ecbfd65 6028 [NFTA_OBJ_HANDLE] = { .type = NLA_U64},
b131c964
JGG
6029 [NFTA_OBJ_USERDATA] = { .type = NLA_BINARY,
6030 .len = NFT_USERDATA_MAXLEN },
e5009240
PNA
6031};
6032
84fba055
FW
6033static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,
6034 const struct nft_object_type *type,
e5009240
PNA
6035 const struct nlattr *attr)
6036{
5b4c6e38 6037 struct nlattr **tb;
dfc46034 6038 const struct nft_object_ops *ops;
e5009240 6039 struct nft_object *obj;
5b4c6e38
GS
6040 int err = -ENOMEM;
6041
6042 tb = kmalloc_array(type->maxattr + 1, sizeof(*tb), GFP_KERNEL);
6043 if (!tb)
6044 goto err1;
e5009240
PNA
6045
6046 if (attr) {
8cb08174
JB
6047 err = nla_parse_nested_deprecated(tb, type->maxattr, attr,
6048 type->policy, NULL);
e5009240 6049 if (err < 0)
5b4c6e38 6050 goto err2;
e5009240
PNA
6051 } else {
6052 memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));
6053 }
6054
dfc46034
PBG
6055 if (type->select_ops) {
6056 ops = type->select_ops(ctx, (const struct nlattr * const *)tb);
6057 if (IS_ERR(ops)) {
6058 err = PTR_ERR(ops);
5b4c6e38 6059 goto err2;
dfc46034
PBG
6060 }
6061 } else {
6062 ops = type->ops;
6063 }
6064
e5009240 6065 err = -ENOMEM;
dfc46034 6066 obj = kzalloc(sizeof(*obj) + ops->size, GFP_KERNEL);
5b4c6e38
GS
6067 if (!obj)
6068 goto err2;
e5009240 6069
dfc46034 6070 err = ops->init(ctx, (const struct nlattr * const *)tb, obj);
e5009240 6071 if (err < 0)
5b4c6e38 6072 goto err3;
e5009240 6073
dfc46034
PBG
6074 obj->ops = ops;
6075
5b4c6e38 6076 kfree(tb);
e5009240 6077 return obj;
5b4c6e38 6078err3:
e5009240 6079 kfree(obj);
5b4c6e38
GS
6080err2:
6081 kfree(tb);
e5009240
PNA
6082err1:
6083 return ERR_PTR(err);
6084}
6085
6086static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
43da04a5 6087 struct nft_object *obj, bool reset)
e5009240
PNA
6088{
6089 struct nlattr *nest;
6090
ae0be8de 6091 nest = nla_nest_start_noflag(skb, attr);
e5009240
PNA
6092 if (!nest)
6093 goto nla_put_failure;
dfc46034 6094 if (obj->ops->dump(skb, obj, reset) < 0)
e5009240
PNA
6095 goto nla_put_failure;
6096 nla_nest_end(skb, nest);
6097 return 0;
6098
6099nla_put_failure:
6100 return -1;
6101}
6102
6103static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
6104{
6105 const struct nft_object_type *type;
6106
6107 list_for_each_entry(type, &nf_tables_objects, list) {
6108 if (objtype == type->type)
6109 return type;
6110 }
6111 return NULL;
6112}
6113
452238e8
FW
6114static const struct nft_object_type *
6115nft_obj_type_get(struct net *net, u32 objtype)
e5009240
PNA
6116{
6117 const struct nft_object_type *type;
6118
6119 type = __nft_obj_type_get(objtype);
6120 if (type != NULL && try_module_get(type->owner))
6121 return type;
6122
f102d66b 6123 lockdep_nfnl_nft_mutex_not_held();
e5009240
PNA
6124#ifdef CONFIG_MODULES
6125 if (type == NULL) {
eb014de4 6126 if (nft_request_module(net, "nft-obj-%u", objtype) == -EAGAIN)
e5009240
PNA
6127 return ERR_PTR(-EAGAIN);
6128 }
6129#endif
6130 return ERR_PTR(-ENOENT);
6131}
6132
d62d0ba9
FFM
6133static int nf_tables_updobj(const struct nft_ctx *ctx,
6134 const struct nft_object_type *type,
6135 const struct nlattr *attr,
6136 struct nft_object *obj)
6137{
6138 struct nft_object *newobj;
6139 struct nft_trans *trans;
6140 int err;
6141
6142 trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ,
6143 sizeof(struct nft_trans_obj));
6144 if (!trans)
6145 return -ENOMEM;
6146
6147 newobj = nft_obj_init(ctx, type, attr);
6148 if (IS_ERR(newobj)) {
6149 err = PTR_ERR(newobj);
b74ae961 6150 goto err_free_trans;
d62d0ba9
FFM
6151 }
6152
6153 nft_trans_obj(trans) = obj;
6154 nft_trans_obj_update(trans) = true;
6155 nft_trans_obj_newobj(trans) = newobj;
0854db2a 6156 nft_trans_commit_list_add_tail(ctx->net, trans);
d62d0ba9
FFM
6157
6158 return 0;
b74ae961
DC
6159
6160err_free_trans:
d62d0ba9 6161 kfree(trans);
d62d0ba9
FFM
6162 return err;
6163}
6164
e5009240
PNA
6165static int nf_tables_newobj(struct net *net, struct sock *nlsk,
6166 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
6167 const struct nlattr * const nla[],
6168 struct netlink_ext_ack *extack)
e5009240
PNA
6169{
6170 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
6171 const struct nft_object_type *type;
6172 u8 genmask = nft_genmask_next(net);
6173 int family = nfmsg->nfgen_family;
e5009240
PNA
6174 struct nft_table *table;
6175 struct nft_object *obj;
6176 struct nft_ctx ctx;
6177 u32 objtype;
6178 int err;
6179
6180 if (!nla[NFTA_OBJ_TYPE] ||
6181 !nla[NFTA_OBJ_NAME] ||
6182 !nla[NFTA_OBJ_DATA])
6183 return -EINVAL;
6184
6001a930
PNA
6185 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask,
6186 NETLINK_CB(skb).portid);
36dd1bcc
PNA
6187 if (IS_ERR(table)) {
6188 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 6189 return PTR_ERR(table);
36dd1bcc 6190 }
e5009240
PNA
6191
6192 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4d44175a 6193 obj = nft_obj_lookup(net, table, nla[NFTA_OBJ_NAME], objtype, genmask);
e5009240
PNA
6194 if (IS_ERR(obj)) {
6195 err = PTR_ERR(obj);
36dd1bcc
PNA
6196 if (err != -ENOENT) {
6197 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 6198 return err;
36dd1bcc 6199 }
1a28ad74 6200 } else {
36dd1bcc
PNA
6201 if (nlh->nlmsg_flags & NLM_F_EXCL) {
6202 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 6203 return -EEXIST;
36dd1bcc 6204 }
d62d0ba9
FFM
6205 if (nlh->nlmsg_flags & NLM_F_REPLACE)
6206 return -EOPNOTSUPP;
6207
fd57d0cb 6208 type = __nft_obj_type_get(objtype);
d62d0ba9
FFM
6209 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
6210
6211 return nf_tables_updobj(&ctx, type, nla[NFTA_OBJ_DATA], obj);
e5009240
PNA
6212 }
6213
98319cb9 6214 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e5009240 6215
452238e8 6216 type = nft_obj_type_get(net, objtype);
e5009240
PNA
6217 if (IS_ERR(type))
6218 return PTR_ERR(type);
6219
84fba055 6220 obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
e5009240
PNA
6221 if (IS_ERR(obj)) {
6222 err = PTR_ERR(obj);
b131c964 6223 goto err_init;
e5009240 6224 }
d152159b 6225 obj->key.table = table;
3ecbfd65
HS
6226 obj->handle = nf_tables_alloc_handle(table);
6227
d152159b
FW
6228 obj->key.name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
6229 if (!obj->key.name) {
61509575 6230 err = -ENOMEM;
b131c964
JGG
6231 goto err_strdup;
6232 }
6233
6234 if (nla[NFTA_OBJ_USERDATA]) {
85db827a 6235 obj->udata = nla_memdup(nla[NFTA_OBJ_USERDATA], GFP_KERNEL);
b131c964
JGG
6236 if (obj->udata == NULL)
6237 goto err_userdata;
6238
85db827a 6239 obj->udlen = nla_len(nla[NFTA_OBJ_USERDATA]);
61509575 6240 }
e5009240
PNA
6241
6242 err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj);
6243 if (err < 0)
b131c964 6244 goto err_trans;
e5009240 6245
4d44175a
FW
6246 err = rhltable_insert(&nft_objname_ht, &obj->rhlhead,
6247 nft_objname_ht_params);
6248 if (err < 0)
b131c964 6249 goto err_obj_ht;
4d44175a 6250
e5009240
PNA
6251 list_add_tail_rcu(&obj->list, &table->objects);
6252 table->use++;
6253 return 0;
b131c964 6254err_obj_ht:
4d44175a
FW
6255 /* queued in transaction log */
6256 INIT_LIST_HEAD(&obj->list);
6257 return err;
b131c964 6258err_trans:
d152159b 6259 kfree(obj->key.name);
b131c964
JGG
6260err_userdata:
6261 kfree(obj->udata);
6262err_strdup:
dfc46034 6263 if (obj->ops->destroy)
00bfb320 6264 obj->ops->destroy(&ctx, obj);
e5009240 6265 kfree(obj);
b131c964 6266err_init:
e5009240
PNA
6267 module_put(type->owner);
6268 return err;
6269}
6270
6271static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
6272 u32 portid, u32 seq, int event, u32 flags,
6273 int family, const struct nft_table *table,
43da04a5 6274 struct nft_object *obj, bool reset)
e5009240 6275{
e5009240
PNA
6276 struct nlmsghdr *nlh;
6277
dedb67c4 6278 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
19c28b13
PNA
6279 nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
6280 NFNETLINK_V0, nft_base_seq(net));
6281 if (!nlh)
e5009240
PNA
6282 goto nla_put_failure;
6283
e5009240 6284 if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
d152159b 6285 nla_put_string(skb, NFTA_OBJ_NAME, obj->key.name) ||
dfc46034 6286 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
e5009240 6287 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
3ecbfd65
HS
6288 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) ||
6289 nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle),
6290 NFTA_OBJ_PAD))
e5009240
PNA
6291 goto nla_put_failure;
6292
b131c964
JGG
6293 if (obj->udata &&
6294 nla_put(skb, NFTA_OBJ_USERDATA, obj->udlen, obj->udata))
6295 goto nla_put_failure;
6296
e5009240
PNA
6297 nlmsg_end(skb, nlh);
6298 return 0;
6299
6300nla_put_failure:
6301 nlmsg_trim(skb, nlh);
6302 return -1;
6303}
6304
a9fea2a3 6305struct nft_obj_filter {
e46abbcc 6306 char *table;
a9fea2a3
PNA
6307 u32 type;
6308};
6309
e5009240
PNA
6310static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
6311{
6312 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
e5009240 6313 const struct nft_table *table;
e5009240 6314 unsigned int idx = 0, s_idx = cb->args[0];
a9fea2a3 6315 struct nft_obj_filter *filter = cb->data;
e5009240
PNA
6316 struct net *net = sock_net(skb->sk);
6317 int family = nfmsg->nfgen_family;
0854db2a 6318 struct nftables_pernet *nft_net;
43da04a5
PNA
6319 struct nft_object *obj;
6320 bool reset = false;
6321
6322 if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
6323 reset = true;
e5009240
PNA
6324
6325 rcu_read_lock();
0854db2a
FW
6326 nft_net = net_generic(net, nf_tables_net_id);
6327 cb->seq = nft_net->base_seq;
e5009240 6328
0854db2a 6329 list_for_each_entry_rcu(table, &nft_net->tables, list) {
98319cb9 6330 if (family != NFPROTO_UNSPEC && family != table->family)
e5009240
PNA
6331 continue;
6332
36596dad
PNA
6333 list_for_each_entry_rcu(obj, &table->objects, list) {
6334 if (!nft_is_active(net, obj))
6335 goto cont;
6336 if (idx < s_idx)
6337 goto cont;
6338 if (idx > s_idx)
6339 memset(&cb->args[1], 0,
6340 sizeof(cb->args) - sizeof(cb->args[0]));
360cc79d 6341 if (filter && filter->table &&
36596dad
PNA
6342 strcmp(filter->table, table->name))
6343 goto cont;
6344 if (filter &&
6345 filter->type != NFT_OBJECT_UNSPEC &&
6346 obj->ops->type->type != filter->type)
6347 goto cont;
8e6cf365 6348 if (reset) {
68df2ed5 6349 char *buf = kasprintf(GFP_ATOMIC,
c520292f 6350 "%s:%u",
8e6cf365 6351 table->name,
0854db2a 6352 nft_net->base_seq);
8e6cf365
RGB
6353
6354 audit_log_nfcfg(buf,
6355 family,
6356 obj->handle,
14224039 6357 AUDIT_NFT_OP_OBJ_RESET,
68df2ed5 6358 GFP_ATOMIC);
8e6cf365
RGB
6359 kfree(buf);
6360 }
6361
36596dad
PNA
6362 if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
6363 cb->nlh->nlmsg_seq,
6364 NFT_MSG_NEWOBJ,
6365 NLM_F_MULTI | NLM_F_APPEND,
98319cb9 6366 table->family, table,
36596dad
PNA
6367 obj, reset) < 0)
6368 goto done;
e5009240 6369
36596dad 6370 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
e5009240 6371cont:
36596dad 6372 idx++;
e5009240
PNA
6373 }
6374 }
6375done:
6376 rcu_read_unlock();
6377
6378 cb->args[0] = idx;
6379 return skb->len;
6380}
6381
90fd131a 6382static int nf_tables_dump_obj_start(struct netlink_callback *cb)
a9fea2a3 6383{
90fd131a
FW
6384 const struct nlattr * const *nla = cb->data;
6385 struct nft_obj_filter *filter = NULL;
e46abbcc 6386
90fd131a
FW
6387 if (nla[NFTA_OBJ_TABLE] || nla[NFTA_OBJ_TYPE]) {
6388 filter = kzalloc(sizeof(*filter), GFP_ATOMIC);
6389 if (!filter)
6390 return -ENOMEM;
6391
6392 if (nla[NFTA_OBJ_TABLE]) {
6393 filter->table = nla_strdup(nla[NFTA_OBJ_TABLE], GFP_ATOMIC);
6394 if (!filter->table) {
6395 kfree(filter);
6396 return -ENOMEM;
6397 }
6398 }
6399
6400 if (nla[NFTA_OBJ_TYPE])
6401 filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
8bea728d 6402 }
a9fea2a3 6403
90fd131a 6404 cb->data = filter;
a9fea2a3
PNA
6405 return 0;
6406}
6407
90fd131a 6408static int nf_tables_dump_obj_done(struct netlink_callback *cb)
a9fea2a3 6409{
90fd131a 6410 struct nft_obj_filter *filter = cb->data;
a9fea2a3 6411
90fd131a
FW
6412 if (filter) {
6413 kfree(filter->table);
6414 kfree(filter);
e46abbcc 6415 }
a9fea2a3 6416
90fd131a 6417 return 0;
a9fea2a3
PNA
6418}
6419
d9adf22a 6420/* called with rcu_read_lock held */
e5009240
PNA
6421static int nf_tables_getobj(struct net *net, struct sock *nlsk,
6422 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
6423 const struct nlattr * const nla[],
6424 struct netlink_ext_ack *extack)
e5009240
PNA
6425{
6426 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
6427 u8 genmask = nft_genmask_cur(net);
6428 int family = nfmsg->nfgen_family;
e5009240
PNA
6429 const struct nft_table *table;
6430 struct nft_object *obj;
6431 struct sk_buff *skb2;
43da04a5 6432 bool reset = false;
e5009240
PNA
6433 u32 objtype;
6434 int err;
6435
6436 if (nlh->nlmsg_flags & NLM_F_DUMP) {
6437 struct netlink_dump_control c = {
90fd131a 6438 .start = nf_tables_dump_obj_start,
e5009240 6439 .dump = nf_tables_dump_obj,
a9fea2a3 6440 .done = nf_tables_dump_obj_done,
d9adf22a 6441 .module = THIS_MODULE,
90fd131a 6442 .data = (void *)nla,
e5009240 6443 };
a9fea2a3 6444
d9adf22a 6445 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
e5009240
PNA
6446 }
6447
6448 if (!nla[NFTA_OBJ_NAME] ||
6449 !nla[NFTA_OBJ_TYPE])
6450 return -EINVAL;
6451
6001a930 6452 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask, 0);
36dd1bcc
PNA
6453 if (IS_ERR(table)) {
6454 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 6455 return PTR_ERR(table);
36dd1bcc 6456 }
e5009240
PNA
6457
6458 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4d44175a 6459 obj = nft_obj_lookup(net, table, nla[NFTA_OBJ_NAME], objtype, genmask);
36dd1bcc
PNA
6460 if (IS_ERR(obj)) {
6461 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 6462 return PTR_ERR(obj);
36dd1bcc 6463 }
e5009240 6464
d9adf22a 6465 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
e5009240
PNA
6466 if (!skb2)
6467 return -ENOMEM;
6468
43da04a5
PNA
6469 if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
6470 reset = true;
6471
8e6cf365 6472 if (reset) {
0854db2a
FW
6473 const struct nftables_pernet *nft_net;
6474 char *buf;
6475
6476 nft_net = net_generic(net, nf_tables_net_id);
6477 buf = kasprintf(GFP_ATOMIC, "%s:%u", table->name, nft_net->base_seq);
8e6cf365
RGB
6478
6479 audit_log_nfcfg(buf,
6480 family,
6481 obj->handle,
14224039 6482 AUDIT_NFT_OP_OBJ_RESET,
68df2ed5 6483 GFP_ATOMIC);
8e6cf365
RGB
6484 kfree(buf);
6485 }
6486
e5009240
PNA
6487 err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
6488 nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
43da04a5 6489 family, table, obj, reset);
e5009240 6490 if (err < 0)
ee921183 6491 goto err_fill_obj_info;
e5009240 6492
ee921183
PNA
6493 return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
6494
6495err_fill_obj_info:
e5009240
PNA
6496 kfree_skb(skb2);
6497 return err;
e5009240
PNA
6498}
6499
00bfb320 6500static void nft_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
e5009240 6501{
dfc46034 6502 if (obj->ops->destroy)
00bfb320 6503 obj->ops->destroy(ctx, obj);
e5009240 6504
dfc46034 6505 module_put(obj->ops->type->owner);
d152159b 6506 kfree(obj->key.name);
bc7a7082 6507 kfree(obj->udata);
e5009240
PNA
6508 kfree(obj);
6509}
6510
6511static int nf_tables_delobj(struct net *net, struct sock *nlsk,
04ba724b
PNA
6512 struct sk_buff *skb, const struct nlmsghdr *nlh,
6513 const struct nlattr * const nla[],
6514 struct netlink_ext_ack *extack)
e5009240
PNA
6515{
6516 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
6517 u8 genmask = nft_genmask_next(net);
6518 int family = nfmsg->nfgen_family;
36dd1bcc 6519 const struct nlattr *attr;
e5009240
PNA
6520 struct nft_table *table;
6521 struct nft_object *obj;
6522 struct nft_ctx ctx;
6523 u32 objtype;
6524
6525 if (!nla[NFTA_OBJ_TYPE] ||
3ecbfd65 6526 (!nla[NFTA_OBJ_NAME] && !nla[NFTA_OBJ_HANDLE]))
e5009240
PNA
6527 return -EINVAL;
6528
6001a930
PNA
6529 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask,
6530 NETLINK_CB(skb).portid);
36dd1bcc
PNA
6531 if (IS_ERR(table)) {
6532 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 6533 return PTR_ERR(table);
36dd1bcc 6534 }
e5009240
PNA
6535
6536 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
36dd1bcc
PNA
6537 if (nla[NFTA_OBJ_HANDLE]) {
6538 attr = nla[NFTA_OBJ_HANDLE];
6539 obj = nft_obj_lookup_byhandle(table, attr, objtype, genmask);
6540 } else {
6541 attr = nla[NFTA_OBJ_NAME];
4d44175a 6542 obj = nft_obj_lookup(net, table, attr, objtype, genmask);
36dd1bcc
PNA
6543 }
6544
6545 if (IS_ERR(obj)) {
6546 NL_SET_BAD_ATTR(extack, attr);
e5009240 6547 return PTR_ERR(obj);
36dd1bcc
PNA
6548 }
6549 if (obj->use > 0) {
6550 NL_SET_BAD_ATTR(extack, attr);
e5009240 6551 return -EBUSY;
36dd1bcc 6552 }
e5009240 6553
98319cb9 6554 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e5009240
PNA
6555
6556 return nft_delobj(&ctx, obj);
6557}
6558
d152159b 6559void nft_obj_notify(struct net *net, const struct nft_table *table,
25e94a99
PNA
6560 struct nft_object *obj, u32 portid, u32 seq, int event,
6561 int family, int report, gfp_t gfp)
e5009240 6562{
0854db2a 6563 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
e5009240
PNA
6564 struct sk_buff *skb;
6565 int err;
c520292f 6566 char *buf = kasprintf(gfp, "%s:%u",
0854db2a 6567 table->name, nft_net->base_seq);
8e6cf365
RGB
6568
6569 audit_log_nfcfg(buf,
6570 family,
6571 obj->handle,
6572 event == NFT_MSG_NEWOBJ ?
c520292f
RGB
6573 AUDIT_NFT_OP_OBJ_REGISTER :
6574 AUDIT_NFT_OP_OBJ_UNREGISTER,
68df2ed5 6575 gfp);
8e6cf365 6576 kfree(buf);
e5009240 6577
2599e989
PNA
6578 if (!report &&
6579 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 6580 return;
e5009240 6581
2599e989 6582 skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
e5009240
PNA
6583 if (skb == NULL)
6584 goto err;
6585
2599e989
PNA
6586 err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
6587 table, obj, false);
e5009240
PNA
6588 if (err < 0) {
6589 kfree_skb(skb);
6590 goto err;
6591 }
6592
0854db2a 6593 nft_notify_enqueue(skb, report, &nft_net->notify_list);
25e94a99 6594 return;
e5009240 6595err:
25e94a99 6596 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
e5009240 6597}
2599e989
PNA
6598EXPORT_SYMBOL_GPL(nft_obj_notify);
6599
25e94a99
PNA
6600static void nf_tables_obj_notify(const struct nft_ctx *ctx,
6601 struct nft_object *obj, int event)
2599e989 6602{
25e94a99 6603 nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
36596dad 6604 ctx->family, ctx->report, GFP_KERNEL);
2599e989 6605}
e5009240 6606
3b49e2e9
PNA
6607/*
6608 * Flow tables
6609 */
6610void nft_register_flowtable_type(struct nf_flowtable_type *type)
6611{
6612 nfnl_lock(NFNL_SUBSYS_NFTABLES);
6613 list_add_tail_rcu(&type->list, &nf_tables_flowtables);
6614 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
6615}
6616EXPORT_SYMBOL_GPL(nft_register_flowtable_type);
6617
6618void nft_unregister_flowtable_type(struct nf_flowtable_type *type)
6619{
6620 nfnl_lock(NFNL_SUBSYS_NFTABLES);
6621 list_del_rcu(&type->list);
6622 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
6623}
6624EXPORT_SYMBOL_GPL(nft_unregister_flowtable_type);
6625
6626static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = {
6627 [NFTA_FLOWTABLE_TABLE] = { .type = NLA_STRING,
6628 .len = NFT_NAME_MAXLEN - 1 },
6629 [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING,
6630 .len = NFT_NAME_MAXLEN - 1 },
6631 [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED },
3ecbfd65 6632 [NFTA_FLOWTABLE_HANDLE] = { .type = NLA_U64 },
8bb69f3b 6633 [NFTA_FLOWTABLE_FLAGS] = { .type = NLA_U32 },
3b49e2e9
PNA
6634};
6635
cac20fcd
PNA
6636struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table,
6637 const struct nlattr *nla, u8 genmask)
3b49e2e9
PNA
6638{
6639 struct nft_flowtable *flowtable;
6640
d9adf22a 6641 list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
3b49e2e9
PNA
6642 if (!nla_strcmp(nla, flowtable->name) &&
6643 nft_active_genmask(flowtable, genmask))
6644 return flowtable;
6645 }
6646 return ERR_PTR(-ENOENT);
6647}
cac20fcd 6648EXPORT_SYMBOL_GPL(nft_flowtable_lookup);
3b49e2e9 6649
9b05b6e1
LGL
6650void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx,
6651 struct nft_flowtable *flowtable,
6652 enum nft_trans_phase phase)
6653{
6654 switch (phase) {
6655 case NFT_TRANS_PREPARE:
6656 case NFT_TRANS_ABORT:
6657 case NFT_TRANS_RELEASE:
6658 flowtable->use--;
954d8297 6659 fallthrough;
9b05b6e1
LGL
6660 default:
6661 return;
6662 }
6663}
6664EXPORT_SYMBOL_GPL(nf_tables_deactivate_flowtable);
6665
ae0662f8 6666static struct nft_flowtable *
cac20fcd
PNA
6667nft_flowtable_lookup_byhandle(const struct nft_table *table,
6668 const struct nlattr *nla, u8 genmask)
3ecbfd65
HS
6669{
6670 struct nft_flowtable *flowtable;
6671
6672 list_for_each_entry(flowtable, &table->flowtables, list) {
6673 if (be64_to_cpu(nla_get_be64(nla)) == flowtable->handle &&
6674 nft_active_genmask(flowtable, genmask))
6675 return flowtable;
6676 }
6677 return ERR_PTR(-ENOENT);
6678}
6679
d9246a53
PNA
6680struct nft_flowtable_hook {
6681 u32 num;
6682 int priority;
6683 struct list_head list;
6684};
6685
3b49e2e9
PNA
6686static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX + 1] = {
6687 [NFTA_FLOWTABLE_HOOK_NUM] = { .type = NLA_U32 },
6688 [NFTA_FLOWTABLE_HOOK_PRIORITY] = { .type = NLA_U32 },
6689 [NFTA_FLOWTABLE_HOOK_DEVS] = { .type = NLA_NESTED },
6690};
6691
d9246a53
PNA
6692static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
6693 const struct nlattr *attr,
6694 struct nft_flowtable_hook *flowtable_hook,
5b6743fb 6695 struct nft_flowtable *flowtable, bool add)
3b49e2e9 6696{
3b49e2e9 6697 struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1];
3f0465a9 6698 struct nft_hook *hook;
3b49e2e9 6699 int hooknum, priority;
3f0465a9 6700 int err;
3b49e2e9 6701
d9246a53
PNA
6702 INIT_LIST_HEAD(&flowtable_hook->list);
6703
8cb08174
JB
6704 err = nla_parse_nested_deprecated(tb, NFTA_FLOWTABLE_HOOK_MAX, attr,
6705 nft_flowtable_hook_policy, NULL);
3b49e2e9
PNA
6706 if (err < 0)
6707 return err;
6708
5b6743fb
PNA
6709 if (add) {
6710 if (!tb[NFTA_FLOWTABLE_HOOK_NUM] ||
6711 !tb[NFTA_FLOWTABLE_HOOK_PRIORITY])
6712 return -EINVAL;
3b49e2e9 6713
5b6743fb
PNA
6714 hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
6715 if (hooknum != NF_NETDEV_INGRESS)
6716 return -EOPNOTSUPP;
6717
6718 priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));
6719
6720 flowtable_hook->priority = priority;
6721 flowtable_hook->num = hooknum;
6722 } else {
6723 if (tb[NFTA_FLOWTABLE_HOOK_NUM]) {
6724 hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
6725 if (hooknum != flowtable->hooknum)
6726 return -EOPNOTSUPP;
6727 }
6728
6729 if (tb[NFTA_FLOWTABLE_HOOK_PRIORITY]) {
6730 priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));
6731 if (priority != flowtable->data.priority)
6732 return -EOPNOTSUPP;
6733 }
3b49e2e9 6734
5b6743fb
PNA
6735 flowtable_hook->priority = flowtable->data.priority;
6736 flowtable_hook->num = flowtable->hooknum;
6737 }
3b49e2e9 6738
05abe445
PNA
6739 if (tb[NFTA_FLOWTABLE_HOOK_DEVS]) {
6740 err = nf_tables_parse_netdev_hooks(ctx->net,
6741 tb[NFTA_FLOWTABLE_HOOK_DEVS],
6742 &flowtable_hook->list);
6743 if (err < 0)
6744 return err;
6745 }
3b49e2e9 6746
d9246a53 6747 list_for_each_entry(hook, &flowtable_hook->list, list) {
3f0465a9 6748 hook->ops.pf = NFPROTO_NETDEV;
5b6743fb
PNA
6749 hook->ops.hooknum = flowtable_hook->num;
6750 hook->ops.priority = flowtable_hook->priority;
6751 hook->ops.priv = &flowtable->data;
6752 hook->ops.hook = flowtable->data.type->hook;
3b49e2e9
PNA
6753 }
6754
3b49e2e9
PNA
6755 return err;
6756}
6757
98319cb9 6758static const struct nf_flowtable_type *__nft_flowtable_type_get(u8 family)
3b49e2e9
PNA
6759{
6760 const struct nf_flowtable_type *type;
6761
6762 list_for_each_entry(type, &nf_tables_flowtables, list) {
98319cb9 6763 if (family == type->family)
3b49e2e9
PNA
6764 return type;
6765 }
6766 return NULL;
6767}
6768
452238e8
FW
6769static const struct nf_flowtable_type *
6770nft_flowtable_type_get(struct net *net, u8 family)
3b49e2e9
PNA
6771{
6772 const struct nf_flowtable_type *type;
6773
98319cb9 6774 type = __nft_flowtable_type_get(family);
3b49e2e9
PNA
6775 if (type != NULL && try_module_get(type->owner))
6776 return type;
6777
f102d66b 6778 lockdep_nfnl_nft_mutex_not_held();
3b49e2e9
PNA
6779#ifdef CONFIG_MODULES
6780 if (type == NULL) {
eb014de4 6781 if (nft_request_module(net, "nf-flowtable-%u", family) == -EAGAIN)
3b49e2e9
PNA
6782 return ERR_PTR(-EAGAIN);
6783 }
6784#endif
6785 return ERR_PTR(-ENOENT);
6786}
6787
5acab914 6788/* Only called from error and netdev event paths. */
ff4bf2f4
PNA
6789static void nft_unregister_flowtable_hook(struct net *net,
6790 struct nft_flowtable *flowtable,
6791 struct nft_hook *hook)
6792{
6793 nf_unregister_net_hook(net, &hook->ops);
6794 flowtable->data.type->setup(&flowtable->data, hook->ops.dev,
6795 FLOW_BLOCK_UNBIND);
6796}
6797
3b49e2e9 6798static void nft_unregister_flowtable_net_hooks(struct net *net,
f9382669 6799 struct list_head *hook_list)
3b49e2e9 6800{
3f0465a9 6801 struct nft_hook *hook;
3b49e2e9 6802
f9382669 6803 list_for_each_entry(hook, hook_list, list)
5acab914 6804 nf_unregister_net_hook(net, &hook->ops);
3f0465a9
PNA
6805}
6806
6807static int nft_register_flowtable_net_hooks(struct net *net,
6808 struct nft_table *table,
f9382669 6809 struct list_head *hook_list,
3f0465a9
PNA
6810 struct nft_flowtable *flowtable)
6811{
6812 struct nft_hook *hook, *hook2, *next;
6813 struct nft_flowtable *ft;
6814 int err, i = 0;
6815
f9382669 6816 list_for_each_entry(hook, hook_list, list) {
3f0465a9 6817 list_for_each_entry(ft, &table->flowtables, list) {
86fe2c19
PNA
6818 if (!nft_is_active_next(net, ft))
6819 continue;
6820
3f0465a9
PNA
6821 list_for_each_entry(hook2, &ft->hook_list, list) {
6822 if (hook->ops.dev == hook2->ops.dev &&
6823 hook->ops.pf == hook2->ops.pf) {
77a92189 6824 err = -EEXIST;
3f0465a9
PNA
6825 goto err_unregister_net_hooks;
6826 }
6827 }
6828 }
3b49e2e9 6829
d7c03a9f 6830 err = flowtable->data.type->setup(&flowtable->data,
6831 hook->ops.dev,
6832 FLOW_BLOCK_BIND);
3f0465a9
PNA
6833 if (err < 0)
6834 goto err_unregister_net_hooks;
6835
d7c03a9f 6836 err = nf_register_net_hook(net, &hook->ops);
6837 if (err < 0) {
6838 flowtable->data.type->setup(&flowtable->data,
6839 hook->ops.dev,
6840 FLOW_BLOCK_UNBIND);
6841 goto err_unregister_net_hooks;
6842 }
6843
3f0465a9 6844 i++;
3b49e2e9 6845 }
3f0465a9
PNA
6846
6847 return 0;
6848
6849err_unregister_net_hooks:
f9382669 6850 list_for_each_entry_safe(hook, next, hook_list, list) {
3f0465a9
PNA
6851 if (i-- <= 0)
6852 break;
6853
ff4bf2f4 6854 nft_unregister_flowtable_hook(net, flowtable, hook);
3f0465a9
PNA
6855 list_del_rcu(&hook->list);
6856 kfree_rcu(hook, rcu);
6857 }
6858
6859 return err;
3b49e2e9
PNA
6860}
6861
389a2cbc
PNA
6862static void nft_flowtable_hooks_destroy(struct list_head *hook_list)
6863{
6864 struct nft_hook *hook, *next;
6865
6866 list_for_each_entry_safe(hook, next, hook_list, list) {
6867 list_del_rcu(&hook->list);
6868 kfree_rcu(hook, rcu);
6869 }
6870}
6871
78d9f48f
PNA
6872static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
6873 struct nft_flowtable *flowtable)
6874{
6875 const struct nlattr * const *nla = ctx->nla;
6876 struct nft_flowtable_hook flowtable_hook;
6877 struct nft_hook *hook, *next;
6878 struct nft_trans *trans;
6879 bool unregister = false;
7b35582c 6880 u32 flags;
78d9f48f
PNA
6881 int err;
6882
6883 err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK],
5b6743fb 6884 &flowtable_hook, flowtable, false);
78d9f48f
PNA
6885 if (err < 0)
6886 return err;
6887
6888 list_for_each_entry_safe(hook, next, &flowtable_hook.list, list) {
6889 if (nft_hook_list_find(&flowtable->hook_list, hook)) {
6890 list_del(&hook->list);
6891 kfree(hook);
6892 }
6893 }
6894
7b35582c
PNA
6895 if (nla[NFTA_FLOWTABLE_FLAGS]) {
6896 flags = ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS]));
6897 if (flags & ~NFT_FLOWTABLE_MASK)
6898 return -EOPNOTSUPP;
6899 if ((flowtable->data.flags & NFT_FLOWTABLE_HW_OFFLOAD) ^
6900 (flags & NFT_FLOWTABLE_HW_OFFLOAD))
6901 return -EOPNOTSUPP;
6902 } else {
6903 flags = flowtable->data.flags;
6904 }
6905
78d9f48f
PNA
6906 err = nft_register_flowtable_net_hooks(ctx->net, ctx->table,
6907 &flowtable_hook.list, flowtable);
6908 if (err < 0)
6909 goto err_flowtable_update_hook;
6910
6911 trans = nft_trans_alloc(ctx, NFT_MSG_NEWFLOWTABLE,
6912 sizeof(struct nft_trans_flowtable));
6913 if (!trans) {
6914 unregister = true;
6915 err = -ENOMEM;
6916 goto err_flowtable_update_hook;
6917 }
6918
7b35582c 6919 nft_trans_flowtable_flags(trans) = flags;
78d9f48f
PNA
6920 nft_trans_flowtable(trans) = flowtable;
6921 nft_trans_flowtable_update(trans) = true;
6922 INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
6923 list_splice(&flowtable_hook.list, &nft_trans_flowtable_hooks(trans));
6924
0854db2a 6925 nft_trans_commit_list_add_tail(ctx->net, trans);
78d9f48f
PNA
6926
6927 return 0;
6928
6929err_flowtable_update_hook:
6930 list_for_each_entry_safe(hook, next, &flowtable_hook.list, list) {
6931 if (unregister)
6932 nft_unregister_flowtable_hook(ctx->net, flowtable, hook);
6933 list_del_rcu(&hook->list);
6934 kfree_rcu(hook, rcu);
6935 }
6936
6937 return err;
6938
6939}
6940
3b49e2e9
PNA
6941static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
6942 struct sk_buff *skb,
6943 const struct nlmsghdr *nlh,
6944 const struct nlattr * const nla[],
6945 struct netlink_ext_ack *extack)
6946{
6947 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
d9246a53 6948 struct nft_flowtable_hook flowtable_hook;
3b49e2e9
PNA
6949 const struct nf_flowtable_type *type;
6950 u8 genmask = nft_genmask_next(net);
6951 int family = nfmsg->nfgen_family;
3f0465a9
PNA
6952 struct nft_flowtable *flowtable;
6953 struct nft_hook *hook, *next;
3b49e2e9
PNA
6954 struct nft_table *table;
6955 struct nft_ctx ctx;
3f0465a9 6956 int err;
3b49e2e9
PNA
6957
6958 if (!nla[NFTA_FLOWTABLE_TABLE] ||
6959 !nla[NFTA_FLOWTABLE_NAME] ||
6960 !nla[NFTA_FLOWTABLE_HOOK])
6961 return -EINVAL;
6962
cac20fcd 6963 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
6001a930 6964 genmask, NETLINK_CB(skb).portid);
36dd1bcc
PNA
6965 if (IS_ERR(table)) {
6966 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_TABLE]);
3b49e2e9 6967 return PTR_ERR(table);
36dd1bcc 6968 }
3b49e2e9 6969
cac20fcd
PNA
6970 flowtable = nft_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME],
6971 genmask);
3b49e2e9
PNA
6972 if (IS_ERR(flowtable)) {
6973 err = PTR_ERR(flowtable);
36dd1bcc
PNA
6974 if (err != -ENOENT) {
6975 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_NAME]);
3b49e2e9 6976 return err;
36dd1bcc 6977 }
3b49e2e9 6978 } else {
36dd1bcc
PNA
6979 if (nlh->nlmsg_flags & NLM_F_EXCL) {
6980 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_NAME]);
3b49e2e9 6981 return -EEXIST;
36dd1bcc 6982 }
3b49e2e9 6983
78d9f48f
PNA
6984 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
6985
6986 return nft_flowtable_update(&ctx, nlh, flowtable);
3b49e2e9
PNA
6987 }
6988
98319cb9 6989 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
3b49e2e9
PNA
6990
6991 flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
6992 if (!flowtable)
6993 return -ENOMEM;
6994
6995 flowtable->table = table;
3ecbfd65 6996 flowtable->handle = nf_tables_alloc_handle(table);
3f0465a9 6997 INIT_LIST_HEAD(&flowtable->hook_list);
3ecbfd65 6998
3b49e2e9
PNA
6999 flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL);
7000 if (!flowtable->name) {
7001 err = -ENOMEM;
7002 goto err1;
7003 }
7004
452238e8 7005 type = nft_flowtable_type_get(net, family);
3b49e2e9
PNA
7006 if (IS_ERR(type)) {
7007 err = PTR_ERR(type);
7008 goto err2;
7009 }
7010
8bb69f3b
PNA
7011 if (nla[NFTA_FLOWTABLE_FLAGS]) {
7012 flowtable->data.flags =
7013 ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS]));
7e6136f1
PNA
7014 if (flowtable->data.flags & ~NFT_FLOWTABLE_MASK) {
7015 err = -EOPNOTSUPP;
8bb69f3b 7016 goto err3;
7e6136f1 7017 }
8bb69f3b
PNA
7018 }
7019
7020 write_pnet(&flowtable->data.net, net);
3b49e2e9 7021 flowtable->data.type = type;
a268de77 7022 err = type->init(&flowtable->data);
3b49e2e9
PNA
7023 if (err < 0)
7024 goto err3;
7025
d9246a53 7026 err = nft_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK],
5b6743fb 7027 &flowtable_hook, flowtable, true);
3b49e2e9 7028 if (err < 0)
a268de77 7029 goto err4;
3b49e2e9 7030
d9246a53
PNA
7031 list_splice(&flowtable_hook.list, &flowtable->hook_list);
7032 flowtable->data.priority = flowtable_hook.priority;
7033 flowtable->hooknum = flowtable_hook.num;
7034
f9382669
PNA
7035 err = nft_register_flowtable_net_hooks(ctx.net, table,
7036 &flowtable->hook_list,
7037 flowtable);
2d285f26 7038 if (err < 0) {
389a2cbc 7039 nft_flowtable_hooks_destroy(&flowtable->hook_list);
3f0465a9 7040 goto err4;
2d285f26 7041 }
3b49e2e9
PNA
7042
7043 err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable);
7044 if (err < 0)
3f0465a9 7045 goto err5;
3b49e2e9
PNA
7046
7047 list_add_tail_rcu(&flowtable->list, &table->flowtables);
7048 table->use++;
7049
7050 return 0;
a268de77 7051err5:
3f0465a9 7052 list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) {
ff4bf2f4 7053 nft_unregister_flowtable_hook(net, flowtable, hook);
3f0465a9
PNA
7054 list_del_rcu(&hook->list);
7055 kfree_rcu(hook, rcu);
7056 }
a268de77
FF
7057err4:
7058 flowtable->data.type->free(&flowtable->data);
3b49e2e9
PNA
7059err3:
7060 module_put(type->owner);
7061err2:
7062 kfree(flowtable->name);
7063err1:
7064 kfree(flowtable);
7065 return err;
7066}
7067
3003055f
PNA
7068static void nft_flowtable_hook_release(struct nft_flowtable_hook *flowtable_hook)
7069{
7070 struct nft_hook *this, *next;
7071
7072 list_for_each_entry_safe(this, next, &flowtable_hook->list, list) {
7073 list_del(&this->list);
7074 kfree(this);
7075 }
7076}
7077
abadb2f8
PNA
7078static int nft_delflowtable_hook(struct nft_ctx *ctx,
7079 struct nft_flowtable *flowtable)
7080{
7081 const struct nlattr * const *nla = ctx->nla;
7082 struct nft_flowtable_hook flowtable_hook;
3003055f 7083 struct nft_hook *this, *hook;
abadb2f8
PNA
7084 struct nft_trans *trans;
7085 int err;
7086
7087 err = nft_flowtable_parse_hook(ctx, nla[NFTA_FLOWTABLE_HOOK],
5b6743fb 7088 &flowtable_hook, flowtable, false);
abadb2f8
PNA
7089 if (err < 0)
7090 return err;
7091
3003055f 7092 list_for_each_entry(this, &flowtable_hook.list, list) {
abadb2f8
PNA
7093 hook = nft_hook_list_find(&flowtable->hook_list, this);
7094 if (!hook) {
7095 err = -ENOENT;
7096 goto err_flowtable_del_hook;
7097 }
7098 hook->inactive = true;
abadb2f8
PNA
7099 }
7100
7101 trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE,
7102 sizeof(struct nft_trans_flowtable));
3003055f
PNA
7103 if (!trans) {
7104 err = -ENOMEM;
7105 goto err_flowtable_del_hook;
7106 }
abadb2f8
PNA
7107
7108 nft_trans_flowtable(trans) = flowtable;
7109 nft_trans_flowtable_update(trans) = true;
7110 INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
3003055f 7111 nft_flowtable_hook_release(&flowtable_hook);
abadb2f8 7112
0854db2a 7113 nft_trans_commit_list_add_tail(ctx->net, trans);
abadb2f8
PNA
7114
7115 return 0;
7116
7117err_flowtable_del_hook:
3003055f
PNA
7118 list_for_each_entry(this, &flowtable_hook.list, list) {
7119 hook = nft_hook_list_find(&flowtable->hook_list, this);
7120 if (!hook)
7121 break;
7122
abadb2f8 7123 hook->inactive = false;
3003055f
PNA
7124 }
7125 nft_flowtable_hook_release(&flowtable_hook);
abadb2f8
PNA
7126
7127 return err;
7128}
7129
3b49e2e9
PNA
7130static int nf_tables_delflowtable(struct net *net, struct sock *nlsk,
7131 struct sk_buff *skb,
7132 const struct nlmsghdr *nlh,
7133 const struct nlattr * const nla[],
7134 struct netlink_ext_ack *extack)
7135{
7136 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7137 u8 genmask = nft_genmask_next(net);
7138 int family = nfmsg->nfgen_family;
7139 struct nft_flowtable *flowtable;
36dd1bcc 7140 const struct nlattr *attr;
3b49e2e9
PNA
7141 struct nft_table *table;
7142 struct nft_ctx ctx;
7143
e603ea4b
PNA
7144 if (!nla[NFTA_FLOWTABLE_TABLE] ||
7145 (!nla[NFTA_FLOWTABLE_NAME] &&
7146 !nla[NFTA_FLOWTABLE_HANDLE]))
7147 return -EINVAL;
7148
cac20fcd 7149 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
6001a930 7150 genmask, NETLINK_CB(skb).portid);
36dd1bcc
PNA
7151 if (IS_ERR(table)) {
7152 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_TABLE]);
3b49e2e9 7153 return PTR_ERR(table);
36dd1bcc 7154 }
3b49e2e9 7155
36dd1bcc
PNA
7156 if (nla[NFTA_FLOWTABLE_HANDLE]) {
7157 attr = nla[NFTA_FLOWTABLE_HANDLE];
7158 flowtable = nft_flowtable_lookup_byhandle(table, attr, genmask);
7159 } else {
7160 attr = nla[NFTA_FLOWTABLE_NAME];
7161 flowtable = nft_flowtable_lookup(table, attr, genmask);
7162 }
7163
7164 if (IS_ERR(flowtable)) {
7165 NL_SET_BAD_ATTR(extack, attr);
7166 return PTR_ERR(flowtable);
7167 }
abadb2f8
PNA
7168
7169 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
7170
7171 if (nla[NFTA_FLOWTABLE_HOOK])
7172 return nft_delflowtable_hook(&ctx, flowtable);
7173
36dd1bcc
PNA
7174 if (flowtable->use > 0) {
7175 NL_SET_BAD_ATTR(extack, attr);
3b49e2e9 7176 return -EBUSY;
36dd1bcc 7177 }
3b49e2e9 7178
3b49e2e9
PNA
7179 return nft_delflowtable(&ctx, flowtable);
7180}
7181
7182static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
7183 u32 portid, u32 seq, int event,
7184 u32 flags, int family,
c42d8bda
PNA
7185 struct nft_flowtable *flowtable,
7186 struct list_head *hook_list)
3b49e2e9
PNA
7187{
7188 struct nlattr *nest, *nest_devs;
3f0465a9 7189 struct nft_hook *hook;
3b49e2e9 7190 struct nlmsghdr *nlh;
3b49e2e9
PNA
7191
7192 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
19c28b13
PNA
7193 nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
7194 NFNETLINK_V0, nft_base_seq(net));
7195 if (!nlh)
3b49e2e9
PNA
7196 goto nla_put_failure;
7197
3b49e2e9
PNA
7198 if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) ||
7199 nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
3ecbfd65
HS
7200 nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
7201 nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
8bb69f3b
PNA
7202 NFTA_FLOWTABLE_PAD) ||
7203 nla_put_be32(skb, NFTA_FLOWTABLE_FLAGS, htonl(flowtable->data.flags)))
3b49e2e9
PNA
7204 goto nla_put_failure;
7205
ae0be8de 7206 nest = nla_nest_start_noflag(skb, NFTA_FLOWTABLE_HOOK);
eb895086
KL
7207 if (!nest)
7208 goto nla_put_failure;
3b49e2e9 7209 if (nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_NUM, htonl(flowtable->hooknum)) ||
71a8a63b 7210 nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_PRIORITY, htonl(flowtable->data.priority)))
3b49e2e9
PNA
7211 goto nla_put_failure;
7212
ae0be8de 7213 nest_devs = nla_nest_start_noflag(skb, NFTA_FLOWTABLE_HOOK_DEVS);
3b49e2e9
PNA
7214 if (!nest_devs)
7215 goto nla_put_failure;
7216
c42d8bda 7217 list_for_each_entry_rcu(hook, hook_list, list) {
3f0465a9 7218 if (nla_put_string(skb, NFTA_DEVICE_NAME, hook->ops.dev->name))
3b49e2e9
PNA
7219 goto nla_put_failure;
7220 }
7221 nla_nest_end(skb, nest_devs);
7222 nla_nest_end(skb, nest);
7223
7224 nlmsg_end(skb, nlh);
7225 return 0;
7226
7227nla_put_failure:
7228 nlmsg_trim(skb, nlh);
7229 return -1;
7230}
7231
7232struct nft_flowtable_filter {
7233 char *table;
7234};
7235
7236static int nf_tables_dump_flowtable(struct sk_buff *skb,
7237 struct netlink_callback *cb)
7238{
7239 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
7240 struct nft_flowtable_filter *filter = cb->data;
7241 unsigned int idx = 0, s_idx = cb->args[0];
7242 struct net *net = sock_net(skb->sk);
7243 int family = nfmsg->nfgen_family;
7244 struct nft_flowtable *flowtable;
0854db2a 7245 struct nftables_pernet *nft_net;
3b49e2e9
PNA
7246 const struct nft_table *table;
7247
7248 rcu_read_lock();
0854db2a
FW
7249 nft_net = net_generic(net, nf_tables_net_id);
7250 cb->seq = nft_net->base_seq;
3b49e2e9 7251
0854db2a 7252 list_for_each_entry_rcu(table, &nft_net->tables, list) {
98319cb9 7253 if (family != NFPROTO_UNSPEC && family != table->family)
3b49e2e9
PNA
7254 continue;
7255
36596dad
PNA
7256 list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
7257 if (!nft_is_active(net, flowtable))
7258 goto cont;
7259 if (idx < s_idx)
7260 goto cont;
7261 if (idx > s_idx)
7262 memset(&cb->args[1], 0,
7263 sizeof(cb->args) - sizeof(cb->args[0]));
360cc79d 7264 if (filter && filter->table &&
36596dad
PNA
7265 strcmp(filter->table, table->name))
7266 goto cont;
3b49e2e9 7267
36596dad
PNA
7268 if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid,
7269 cb->nlh->nlmsg_seq,
7270 NFT_MSG_NEWFLOWTABLE,
7271 NLM_F_MULTI | NLM_F_APPEND,
c42d8bda
PNA
7272 table->family,
7273 flowtable,
7274 &flowtable->hook_list) < 0)
36596dad 7275 goto done;
3b49e2e9 7276
36596dad 7277 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
3b49e2e9 7278cont:
36596dad 7279 idx++;
3b49e2e9
PNA
7280 }
7281 }
7282done:
7283 rcu_read_unlock();
7284
7285 cb->args[0] = idx;
7286 return skb->len;
7287}
7288
90fd131a 7289static int nf_tables_dump_flowtable_start(struct netlink_callback *cb)
3b49e2e9 7290{
90fd131a
FW
7291 const struct nlattr * const *nla = cb->data;
7292 struct nft_flowtable_filter *filter = NULL;
3b49e2e9 7293
90fd131a
FW
7294 if (nla[NFTA_FLOWTABLE_TABLE]) {
7295 filter = kzalloc(sizeof(*filter), GFP_ATOMIC);
7296 if (!filter)
7297 return -ENOMEM;
3b49e2e9 7298
90fd131a
FW
7299 filter->table = nla_strdup(nla[NFTA_FLOWTABLE_TABLE],
7300 GFP_ATOMIC);
7301 if (!filter->table) {
7302 kfree(filter);
7303 return -ENOMEM;
7304 }
7305 }
3b49e2e9 7306
90fd131a 7307 cb->data = filter;
3b49e2e9
PNA
7308 return 0;
7309}
7310
90fd131a 7311static int nf_tables_dump_flowtable_done(struct netlink_callback *cb)
3b49e2e9 7312{
90fd131a 7313 struct nft_flowtable_filter *filter = cb->data;
3b49e2e9 7314
3b49e2e9 7315 if (!filter)
90fd131a 7316 return 0;
3b49e2e9 7317
90fd131a
FW
7318 kfree(filter->table);
7319 kfree(filter);
7320
7321 return 0;
3b49e2e9
PNA
7322}
7323
d9adf22a 7324/* called with rcu_read_lock held */
3b49e2e9
PNA
7325static int nf_tables_getflowtable(struct net *net, struct sock *nlsk,
7326 struct sk_buff *skb,
7327 const struct nlmsghdr *nlh,
7328 const struct nlattr * const nla[],
7329 struct netlink_ext_ack *extack)
7330{
7331 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7332 u8 genmask = nft_genmask_cur(net);
7333 int family = nfmsg->nfgen_family;
7334 struct nft_flowtable *flowtable;
3b49e2e9
PNA
7335 const struct nft_table *table;
7336 struct sk_buff *skb2;
7337 int err;
7338
7339 if (nlh->nlmsg_flags & NLM_F_DUMP) {
7340 struct netlink_dump_control c = {
90fd131a 7341 .start = nf_tables_dump_flowtable_start,
3b49e2e9
PNA
7342 .dump = nf_tables_dump_flowtable,
7343 .done = nf_tables_dump_flowtable_done,
d9adf22a 7344 .module = THIS_MODULE,
90fd131a 7345 .data = (void *)nla,
3b49e2e9
PNA
7346 };
7347
d9adf22a 7348 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
3b49e2e9
PNA
7349 }
7350
7351 if (!nla[NFTA_FLOWTABLE_NAME])
7352 return -EINVAL;
7353
cac20fcd 7354 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
6001a930 7355 genmask, 0);
3b49e2e9
PNA
7356 if (IS_ERR(table))
7357 return PTR_ERR(table);
7358
cac20fcd
PNA
7359 flowtable = nft_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME],
7360 genmask);
03a0120f 7361 if (IS_ERR(flowtable))
3b49e2e9
PNA
7362 return PTR_ERR(flowtable);
7363
d9adf22a 7364 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
3b49e2e9
PNA
7365 if (!skb2)
7366 return -ENOMEM;
7367
7368 err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid,
7369 nlh->nlmsg_seq,
7370 NFT_MSG_NEWFLOWTABLE, 0, family,
c42d8bda 7371 flowtable, &flowtable->hook_list);
3b49e2e9 7372 if (err < 0)
ee921183 7373 goto err_fill_flowtable_info;
3b49e2e9 7374
ee921183
PNA
7375 return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
7376
7377err_fill_flowtable_info:
3b49e2e9
PNA
7378 kfree_skb(skb2);
7379 return err;
7380}
7381
7382static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
7383 struct nft_flowtable *flowtable,
c42d8bda 7384 struct list_head *hook_list,
3b49e2e9
PNA
7385 int event)
7386{
0854db2a 7387 struct nftables_pernet *nft_net = net_generic(ctx->net, nf_tables_net_id);
3b49e2e9
PNA
7388 struct sk_buff *skb;
7389 int err;
7390
dceababa 7391 if (!ctx->report &&
3b49e2e9
PNA
7392 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
7393 return;
7394
7395 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
7396 if (skb == NULL)
7397 goto err;
7398
7399 err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid,
7400 ctx->seq, event, 0,
c42d8bda 7401 ctx->family, flowtable, hook_list);
3b49e2e9
PNA
7402 if (err < 0) {
7403 kfree_skb(skb);
7404 goto err;
7405 }
7406
0854db2a 7407 nft_notify_enqueue(skb, ctx->report, &nft_net->notify_list);
3b49e2e9
PNA
7408 return;
7409err:
7410 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
7411}
7412
3b49e2e9
PNA
7413static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
7414{
3f0465a9
PNA
7415 struct nft_hook *hook, *next;
7416
5acab914 7417 flowtable->data.type->free(&flowtable->data);
3f0465a9 7418 list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) {
5acab914
PNA
7419 flowtable->data.type->setup(&flowtable->data, hook->ops.dev,
7420 FLOW_BLOCK_UNBIND);
3f0465a9
PNA
7421 list_del_rcu(&hook->list);
7422 kfree(hook);
7423 }
3b49e2e9 7424 kfree(flowtable->name);
3b49e2e9 7425 module_put(flowtable->data.type->owner);
a12486eb 7426 kfree(flowtable);
3b49e2e9
PNA
7427}
7428
84d7fce6
PNA
7429static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
7430 u32 portid, u32 seq)
7431{
0854db2a 7432 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
84d7fce6 7433 struct nlmsghdr *nlh;
784b4e61 7434 char buf[TASK_COMM_LEN];
dedb67c4 7435 int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN);
84d7fce6 7436
19c28b13
PNA
7437 nlh = nfnl_msg_put(skb, portid, seq, event, 0, AF_UNSPEC,
7438 NFNETLINK_V0, nft_base_seq(net));
7439 if (!nlh)
84d7fce6
PNA
7440 goto nla_put_failure;
7441
0854db2a 7442 if (nla_put_be32(skb, NFTA_GEN_ID, htonl(nft_net->base_seq)) ||
784b4e61
PS
7443 nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
7444 nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
84d7fce6
PNA
7445 goto nla_put_failure;
7446
053c095a
JB
7447 nlmsg_end(skb, nlh);
7448 return 0;
84d7fce6
PNA
7449
7450nla_put_failure:
7451 nlmsg_trim(skb, nlh);
7452 return -EMSGSIZE;
7453}
7454
3b49e2e9
PNA
7455static void nft_flowtable_event(unsigned long event, struct net_device *dev,
7456 struct nft_flowtable *flowtable)
7457{
3f0465a9 7458 struct nft_hook *hook;
3b49e2e9 7459
3f0465a9
PNA
7460 list_for_each_entry(hook, &flowtable->hook_list, list) {
7461 if (hook->ops.dev != dev)
3b49e2e9
PNA
7462 continue;
7463
5acab914 7464 /* flow_offload_netdev_event() cleans up entries for us. */
ff4bf2f4 7465 nft_unregister_flowtable_hook(dev_net(dev), flowtable, hook);
3f0465a9
PNA
7466 list_del_rcu(&hook->list);
7467 kfree_rcu(hook, rcu);
3b49e2e9
PNA
7468 break;
7469 }
7470}
7471
7472static int nf_tables_flowtable_event(struct notifier_block *this,
7473 unsigned long event, void *ptr)
7474{
7475 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
7476 struct nft_flowtable *flowtable;
0854db2a 7477 struct nftables_pernet *nft_net;
3b49e2e9 7478 struct nft_table *table;
0a2cf5ee 7479 struct net *net;
3b49e2e9
PNA
7480
7481 if (event != NETDEV_UNREGISTER)
7482 return 0;
7483
6a48de01 7484 net = dev_net(dev);
0854db2a
FW
7485 nft_net = net_generic(net, nf_tables_net_id);
7486 mutex_lock(&nft_net->commit_mutex);
7487 list_for_each_entry(table, &nft_net->tables, list) {
36596dad
PNA
7488 list_for_each_entry(flowtable, &table->flowtables, list) {
7489 nft_flowtable_event(event, dev, flowtable);
3b49e2e9
PNA
7490 }
7491 }
0854db2a 7492 mutex_unlock(&nft_net->commit_mutex);
6a48de01 7493
3b49e2e9
PNA
7494 return NOTIFY_DONE;
7495}
7496
7497static struct notifier_block nf_tables_flowtable_notifier = {
7498 .notifier_call = nf_tables_flowtable_event,
7499};
7500
25e94a99
PNA
7501static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
7502 int event)
84d7fce6
PNA
7503{
7504 struct nlmsghdr *nlh = nlmsg_hdr(skb);
7505 struct sk_buff *skb2;
7506 int err;
7507
dceababa 7508 if (!nlmsg_report(nlh) &&
84d7fce6 7509 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 7510 return;
84d7fce6 7511
84d7fce6
PNA
7512 skb2 = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
7513 if (skb2 == NULL)
7514 goto err;
7515
7516 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
7517 nlh->nlmsg_seq);
7518 if (err < 0) {
7519 kfree_skb(skb2);
7520 goto err;
7521 }
7522
25e94a99
PNA
7523 nfnetlink_send(skb2, net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
7524 nlmsg_report(nlh), GFP_KERNEL);
7525 return;
84d7fce6 7526err:
25e94a99
PNA
7527 nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
7528 -ENOBUFS);
84d7fce6
PNA
7529}
7530
7b8002a1
PNA
7531static int nf_tables_getgen(struct net *net, struct sock *nlsk,
7532 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
7533 const struct nlattr * const nla[],
7534 struct netlink_ext_ack *extack)
84d7fce6 7535{
84d7fce6
PNA
7536 struct sk_buff *skb2;
7537 int err;
7538
d9adf22a 7539 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
84d7fce6
PNA
7540 if (skb2 == NULL)
7541 return -ENOMEM;
7542
7543 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
7544 nlh->nlmsg_seq);
7545 if (err < 0)
ee921183 7546 goto err_fill_gen_info;
84d7fce6 7547
ee921183
PNA
7548 return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
7549
7550err_fill_gen_info:
84d7fce6
PNA
7551 kfree_skb(skb2);
7552 return err;
7553}
7554
96518518
PM
7555static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
7556 [NFT_MSG_NEWTABLE] = {
55dd6f93 7557 .call_batch = nf_tables_newtable,
96518518
PM
7558 .attr_count = NFTA_TABLE_MAX,
7559 .policy = nft_table_policy,
7560 },
7561 [NFT_MSG_GETTABLE] = {
d9adf22a 7562 .call_rcu = nf_tables_gettable,
96518518
PM
7563 .attr_count = NFTA_TABLE_MAX,
7564 .policy = nft_table_policy,
7565 },
7566 [NFT_MSG_DELTABLE] = {
55dd6f93 7567 .call_batch = nf_tables_deltable,
96518518
PM
7568 .attr_count = NFTA_TABLE_MAX,
7569 .policy = nft_table_policy,
7570 },
7571 [NFT_MSG_NEWCHAIN] = {
91c7b38d 7572 .call_batch = nf_tables_newchain,
96518518
PM
7573 .attr_count = NFTA_CHAIN_MAX,
7574 .policy = nft_chain_policy,
7575 },
7576 [NFT_MSG_GETCHAIN] = {
d9adf22a 7577 .call_rcu = nf_tables_getchain,
96518518
PM
7578 .attr_count = NFTA_CHAIN_MAX,
7579 .policy = nft_chain_policy,
7580 },
7581 [NFT_MSG_DELCHAIN] = {
91c7b38d 7582 .call_batch = nf_tables_delchain,
96518518
PM
7583 .attr_count = NFTA_CHAIN_MAX,
7584 .policy = nft_chain_policy,
7585 },
7586 [NFT_MSG_NEWRULE] = {
0628b123 7587 .call_batch = nf_tables_newrule,
96518518
PM
7588 .attr_count = NFTA_RULE_MAX,
7589 .policy = nft_rule_policy,
7590 },
7591 [NFT_MSG_GETRULE] = {
d9adf22a 7592 .call_rcu = nf_tables_getrule,
96518518
PM
7593 .attr_count = NFTA_RULE_MAX,
7594 .policy = nft_rule_policy,
7595 },
7596 [NFT_MSG_DELRULE] = {
0628b123 7597 .call_batch = nf_tables_delrule,
96518518
PM
7598 .attr_count = NFTA_RULE_MAX,
7599 .policy = nft_rule_policy,
7600 },
20a69341 7601 [NFT_MSG_NEWSET] = {
958bee14 7602 .call_batch = nf_tables_newset,
20a69341
PM
7603 .attr_count = NFTA_SET_MAX,
7604 .policy = nft_set_policy,
7605 },
7606 [NFT_MSG_GETSET] = {
d9adf22a 7607 .call_rcu = nf_tables_getset,
20a69341
PM
7608 .attr_count = NFTA_SET_MAX,
7609 .policy = nft_set_policy,
7610 },
7611 [NFT_MSG_DELSET] = {
958bee14 7612 .call_batch = nf_tables_delset,
20a69341
PM
7613 .attr_count = NFTA_SET_MAX,
7614 .policy = nft_set_policy,
7615 },
7616 [NFT_MSG_NEWSETELEM] = {
958bee14 7617 .call_batch = nf_tables_newsetelem,
20a69341
PM
7618 .attr_count = NFTA_SET_ELEM_LIST_MAX,
7619 .policy = nft_set_elem_list_policy,
7620 },
7621 [NFT_MSG_GETSETELEM] = {
d9adf22a 7622 .call_rcu = nf_tables_getsetelem,
20a69341
PM
7623 .attr_count = NFTA_SET_ELEM_LIST_MAX,
7624 .policy = nft_set_elem_list_policy,
7625 },
7626 [NFT_MSG_DELSETELEM] = {
958bee14 7627 .call_batch = nf_tables_delsetelem,
20a69341
PM
7628 .attr_count = NFTA_SET_ELEM_LIST_MAX,
7629 .policy = nft_set_elem_list_policy,
7630 },
84d7fce6 7631 [NFT_MSG_GETGEN] = {
d9adf22a 7632 .call_rcu = nf_tables_getgen,
84d7fce6 7633 },
e5009240
PNA
7634 [NFT_MSG_NEWOBJ] = {
7635 .call_batch = nf_tables_newobj,
7636 .attr_count = NFTA_OBJ_MAX,
7637 .policy = nft_obj_policy,
7638 },
7639 [NFT_MSG_GETOBJ] = {
d9adf22a 7640 .call_rcu = nf_tables_getobj,
e5009240
PNA
7641 .attr_count = NFTA_OBJ_MAX,
7642 .policy = nft_obj_policy,
7643 },
7644 [NFT_MSG_DELOBJ] = {
7645 .call_batch = nf_tables_delobj,
7646 .attr_count = NFTA_OBJ_MAX,
7647 .policy = nft_obj_policy,
7648 },
43da04a5 7649 [NFT_MSG_GETOBJ_RESET] = {
d9adf22a 7650 .call_rcu = nf_tables_getobj,
43da04a5
PNA
7651 .attr_count = NFTA_OBJ_MAX,
7652 .policy = nft_obj_policy,
7653 },
3b49e2e9
PNA
7654 [NFT_MSG_NEWFLOWTABLE] = {
7655 .call_batch = nf_tables_newflowtable,
7656 .attr_count = NFTA_FLOWTABLE_MAX,
7657 .policy = nft_flowtable_policy,
7658 },
7659 [NFT_MSG_GETFLOWTABLE] = {
d9adf22a 7660 .call_rcu = nf_tables_getflowtable,
3b49e2e9
PNA
7661 .attr_count = NFTA_FLOWTABLE_MAX,
7662 .policy = nft_flowtable_policy,
7663 },
7664 [NFT_MSG_DELFLOWTABLE] = {
7665 .call_batch = nf_tables_delflowtable,
7666 .attr_count = NFTA_FLOWTABLE_MAX,
7667 .policy = nft_flowtable_policy,
7668 },
96518518
PM
7669};
7670
a654de8f
PNA
7671static int nf_tables_validate(struct net *net)
7672{
0854db2a 7673 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
a654de8f
PNA
7674 struct nft_table *table;
7675
0854db2a 7676 switch (nft_net->validate_state) {
a654de8f
PNA
7677 case NFT_VALIDATE_SKIP:
7678 break;
7679 case NFT_VALIDATE_NEED:
7680 nft_validate_state_update(net, NFT_VALIDATE_DO);
954d8297 7681 fallthrough;
a654de8f 7682 case NFT_VALIDATE_DO:
0854db2a 7683 list_for_each_entry(table, &nft_net->tables, list) {
a654de8f
PNA
7684 if (nft_table_validate(net, table) < 0)
7685 return -EAGAIN;
7686 }
7687 break;
7688 }
7689
7690 return 0;
7691}
7692
66293c46
FW
7693/* a drop policy has to be deferred until all rules have been activated,
7694 * otherwise a large ruleset that contains a drop-policy base chain will
7695 * cause all packets to get dropped until the full transaction has been
7696 * processed.
7697 *
7698 * We defer the drop policy until the transaction has been finalized.
7699 */
7700static void nft_chain_commit_drop_policy(struct nft_trans *trans)
7701{
7702 struct nft_base_chain *basechain;
7703
7704 if (nft_trans_chain_policy(trans) != NF_DROP)
7705 return;
7706
7707 if (!nft_is_base_chain(trans->ctx.chain))
7708 return;
7709
7710 basechain = nft_base_chain(trans->ctx.chain);
7711 basechain->policy = NF_DROP;
7712}
7713
91c7b38d
PNA
7714static void nft_chain_commit_update(struct nft_trans *trans)
7715{
7716 struct nft_base_chain *basechain;
7717
1b2470e5
FW
7718 if (nft_trans_chain_name(trans)) {
7719 rhltable_remove(&trans->ctx.table->chains_ht,
7720 &trans->ctx.chain->rhlhead,
7721 nft_chain_ht_params);
d71efb59 7722 swap(trans->ctx.chain->name, nft_trans_chain_name(trans));
1b2470e5
FW
7723 rhltable_insert_key(&trans->ctx.table->chains_ht,
7724 trans->ctx.chain->name,
7725 &trans->ctx.chain->rhlhead,
7726 nft_chain_ht_params);
7727 }
91c7b38d 7728
f323d954 7729 if (!nft_is_base_chain(trans->ctx.chain))
91c7b38d
PNA
7730 return;
7731
53315ac6
FW
7732 nft_chain_stats_replace(trans);
7733
91c7b38d 7734 basechain = nft_base_chain(trans->ctx.chain);
91c7b38d
PNA
7735
7736 switch (nft_trans_chain_policy(trans)) {
7737 case NF_DROP:
7738 case NF_ACCEPT:
7739 basechain->policy = nft_trans_chain_policy(trans);
7740 break;
7741 }
7742}
7743
d62d0ba9
FFM
7744static void nft_obj_commit_update(struct nft_trans *trans)
7745{
7746 struct nft_object *newobj;
7747 struct nft_object *obj;
7748
7749 obj = nft_trans_obj(trans);
7750 newobj = nft_trans_obj_newobj(trans);
7751
9fedd894
FFM
7752 if (obj->ops->update)
7753 obj->ops->update(obj, newobj);
d62d0ba9
FFM
7754
7755 kfree(newobj);
7756}
7757
2f99aa31 7758static void nft_commit_release(struct nft_trans *trans)
c7c32e72 7759{
c7c32e72
PNA
7760 switch (trans->msg_type) {
7761 case NFT_MSG_DELTABLE:
7762 nf_tables_table_destroy(&trans->ctx);
7763 break;
9f8aac0b 7764 case NFT_MSG_NEWCHAIN:
53315ac6 7765 free_percpu(nft_trans_chain_stats(trans));
9f8aac0b
FW
7766 kfree(nft_trans_chain_name(trans));
7767 break;
c7c32e72 7768 case NFT_MSG_DELCHAIN:
43a605f2 7769 nf_tables_chain_destroy(&trans->ctx);
c7c32e72
PNA
7770 break;
7771 case NFT_MSG_DELRULE:
7772 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
7773 break;
7774 case NFT_MSG_DELSET:
0c2a85ed 7775 nft_set_destroy(&trans->ctx, nft_trans_set(trans));
c7c32e72 7776 break;
61edafbb 7777 case NFT_MSG_DELSETELEM:
3453c927
PNA
7778 nf_tables_set_elem_destroy(&trans->ctx,
7779 nft_trans_elem_set(trans),
59105446 7780 nft_trans_elem(trans).priv);
61edafbb 7781 break;
e5009240 7782 case NFT_MSG_DELOBJ:
00bfb320 7783 nft_obj_destroy(&trans->ctx, nft_trans_obj(trans));
e5009240 7784 break;
3b49e2e9 7785 case NFT_MSG_DELFLOWTABLE:
abadb2f8
PNA
7786 if (nft_trans_flowtable_update(trans))
7787 nft_flowtable_hooks_destroy(&nft_trans_flowtable_hooks(trans));
7788 else
7789 nf_tables_flowtable_destroy(nft_trans_flowtable(trans));
3b49e2e9 7790 break;
c7c32e72 7791 }
0935d558
FW
7792
7793 if (trans->put_net)
7794 put_net(trans->ctx.net);
7795
c7c32e72
PNA
7796 kfree(trans);
7797}
7798
0935d558 7799static void nf_tables_trans_destroy_work(struct work_struct *w)
2f99aa31
FW
7800{
7801 struct nft_trans *trans, *next;
0935d558
FW
7802 LIST_HEAD(head);
7803
7804 spin_lock(&nf_tables_destroy_list_lock);
7805 list_splice_init(&nf_tables_destroy_list, &head);
7806 spin_unlock(&nf_tables_destroy_list_lock);
2f99aa31 7807
0935d558 7808 if (list_empty(&head))
2f99aa31
FW
7809 return;
7810
7811 synchronize_rcu();
7812
0935d558 7813 list_for_each_entry_safe(trans, next, &head, list) {
2f99aa31
FW
7814 list_del(&trans->list);
7815 nft_commit_release(trans);
7816 }
7817}
7818
ffe8923f
FW
7819void nf_tables_trans_destroy_flush_work(void)
7820{
7821 flush_work(&trans_destroy_work);
7822}
7823EXPORT_SYMBOL_GPL(nf_tables_trans_destroy_flush_work);
7824
0cbc06b3
FW
7825static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *chain)
7826{
7827 struct nft_rule *rule;
7828 unsigned int alloc = 0;
7829 int i;
7830
7831 /* already handled or inactive chain? */
7832 if (chain->rules_next || !nft_is_active_next(net, chain))
7833 return 0;
7834
7835 rule = list_entry(&chain->rules, struct nft_rule, list);
7836 i = 0;
7837
7838 list_for_each_entry_continue(rule, &chain->rules, list) {
7839 if (nft_is_active_next(net, rule))
7840 alloc++;
7841 }
7842
7843 chain->rules_next = nf_tables_chain_alloc_rules(chain, alloc);
7844 if (!chain->rules_next)
7845 return -ENOMEM;
7846
7847 list_for_each_entry_continue(rule, &chain->rules, list) {
7848 if (nft_is_active_next(net, rule))
7849 chain->rules_next[i++] = rule;
7850 }
7851
7852 chain->rules_next[i] = NULL;
7853 return 0;
7854}
7855
7856static void nf_tables_commit_chain_prepare_cancel(struct net *net)
7857{
0854db2a 7858 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
0cbc06b3
FW
7859 struct nft_trans *trans, *next;
7860
0854db2a 7861 list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
0cbc06b3
FW
7862 struct nft_chain *chain = trans->ctx.chain;
7863
7864 if (trans->msg_type == NFT_MSG_NEWRULE ||
7865 trans->msg_type == NFT_MSG_DELRULE) {
7866 kvfree(chain->rules_next);
7867 chain->rules_next = NULL;
7868 }
7869 }
7870}
7871
7872static void __nf_tables_commit_chain_free_rules_old(struct rcu_head *h)
7873{
7874 struct nft_rules_old *o = container_of(h, struct nft_rules_old, h);
7875
7876 kvfree(o->start);
7877}
7878
7879static void nf_tables_commit_chain_free_rules_old(struct nft_rule **rules)
7880{
7881 struct nft_rule **r = rules;
7882 struct nft_rules_old *old;
7883
7884 while (*r)
7885 r++;
7886
7887 r++; /* rcu_head is after end marker */
7888 old = (void *) r;
7889 old->start = rules;
7890
7891 call_rcu(&old->h, __nf_tables_commit_chain_free_rules_old);
7892}
7893
0fb39bbe 7894static void nf_tables_commit_chain(struct net *net, struct nft_chain *chain)
0cbc06b3
FW
7895{
7896 struct nft_rule **g0, **g1;
7897 bool next_genbit;
7898
7899 next_genbit = nft_gencursor_next(net);
7900
7901 g0 = rcu_dereference_protected(chain->rules_gen_0,
f102d66b 7902 lockdep_commit_lock_is_held(net));
0cbc06b3 7903 g1 = rcu_dereference_protected(chain->rules_gen_1,
f102d66b 7904 lockdep_commit_lock_is_held(net));
0cbc06b3
FW
7905
7906 /* No changes to this chain? */
7907 if (chain->rules_next == NULL) {
7908 /* chain had no change in last or next generation */
7909 if (g0 == g1)
7910 return;
7911 /*
7912 * chain had no change in this generation; make sure next
7913 * one uses same rules as current generation.
7914 */
7915 if (next_genbit) {
7916 rcu_assign_pointer(chain->rules_gen_1, g0);
7917 nf_tables_commit_chain_free_rules_old(g1);
7918 } else {
7919 rcu_assign_pointer(chain->rules_gen_0, g1);
7920 nf_tables_commit_chain_free_rules_old(g0);
7921 }
7922
7923 return;
7924 }
7925
7926 if (next_genbit)
7927 rcu_assign_pointer(chain->rules_gen_1, chain->rules_next);
7928 else
7929 rcu_assign_pointer(chain->rules_gen_0, chain->rules_next);
7930
7931 chain->rules_next = NULL;
7932
7933 if (g0 == g1)
7934 return;
7935
7936 if (next_genbit)
7937 nf_tables_commit_chain_free_rules_old(g1);
7938 else
7939 nf_tables_commit_chain_free_rules_old(g0);
7940}
7941
d152159b
FW
7942static void nft_obj_del(struct nft_object *obj)
7943{
4d44175a 7944 rhltable_remove(&nft_objname_ht, &obj->rhlhead, nft_objname_ht_params);
d152159b
FW
7945 list_del_rcu(&obj->list);
7946}
7947
d0e2c7de 7948void nft_chain_del(struct nft_chain *chain)
1b2470e5
FW
7949{
7950 struct nft_table *table = chain->table;
7951
7952 WARN_ON_ONCE(rhltable_remove(&table->chains_ht, &chain->rhlhead,
7953 nft_chain_ht_params));
7954 list_del_rcu(&chain->list);
7955}
7956
abadb2f8
PNA
7957static void nft_flowtable_hooks_del(struct nft_flowtable *flowtable,
7958 struct list_head *hook_list)
7959{
7960 struct nft_hook *hook, *next;
7961
7962 list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) {
7963 if (hook->inactive)
7964 list_move(&hook->list, hook_list);
7965 }
7966}
7967
eb014de4
PNA
7968static void nf_tables_module_autoload_cleanup(struct net *net)
7969{
0854db2a 7970 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
eb014de4
PNA
7971 struct nft_module_request *req, *next;
7972
0854db2a
FW
7973 WARN_ON_ONCE(!list_empty(&nft_net->commit_list));
7974 list_for_each_entry_safe(req, next, &nft_net->module_list, list) {
eb014de4
PNA
7975 WARN_ON_ONCE(!req->done);
7976 list_del(&req->list);
7977 kfree(req);
7978 }
7979}
7980
0935d558
FW
7981static void nf_tables_commit_release(struct net *net)
7982{
0854db2a 7983 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
0935d558
FW
7984 struct nft_trans *trans;
7985
7986 /* all side effects have to be made visible.
7987 * For example, if a chain named 'foo' has been deleted, a
7988 * new transaction must not find it anymore.
7989 *
7990 * Memory reclaim happens asynchronously from work queue
7991 * to prevent expensive synchronize_rcu() in commit phase.
7992 */
0854db2a 7993 if (list_empty(&nft_net->commit_list)) {
eb014de4 7994 nf_tables_module_autoload_cleanup(net);
0854db2a 7995 mutex_unlock(&nft_net->commit_mutex);
0935d558
FW
7996 return;
7997 }
7998
0854db2a 7999 trans = list_last_entry(&nft_net->commit_list,
0935d558
FW
8000 struct nft_trans, list);
8001 get_net(trans->ctx.net);
8002 WARN_ON_ONCE(trans->put_net);
8003
8004 trans->put_net = true;
8005 spin_lock(&nf_tables_destroy_list_lock);
0854db2a 8006 list_splice_tail_init(&nft_net->commit_list, &nf_tables_destroy_list);
0935d558
FW
8007 spin_unlock(&nf_tables_destroy_list_lock);
8008
eb014de4 8009 nf_tables_module_autoload_cleanup(net);
0935d558 8010 schedule_work(&trans_destroy_work);
ffe8923f 8011
0854db2a 8012 mutex_unlock(&nft_net->commit_mutex);
0935d558
FW
8013}
8014
67cc570e
PNA
8015static void nft_commit_notify(struct net *net, u32 portid)
8016{
0854db2a 8017 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
67cc570e
PNA
8018 struct sk_buff *batch_skb = NULL, *nskb, *skb;
8019 unsigned char *data;
8020 int len;
8021
0854db2a 8022 list_for_each_entry_safe(skb, nskb, &nft_net->notify_list, list) {
67cc570e
PNA
8023 if (!batch_skb) {
8024new_batch:
8025 batch_skb = skb;
8026 len = NLMSG_GOODSIZE - skb->len;
8027 list_del(&skb->list);
8028 continue;
8029 }
8030 len -= skb->len;
8031 if (len > 0 && NFT_CB(skb).report == NFT_CB(batch_skb).report) {
8032 data = skb_put(batch_skb, skb->len);
8033 memcpy(data, skb->data, skb->len);
8034 list_del(&skb->list);
8035 kfree_skb(skb);
8036 continue;
8037 }
8038 nfnetlink_send(batch_skb, net, portid, NFNLGRP_NFTABLES,
8039 NFT_CB(batch_skb).report, GFP_KERNEL);
8040 goto new_batch;
8041 }
8042
8043 if (batch_skb) {
8044 nfnetlink_send(batch_skb, net, portid, NFNLGRP_NFTABLES,
8045 NFT_CB(batch_skb).report, GFP_KERNEL);
8046 }
8047
0854db2a 8048 WARN_ON_ONCE(!list_empty(&nft_net->notify_list));
67cc570e
PNA
8049}
8050
c520292f
RGB
8051static int nf_tables_commit_audit_alloc(struct list_head *adl,
8052 struct nft_table *table)
8053{
8054 struct nft_audit_data *adp;
8055
8056 list_for_each_entry(adp, adl, list) {
8057 if (adp->table == table)
8058 return 0;
8059 }
8060 adp = kzalloc(sizeof(*adp), GFP_KERNEL);
8061 if (!adp)
8062 return -ENOMEM;
8063 adp->table = table;
8064 list_add(&adp->list, adl);
8065 return 0;
8066}
8067
8068static void nf_tables_commit_audit_collect(struct list_head *adl,
8069 struct nft_table *table, u32 op)
8070{
8071 struct nft_audit_data *adp;
8072
8073 list_for_each_entry(adp, adl, list) {
8074 if (adp->table == table)
8075 goto found;
8076 }
dadf33c9 8077 WARN_ONCE(1, "table=%s not expected in commit list", table->name);
c520292f
RGB
8078 return;
8079found:
8080 adp->entries++;
8081 if (!adp->op || adp->op > op)
8082 adp->op = op;
8083}
8084
8085#define AUNFTABLENAMELEN (NFT_TABLE_MAXNAMELEN + 22)
8086
8087static void nf_tables_commit_audit_log(struct list_head *adl, u32 generation)
8088{
8089 struct nft_audit_data *adp, *adn;
8090 char aubuf[AUNFTABLENAMELEN];
8091
8092 list_for_each_entry_safe(adp, adn, adl, list) {
8093 snprintf(aubuf, AUNFTABLENAMELEN, "%s:%u", adp->table->name,
8094 generation);
8095 audit_log_nfcfg(aubuf, adp->table->family, adp->entries,
8096 nft2audit_op[adp->op], GFP_KERNEL);
8097 list_del(&adp->list);
8098 kfree(adp);
8099 }
8100}
8101
5913beaf 8102static int nf_tables_commit(struct net *net, struct sk_buff *skb)
37082f93 8103{
0854db2a 8104 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
37082f93 8105 struct nft_trans *trans, *next;
a3716e70 8106 struct nft_trans_elem *te;
0cbc06b3
FW
8107 struct nft_chain *chain;
8108 struct nft_table *table;
c520292f 8109 LIST_HEAD(adl);
c9626a2c 8110 int err;
37082f93 8111
0854db2a
FW
8112 if (list_empty(&nft_net->commit_list)) {
8113 mutex_unlock(&nft_net->commit_mutex);
b8b27498
FW
8114 return 0;
8115 }
8116
a654de8f
PNA
8117 /* 0. Validate ruleset, otherwise roll back for error reporting. */
8118 if (nf_tables_validate(net) < 0)
8119 return -EAGAIN;
8120
c9626a2c
PNA
8121 err = nft_flow_rule_offload_commit(net);
8122 if (err < 0)
8123 return err;
8124
0cbc06b3 8125 /* 1. Allocate space for next generation rules_gen_X[] */
0854db2a 8126 list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
0cbc06b3 8127 int ret;
37082f93 8128
c520292f
RGB
8129 ret = nf_tables_commit_audit_alloc(&adl, trans->ctx.table);
8130 if (ret) {
8131 nf_tables_commit_chain_prepare_cancel(net);
8132 return ret;
8133 }
0cbc06b3
FW
8134 if (trans->msg_type == NFT_MSG_NEWRULE ||
8135 trans->msg_type == NFT_MSG_DELRULE) {
8136 chain = trans->ctx.chain;
8137
8138 ret = nf_tables_commit_chain_prepare(net, chain);
8139 if (ret < 0) {
8140 nf_tables_commit_chain_prepare_cancel(net);
8141 return ret;
8142 }
8143 }
8144 }
37082f93 8145
0cbc06b3 8146 /* step 2. Make rules_gen_X visible to packet path */
0854db2a 8147 list_for_each_entry(table, &nft_net->tables, list) {
0fb39bbe
FW
8148 list_for_each_entry(chain, &table->chains, list)
8149 nf_tables_commit_chain(net, chain);
0cbc06b3
FW
8150 }
8151
8152 /*
8153 * Bump generation counter, invalidate any dump in progress.
8154 * Cannot fail after this point.
37082f93 8155 */
0854db2a
FW
8156 while (++nft_net->base_seq == 0)
8157 ;
0cbc06b3
FW
8158
8159 /* step 3. Start new generation, rules_gen_X now in use. */
8160 net->nft.gencursor = nft_gencursor_next(net);
37082f93 8161
0854db2a 8162 list_for_each_entry_safe(trans, next, &nft_net->commit_list, list) {
c520292f
RGB
8163 nf_tables_commit_audit_collect(&adl, trans->ctx.table,
8164 trans->msg_type);
b380e5c7 8165 switch (trans->msg_type) {
55dd6f93
PNA
8166 case NFT_MSG_NEWTABLE:
8167 if (nft_trans_table_update(trans)) {
0ce7cf41
PNA
8168 if (nft_trans_table_state(trans) == NFT_TABLE_STATE_DORMANT)
8169 nf_tables_table_disable(net, trans->ctx.table);
8170
8171 trans->ctx.table->flags = nft_trans_table_flags(trans);
55dd6f93 8172 } else {
f2a6d766 8173 nft_clear(net, trans->ctx.table);
55dd6f93 8174 }
35151d84 8175 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
55dd6f93
PNA
8176 nft_trans_destroy(trans);
8177 break;
8178 case NFT_MSG_DELTABLE:
f2a6d766 8179 list_del_rcu(&trans->ctx.table->list);
35151d84 8180 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
55dd6f93 8181 break;
91c7b38d 8182 case NFT_MSG_NEWCHAIN:
9f8aac0b 8183 if (nft_trans_chain_update(trans)) {
91c7b38d 8184 nft_chain_commit_update(trans);
9f8aac0b
FW
8185 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
8186 /* trans destroyed after rcu grace period */
8187 } else {
66293c46 8188 nft_chain_commit_drop_policy(trans);
664b0f8c 8189 nft_clear(net, trans->ctx.chain);
9f8aac0b
FW
8190 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
8191 nft_trans_destroy(trans);
8192 }
91c7b38d
PNA
8193 break;
8194 case NFT_MSG_DELCHAIN:
1b2470e5 8195 nft_chain_del(trans->ctx.chain);
35151d84 8196 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
c974a3a3
PNA
8197 nf_tables_unregister_hook(trans->ctx.net,
8198 trans->ctx.table,
8199 trans->ctx.chain);
91c7b38d 8200 break;
b380e5c7 8201 case NFT_MSG_NEWRULE:
889f7ee7 8202 nft_clear(trans->ctx.net, nft_trans_rule(trans));
35151d84 8203 nf_tables_rule_notify(&trans->ctx,
37082f93 8204 nft_trans_rule(trans),
35151d84 8205 NFT_MSG_NEWRULE);
37082f93 8206 nft_trans_destroy(trans);
b380e5c7
PNA
8207 break;
8208 case NFT_MSG_DELRULE:
8209 list_del_rcu(&nft_trans_rule(trans)->list);
35151d84
PNA
8210 nf_tables_rule_notify(&trans->ctx,
8211 nft_trans_rule(trans),
8212 NFT_MSG_DELRULE);
f6ac8585
PNA
8213 nft_rule_expr_deactivate(&trans->ctx,
8214 nft_trans_rule(trans),
8215 NFT_TRANS_COMMIT);
b380e5c7 8216 break;
958bee14 8217 case NFT_MSG_NEWSET:
37a9cc52 8218 nft_clear(net, nft_trans_set(trans));
4fefee57
PNA
8219 /* This avoids hitting -EBUSY when deleting the table
8220 * from the transaction.
8221 */
408070d6 8222 if (nft_set_is_anonymous(nft_trans_set(trans)) &&
4fefee57
PNA
8223 !list_empty(&nft_trans_set(trans)->bindings))
8224 trans->ctx.table->use--;
8225
958bee14 8226 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 8227 NFT_MSG_NEWSET, GFP_KERNEL);
958bee14
PNA
8228 nft_trans_destroy(trans);
8229 break;
8230 case NFT_MSG_DELSET:
37a9cc52 8231 list_del_rcu(&nft_trans_set(trans)->list);
958bee14 8232 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 8233 NFT_MSG_DELSET, GFP_KERNEL);
958bee14 8234 break;
60319eb1 8235 case NFT_MSG_NEWSETELEM:
cc02e457
PM
8236 te = (struct nft_trans_elem *)trans->data;
8237
42a55769 8238 te->set->ops->activate(net, te->set, &te->elem);
cc02e457
PM
8239 nf_tables_setelem_notify(&trans->ctx, te->set,
8240 &te->elem,
60319eb1
PNA
8241 NFT_MSG_NEWSETELEM, 0);
8242 nft_trans_destroy(trans);
8243 break;
8244 case NFT_MSG_DELSETELEM:
a3716e70 8245 te = (struct nft_trans_elem *)trans->data;
fe2811eb 8246
a3716e70
PNA
8247 nf_tables_setelem_notify(&trans->ctx, te->set,
8248 &te->elem,
60319eb1 8249 NFT_MSG_DELSETELEM, 0);
5cb82a38 8250 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a
PM
8251 atomic_dec(&te->set->nelems);
8252 te->set->ndeact--;
60319eb1 8253 break;
e5009240 8254 case NFT_MSG_NEWOBJ:
d62d0ba9
FFM
8255 if (nft_trans_obj_update(trans)) {
8256 nft_obj_commit_update(trans);
8257 nf_tables_obj_notify(&trans->ctx,
8258 nft_trans_obj(trans),
8259 NFT_MSG_NEWOBJ);
8260 } else {
8261 nft_clear(net, nft_trans_obj(trans));
8262 nf_tables_obj_notify(&trans->ctx,
8263 nft_trans_obj(trans),
8264 NFT_MSG_NEWOBJ);
8265 nft_trans_destroy(trans);
8266 }
e5009240
PNA
8267 break;
8268 case NFT_MSG_DELOBJ:
d152159b 8269 nft_obj_del(nft_trans_obj(trans));
e5009240
PNA
8270 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
8271 NFT_MSG_DELOBJ);
8272 break;
3b49e2e9 8273 case NFT_MSG_NEWFLOWTABLE:
78d9f48f 8274 if (nft_trans_flowtable_update(trans)) {
7b35582c
PNA
8275 nft_trans_flowtable(trans)->data.flags =
8276 nft_trans_flowtable_flags(trans);
78d9f48f
PNA
8277 nf_tables_flowtable_notify(&trans->ctx,
8278 nft_trans_flowtable(trans),
8279 &nft_trans_flowtable_hooks(trans),
8280 NFT_MSG_NEWFLOWTABLE);
8281 list_splice(&nft_trans_flowtable_hooks(trans),
8282 &nft_trans_flowtable(trans)->hook_list);
8283 } else {
8284 nft_clear(net, nft_trans_flowtable(trans));
8285 nf_tables_flowtable_notify(&trans->ctx,
8286 nft_trans_flowtable(trans),
8287 &nft_trans_flowtable(trans)->hook_list,
8288 NFT_MSG_NEWFLOWTABLE);
8289 }
3b49e2e9
PNA
8290 nft_trans_destroy(trans);
8291 break;
8292 case NFT_MSG_DELFLOWTABLE:
abadb2f8
PNA
8293 if (nft_trans_flowtable_update(trans)) {
8294 nft_flowtable_hooks_del(nft_trans_flowtable(trans),
8295 &nft_trans_flowtable_hooks(trans));
8296 nf_tables_flowtable_notify(&trans->ctx,
8297 nft_trans_flowtable(trans),
8298 &nft_trans_flowtable_hooks(trans),
8299 NFT_MSG_DELFLOWTABLE);
8300 nft_unregister_flowtable_net_hooks(net,
8301 &nft_trans_flowtable_hooks(trans));
8302 } else {
8303 list_del_rcu(&nft_trans_flowtable(trans)->list);
8304 nf_tables_flowtable_notify(&trans->ctx,
8305 nft_trans_flowtable(trans),
8306 &nft_trans_flowtable(trans)->hook_list,
8307 NFT_MSG_DELFLOWTABLE);
8308 nft_unregister_flowtable_net_hooks(net,
8309 &nft_trans_flowtable(trans)->hook_list);
8310 }
3b49e2e9 8311 break;
37082f93 8312 }
37082f93
PNA
8313 }
8314
67cc570e 8315 nft_commit_notify(net, NETLINK_CB(skb).portid);
84d7fce6 8316 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
0854db2a 8317 nf_tables_commit_audit_log(&adl, nft_net->base_seq);
0935d558 8318 nf_tables_commit_release(net);
37082f93
PNA
8319
8320 return 0;
8321}
8322
eb014de4
PNA
8323static void nf_tables_module_autoload(struct net *net)
8324{
0854db2a 8325 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
eb014de4
PNA
8326 struct nft_module_request *req, *next;
8327 LIST_HEAD(module_list);
8328
0854db2a
FW
8329 list_splice_init(&nft_net->module_list, &module_list);
8330 mutex_unlock(&nft_net->commit_mutex);
eb014de4 8331 list_for_each_entry_safe(req, next, &module_list, list) {
1d305ba4
FW
8332 request_module("%s", req->module);
8333 req->done = true;
eb014de4 8334 }
0854db2a
FW
8335 mutex_lock(&nft_net->commit_mutex);
8336 list_splice(&module_list, &nft_net->module_list);
eb014de4
PNA
8337}
8338
b326dd37 8339static void nf_tables_abort_release(struct nft_trans *trans)
c7c32e72 8340{
c7c32e72
PNA
8341 switch (trans->msg_type) {
8342 case NFT_MSG_NEWTABLE:
8343 nf_tables_table_destroy(&trans->ctx);
8344 break;
8345 case NFT_MSG_NEWCHAIN:
43a605f2 8346 nf_tables_chain_destroy(&trans->ctx);
c7c32e72
PNA
8347 break;
8348 case NFT_MSG_NEWRULE:
8349 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
8350 break;
8351 case NFT_MSG_NEWSET:
0c2a85ed 8352 nft_set_destroy(&trans->ctx, nft_trans_set(trans));
c7c32e72 8353 break;
61edafbb
PM
8354 case NFT_MSG_NEWSETELEM:
8355 nft_set_elem_destroy(nft_trans_elem_set(trans),
61f9e292 8356 nft_trans_elem(trans).priv, true);
61edafbb 8357 break;
e5009240 8358 case NFT_MSG_NEWOBJ:
00bfb320 8359 nft_obj_destroy(&trans->ctx, nft_trans_obj(trans));
e5009240 8360 break;
3b49e2e9 8361 case NFT_MSG_NEWFLOWTABLE:
78d9f48f
PNA
8362 if (nft_trans_flowtable_update(trans))
8363 nft_flowtable_hooks_destroy(&nft_trans_flowtable_hooks(trans));
8364 else
8365 nf_tables_flowtable_destroy(nft_trans_flowtable(trans));
3b49e2e9 8366 break;
c7c32e72
PNA
8367 }
8368 kfree(trans);
8369}
8370
c0391b6a 8371static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
37082f93 8372{
0854db2a 8373 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
37082f93 8374 struct nft_trans *trans, *next;
02263db0 8375 struct nft_trans_elem *te;
abadb2f8 8376 struct nft_hook *hook;
37082f93 8377
c0391b6a
PNA
8378 if (action == NFNL_ABORT_VALIDATE &&
8379 nf_tables_validate(net) < 0)
8380 return -EAGAIN;
8381
0854db2a 8382 list_for_each_entry_safe_reverse(trans, next, &nft_net->commit_list,
a907e36d 8383 list) {
b380e5c7 8384 switch (trans->msg_type) {
55dd6f93
PNA
8385 case NFT_MSG_NEWTABLE:
8386 if (nft_trans_table_update(trans)) {
0ce7cf41
PNA
8387 if (nft_trans_table_state(trans) == NFT_TABLE_STATE_WAKEUP)
8388 nf_tables_table_disable(net, trans->ctx.table);
8389
55dd6f93
PNA
8390 nft_trans_destroy(trans);
8391 } else {
e688a7f8 8392 list_del_rcu(&trans->ctx.table->list);
55dd6f93
PNA
8393 }
8394 break;
8395 case NFT_MSG_DELTABLE:
f2a6d766 8396 nft_clear(trans->ctx.net, trans->ctx.table);
55dd6f93
PNA
8397 nft_trans_destroy(trans);
8398 break;
91c7b38d
PNA
8399 case NFT_MSG_NEWCHAIN:
8400 if (nft_trans_chain_update(trans)) {
982f4051 8401 free_percpu(nft_trans_chain_stats(trans));
9f8aac0b 8402 kfree(nft_trans_chain_name(trans));
91c7b38d
PNA
8403 nft_trans_destroy(trans);
8404 } else {
d0e2c7de
PNA
8405 if (nft_chain_is_bound(trans->ctx.chain)) {
8406 nft_trans_destroy(trans);
8407 break;
8408 }
4fefee57 8409 trans->ctx.table->use--;
1b2470e5 8410 nft_chain_del(trans->ctx.chain);
c974a3a3
PNA
8411 nf_tables_unregister_hook(trans->ctx.net,
8412 trans->ctx.table,
8413 trans->ctx.chain);
91c7b38d
PNA
8414 }
8415 break;
8416 case NFT_MSG_DELCHAIN:
4fefee57 8417 trans->ctx.table->use++;
664b0f8c 8418 nft_clear(trans->ctx.net, trans->ctx.chain);
91c7b38d
PNA
8419 nft_trans_destroy(trans);
8420 break;
b380e5c7 8421 case NFT_MSG_NEWRULE:
4fefee57 8422 trans->ctx.chain->use--;
b380e5c7 8423 list_del_rcu(&nft_trans_rule(trans)->list);
f6ac8585
PNA
8424 nft_rule_expr_deactivate(&trans->ctx,
8425 nft_trans_rule(trans),
8426 NFT_TRANS_ABORT);
b380e5c7
PNA
8427 break;
8428 case NFT_MSG_DELRULE:
4fefee57 8429 trans->ctx.chain->use++;
889f7ee7 8430 nft_clear(trans->ctx.net, nft_trans_rule(trans));
bb7b40ae 8431 nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
37082f93 8432 nft_trans_destroy(trans);
b380e5c7 8433 break;
958bee14 8434 case NFT_MSG_NEWSET:
4fefee57 8435 trans->ctx.table->use--;
6a0a8d10 8436 if (nft_trans_set_bound(trans)) {
40ba1d9b
PNA
8437 nft_trans_destroy(trans);
8438 break;
8439 }
8440 list_del_rcu(&nft_trans_set(trans)->list);
958bee14
PNA
8441 break;
8442 case NFT_MSG_DELSET:
4fefee57 8443 trans->ctx.table->use++;
37a9cc52 8444 nft_clear(trans->ctx.net, nft_trans_set(trans));
958bee14
PNA
8445 nft_trans_destroy(trans);
8446 break;
60319eb1 8447 case NFT_MSG_NEWSETELEM:
6a0a8d10 8448 if (nft_trans_elem_set_bound(trans)) {
40ba1d9b
PNA
8449 nft_trans_destroy(trans);
8450 break;
8451 }
02263db0 8452 te = (struct nft_trans_elem *)trans->data;
5cb82a38 8453 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a 8454 atomic_dec(&te->set->nelems);
60319eb1
PNA
8455 break;
8456 case NFT_MSG_DELSETELEM:
cc02e457
PM
8457 te = (struct nft_trans_elem *)trans->data;
8458
59105446 8459 nft_set_elem_activate(net, te->set, &te->elem);
42a55769 8460 te->set->ops->activate(net, te->set, &te->elem);
3dd0673a 8461 te->set->ndeact--;
cc02e457 8462
e5009240
PNA
8463 nft_trans_destroy(trans);
8464 break;
8465 case NFT_MSG_NEWOBJ:
d62d0ba9
FFM
8466 if (nft_trans_obj_update(trans)) {
8467 kfree(nft_trans_obj_newobj(trans));
8468 nft_trans_destroy(trans);
8469 } else {
8470 trans->ctx.table->use--;
8471 nft_obj_del(nft_trans_obj(trans));
8472 }
e5009240
PNA
8473 break;
8474 case NFT_MSG_DELOBJ:
8475 trans->ctx.table->use++;
8476 nft_clear(trans->ctx.net, nft_trans_obj(trans));
60319eb1
PNA
8477 nft_trans_destroy(trans);
8478 break;
3b49e2e9 8479 case NFT_MSG_NEWFLOWTABLE:
78d9f48f
PNA
8480 if (nft_trans_flowtable_update(trans)) {
8481 nft_unregister_flowtable_net_hooks(net,
8482 &nft_trans_flowtable_hooks(trans));
8483 } else {
8484 trans->ctx.table->use--;
8485 list_del_rcu(&nft_trans_flowtable(trans)->list);
8486 nft_unregister_flowtable_net_hooks(net,
8487 &nft_trans_flowtable(trans)->hook_list);
8488 }
3b49e2e9
PNA
8489 break;
8490 case NFT_MSG_DELFLOWTABLE:
abadb2f8
PNA
8491 if (nft_trans_flowtable_update(trans)) {
8492 list_for_each_entry(hook, &nft_trans_flowtable(trans)->hook_list, list)
8493 hook->inactive = false;
8494 } else {
8495 trans->ctx.table->use++;
8496 nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
8497 }
3b49e2e9
PNA
8498 nft_trans_destroy(trans);
8499 break;
37082f93 8500 }
37082f93
PNA
8501 }
8502
b326dd37
PNA
8503 synchronize_rcu();
8504
a1cee076 8505 list_for_each_entry_safe_reverse(trans, next,
0854db2a 8506 &nft_net->commit_list, list) {
c7c32e72 8507 list_del(&trans->list);
b326dd37 8508 nf_tables_abort_release(trans);
37082f93
PNA
8509 }
8510
c0391b6a 8511 if (action == NFNL_ABORT_AUTOLOAD)
eb014de4
PNA
8512 nf_tables_module_autoload(net);
8513 else
8514 nf_tables_module_autoload_cleanup(net);
8515
37082f93
PNA
8516 return 0;
8517}
8518
a654de8f
PNA
8519static void nf_tables_cleanup(struct net *net)
8520{
8521 nft_validate_state_update(net, NFT_VALIDATE_SKIP);
8522}
8523
c0391b6a
PNA
8524static int nf_tables_abort(struct net *net, struct sk_buff *skb,
8525 enum nfnl_abort_action action)
71ad00c5 8526{
0854db2a 8527 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
c0391b6a 8528 int ret = __nf_tables_abort(net, action);
f102d66b 8529
0854db2a 8530 mutex_unlock(&nft_net->commit_mutex);
f102d66b
FW
8531
8532 return ret;
71ad00c5
FW
8533}
8534
74e8bcd2
PNA
8535static bool nf_tables_valid_genid(struct net *net, u32 genid)
8536{
0854db2a 8537 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
f102d66b
FW
8538 bool genid_ok;
8539
0854db2a 8540 mutex_lock(&nft_net->commit_mutex);
f102d66b 8541
0854db2a 8542 genid_ok = genid == 0 || nft_net->base_seq == genid;
f102d66b 8543 if (!genid_ok)
0854db2a 8544 mutex_unlock(&nft_net->commit_mutex);
f102d66b
FW
8545
8546 /* else, commit mutex has to be released by commit or abort function */
8547 return genid_ok;
74e8bcd2
PNA
8548}
8549
96518518
PM
8550static const struct nfnetlink_subsystem nf_tables_subsys = {
8551 .name = "nf_tables",
8552 .subsys_id = NFNL_SUBSYS_NFTABLES,
8553 .cb_count = NFT_MSG_MAX,
8554 .cb = nf_tables_cb,
0628b123
PNA
8555 .commit = nf_tables_commit,
8556 .abort = nf_tables_abort,
a654de8f 8557 .cleanup = nf_tables_cleanup,
74e8bcd2 8558 .valid_genid = nf_tables_valid_genid,
be2ab5b4 8559 .owner = THIS_MODULE,
96518518
PM
8560};
8561
7210e4e3 8562int nft_chain_validate_dependency(const struct nft_chain *chain,
32537e91 8563 enum nft_chain_types type)
7210e4e3
PNA
8564{
8565 const struct nft_base_chain *basechain;
8566
f323d954 8567 if (nft_is_base_chain(chain)) {
7210e4e3
PNA
8568 basechain = nft_base_chain(chain);
8569 if (basechain->type->type != type)
8570 return -EOPNOTSUPP;
8571 }
8572 return 0;
8573}
8574EXPORT_SYMBOL_GPL(nft_chain_validate_dependency);
8575
75e8d06d
PNA
8576int nft_chain_validate_hooks(const struct nft_chain *chain,
8577 unsigned int hook_flags)
8578{
8579 struct nft_base_chain *basechain;
8580
f323d954 8581 if (nft_is_base_chain(chain)) {
75e8d06d
PNA
8582 basechain = nft_base_chain(chain);
8583
c974a3a3 8584 if ((1 << basechain->ops.hooknum) & hook_flags)
75e8d06d
PNA
8585 return 0;
8586
8587 return -EOPNOTSUPP;
8588 }
8589
8590 return 0;
8591}
8592EXPORT_SYMBOL_GPL(nft_chain_validate_hooks);
8593
20a69341
PM
8594/*
8595 * Loop detection - walk through the ruleset beginning at the destination chain
8596 * of a new jump until either the source chain is reached (loop) or all
8597 * reachable chains have been traversed.
8598 *
8599 * The loop check is performed whenever a new jump verdict is added to an
8600 * expression or verdict map or a verdict map is bound to a new chain.
8601 */
8602
8603static int nf_tables_check_loops(const struct nft_ctx *ctx,
8604 const struct nft_chain *chain);
8605
8606static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
de70185d 8607 struct nft_set *set,
20a69341 8608 const struct nft_set_iter *iter,
de70185d 8609 struct nft_set_elem *elem)
20a69341 8610{
fe2811eb
PM
8611 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
8612 const struct nft_data *data;
8613
8614 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
8615 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
62f9c8b4
PNA
8616 return 0;
8617
fe2811eb 8618 data = nft_set_ext_data(ext);
1ca2e170 8619 switch (data->verdict.code) {
20a69341
PM
8620 case NFT_JUMP:
8621 case NFT_GOTO:
1ca2e170 8622 return nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
8623 default:
8624 return 0;
8625 }
8626}
8627
8628static int nf_tables_check_loops(const struct nft_ctx *ctx,
8629 const struct nft_chain *chain)
8630{
8631 const struct nft_rule *rule;
8632 const struct nft_expr *expr, *last;
de70185d 8633 struct nft_set *set;
20a69341
PM
8634 struct nft_set_binding *binding;
8635 struct nft_set_iter iter;
20a69341
PM
8636
8637 if (ctx->chain == chain)
8638 return -ELOOP;
8639
8640 list_for_each_entry(rule, &chain->rules, list) {
8641 nft_rule_for_each_expr(expr, last, rule) {
a654de8f
PNA
8642 struct nft_immediate_expr *priv;
8643 const struct nft_data *data;
0ca743a5
PNA
8644 int err;
8645
a654de8f 8646 if (strcmp(expr->ops->type->name, "immediate"))
20a69341
PM
8647 continue;
8648
a654de8f
PNA
8649 priv = nft_expr_priv(expr);
8650 if (priv->dreg != NFT_REG_VERDICT)
0ca743a5 8651 continue;
20a69341 8652
a654de8f 8653 data = &priv->data;
1ca2e170 8654 switch (data->verdict.code) {
20a69341
PM
8655 case NFT_JUMP:
8656 case NFT_GOTO:
1ca2e170
PM
8657 err = nf_tables_check_loops(ctx,
8658 data->verdict.chain);
20a69341
PM
8659 if (err < 0)
8660 return err;
c2168e6b 8661 break;
20a69341
PM
8662 default:
8663 break;
8664 }
8665 }
8666 }
8667
8668 list_for_each_entry(set, &ctx->table->sets, list) {
37a9cc52
PNA
8669 if (!nft_is_active_next(ctx->net, set))
8670 continue;
20a69341
PM
8671 if (!(set->flags & NFT_SET_MAP) ||
8672 set->dtype != NFT_DATA_VERDICT)
8673 continue;
8674
8675 list_for_each_entry(binding, &set->bindings, list) {
11113e19
PM
8676 if (!(binding->flags & NFT_SET_MAP) ||
8677 binding->chain != chain)
20a69341
PM
8678 continue;
8679
8588ac09 8680 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
8681 iter.skip = 0;
8682 iter.count = 0;
8683 iter.err = 0;
8684 iter.fn = nf_tables_loop_check_setelem;
8685
8686 set->ops->walk(ctx, set, &iter);
8687 if (iter.err < 0)
8688 return iter.err;
8689 }
8690 }
8691
8692 return 0;
8693}
8694
36b701fa
LGL
8695/**
8696 * nft_parse_u32_check - fetch u32 attribute and check for maximum value
8697 *
8698 * @attr: netlink attribute to fetch value from
8699 * @max: maximum value to be stored in dest
8700 * @dest: pointer to the variable
8701 *
8702 * Parse, check and store a given u32 netlink attribute into variable.
8703 * This function returns -ERANGE if the value goes over maximum value.
8704 * Otherwise a 0 is returned and the attribute value is stored in the
8705 * destination variable.
8706 */
f1d505bb 8707int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
36b701fa 8708{
09525a09 8709 u32 val;
36b701fa
LGL
8710
8711 val = ntohl(nla_get_be32(attr));
8712 if (val > max)
8713 return -ERANGE;
8714
8715 *dest = val;
8716 return 0;
8717}
8718EXPORT_SYMBOL_GPL(nft_parse_u32_check);
8719
08a01c11 8720static unsigned int nft_parse_register(const struct nlattr *attr)
b1c96ed3 8721{
49499c3e
PM
8722 unsigned int reg;
8723
8724 reg = ntohl(nla_get_be32(attr));
8725 switch (reg) {
8726 case NFT_REG_VERDICT...NFT_REG_4:
8727 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
8728 default:
8729 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
8730 }
b1c96ed3 8731}
b1c96ed3 8732
49499c3e
PM
8733/**
8734 * nft_dump_register - dump a register value to a netlink attribute
8735 *
8736 * @skb: socket buffer
8737 * @attr: attribute number
8738 * @reg: register number
8739 *
8740 * Construct a netlink attribute containing the register number. For
8741 * compatibility reasons, register numbers being a multiple of 4 are
8742 * translated to the corresponding 128 bit register numbers.
8743 */
b1c96ed3
PM
8744int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
8745{
49499c3e
PM
8746 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
8747 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
8748 else
8749 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
8750
b1c96ed3
PM
8751 return nla_put_be32(skb, attr, htonl(reg));
8752}
8753EXPORT_SYMBOL_GPL(nft_dump_register);
8754
4f16d25c 8755static int nft_validate_register_load(enum nft_registers reg, unsigned int len)
96518518 8756{
49499c3e 8757 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
96518518 8758 return -EINVAL;
d07db988
PM
8759 if (len == 0)
8760 return -EINVAL;
c593642c 8761 if (reg * NFT_REG32_SIZE + len > sizeof_field(struct nft_regs, data))
d07db988 8762 return -ERANGE;
49499c3e 8763
96518518
PM
8764 return 0;
8765}
4f16d25c
PNA
8766
8767int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len)
8768{
8769 u32 reg;
8770 int err;
8771
8772 reg = nft_parse_register(attr);
8773 err = nft_validate_register_load(reg, len);
8774 if (err < 0)
8775 return err;
8776
8777 *sreg = reg;
8778 return 0;
8779}
8780EXPORT_SYMBOL_GPL(nft_parse_register_load);
96518518 8781
345023b0
PNA
8782static int nft_validate_register_store(const struct nft_ctx *ctx,
8783 enum nft_registers reg,
8784 const struct nft_data *data,
8785 enum nft_data_types type,
8786 unsigned int len)
96518518 8787{
20a69341
PM
8788 int err;
8789
96518518
PM
8790 switch (reg) {
8791 case NFT_REG_VERDICT:
58f40ab6 8792 if (type != NFT_DATA_VERDICT)
96518518 8793 return -EINVAL;
20a69341 8794
58f40ab6 8795 if (data != NULL &&
1ca2e170
PM
8796 (data->verdict.code == NFT_GOTO ||
8797 data->verdict.code == NFT_JUMP)) {
8798 err = nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
8799 if (err < 0)
8800 return err;
20a69341
PM
8801 }
8802
96518518
PM
8803 return 0;
8804 default:
49499c3e 8805 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
27e6d201 8806 return -EINVAL;
45d9bcda
PM
8807 if (len == 0)
8808 return -EINVAL;
49499c3e 8809 if (reg * NFT_REG32_SIZE + len >
c593642c 8810 sizeof_field(struct nft_regs, data))
45d9bcda 8811 return -ERANGE;
27e6d201 8812
96518518
PM
8813 if (data != NULL && type != NFT_DATA_VALUE)
8814 return -EINVAL;
8815 return 0;
8816 }
8817}
345023b0
PNA
8818
8819int nft_parse_register_store(const struct nft_ctx *ctx,
8820 const struct nlattr *attr, u8 *dreg,
8821 const struct nft_data *data,
8822 enum nft_data_types type, unsigned int len)
8823{
8824 int err;
8825 u32 reg;
8826
8827 reg = nft_parse_register(attr);
8828 err = nft_validate_register_store(ctx, reg, data, type, len);
8829 if (err < 0)
8830 return err;
8831
8832 *dreg = reg;
8833 return 0;
8834}
8835EXPORT_SYMBOL_GPL(nft_parse_register_store);
96518518
PM
8836
8837static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
8838 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
8839 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
8840 .len = NFT_CHAIN_MAXNAMELEN - 1 },
51d70f18 8841 [NFTA_VERDICT_CHAIN_ID] = { .type = NLA_U32 },
96518518
PM
8842};
8843
8844static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
8845 struct nft_data_desc *desc, const struct nlattr *nla)
8846{
664b0f8c 8847 u8 genmask = nft_genmask_next(ctx->net);
96518518
PM
8848 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
8849 struct nft_chain *chain;
8850 int err;
8851
8cb08174
JB
8852 err = nla_parse_nested_deprecated(tb, NFTA_VERDICT_MAX, nla,
8853 nft_verdict_policy, NULL);
96518518
PM
8854 if (err < 0)
8855 return err;
8856
8857 if (!tb[NFTA_VERDICT_CODE])
8858 return -EINVAL;
1ca2e170 8859 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
96518518 8860
1ca2e170 8861 switch (data->verdict.code) {
e0abdadc 8862 default:
1ca2e170 8863 switch (data->verdict.code & NF_VERDICT_MASK) {
e0abdadc
PM
8864 case NF_ACCEPT:
8865 case NF_DROP:
8866 case NF_QUEUE:
8867 break;
8868 default:
8869 return -EINVAL;
8870 }
954d8297 8871 fallthrough;
96518518
PM
8872 case NFT_CONTINUE:
8873 case NFT_BREAK:
8874 case NFT_RETURN:
96518518
PM
8875 break;
8876 case NFT_JUMP:
8877 case NFT_GOTO:
51d70f18
PNA
8878 if (tb[NFTA_VERDICT_CHAIN]) {
8879 chain = nft_chain_lookup(ctx->net, ctx->table,
8880 tb[NFTA_VERDICT_CHAIN],
8881 genmask);
8882 } else if (tb[NFTA_VERDICT_CHAIN_ID]) {
8883 chain = nft_chain_lookup_byid(ctx->net,
8884 tb[NFTA_VERDICT_CHAIN_ID]);
8885 if (IS_ERR(chain))
8886 return PTR_ERR(chain);
8887 } else {
96518518 8888 return -EINVAL;
51d70f18
PNA
8889 }
8890
96518518
PM
8891 if (IS_ERR(chain))
8892 return PTR_ERR(chain);
f323d954 8893 if (nft_is_base_chain(chain))
96518518
PM
8894 return -EOPNOTSUPP;
8895
96518518 8896 chain->use++;
1ca2e170 8897 data->verdict.chain = chain;
96518518 8898 break;
96518518
PM
8899 }
8900
4c4ed074 8901 desc->len = sizeof(data->verdict);
96518518
PM
8902 desc->type = NFT_DATA_VERDICT;
8903 return 0;
8904}
8905
8906static void nft_verdict_uninit(const struct nft_data *data)
8907{
d0e2c7de
PNA
8908 struct nft_chain *chain;
8909 struct nft_rule *rule;
8910
1ca2e170 8911 switch (data->verdict.code) {
96518518
PM
8912 case NFT_JUMP:
8913 case NFT_GOTO:
d0e2c7de
PNA
8914 chain = data->verdict.chain;
8915 chain->use--;
8916
8917 if (!nft_chain_is_bound(chain))
8918 break;
8919
8920 chain->table->use--;
8921 list_for_each_entry(rule, &chain->rules, list)
8922 chain->use--;
8923
8924 nft_chain_del(chain);
96518518
PM
8925 break;
8926 }
8927}
8928
33d5a7b1 8929int nft_verdict_dump(struct sk_buff *skb, int type, const struct nft_verdict *v)
96518518
PM
8930{
8931 struct nlattr *nest;
8932
ae0be8de 8933 nest = nla_nest_start_noflag(skb, type);
96518518
PM
8934 if (!nest)
8935 goto nla_put_failure;
8936
33d5a7b1 8937 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(v->code)))
96518518
PM
8938 goto nla_put_failure;
8939
33d5a7b1 8940 switch (v->code) {
96518518
PM
8941 case NFT_JUMP:
8942 case NFT_GOTO:
1ca2e170 8943 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
33d5a7b1 8944 v->chain->name))
96518518
PM
8945 goto nla_put_failure;
8946 }
8947 nla_nest_end(skb, nest);
8948 return 0;
8949
8950nla_put_failure:
8951 return -1;
8952}
8953
d0a11fc3
PM
8954static int nft_value_init(const struct nft_ctx *ctx,
8955 struct nft_data *data, unsigned int size,
96518518
PM
8956 struct nft_data_desc *desc, const struct nlattr *nla)
8957{
8958 unsigned int len;
8959
8960 len = nla_len(nla);
8961 if (len == 0)
8962 return -EINVAL;
d0a11fc3 8963 if (len > size)
96518518
PM
8964 return -EOVERFLOW;
8965
d0a11fc3 8966 nla_memcpy(data->data, nla, len);
96518518
PM
8967 desc->type = NFT_DATA_VALUE;
8968 desc->len = len;
8969 return 0;
8970}
8971
8972static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
8973 unsigned int len)
8974{
8975 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
8976}
8977
8978static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
d0a11fc3 8979 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
96518518
PM
8980 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
8981};
8982
8983/**
8984 * nft_data_init - parse nf_tables data netlink attributes
8985 *
8986 * @ctx: context of the expression using the data
8987 * @data: destination struct nft_data
d0a11fc3 8988 * @size: maximum data length
96518518
PM
8989 * @desc: data description
8990 * @nla: netlink attribute containing data
8991 *
8992 * Parse the netlink data attributes and initialize a struct nft_data.
8993 * The type and length of data are returned in the data description.
8994 *
8995 * The caller can indicate that it only wants to accept data of type
8996 * NFT_DATA_VALUE by passing NULL for the ctx argument.
8997 */
d0a11fc3
PM
8998int nft_data_init(const struct nft_ctx *ctx,
8999 struct nft_data *data, unsigned int size,
96518518
PM
9000 struct nft_data_desc *desc, const struct nlattr *nla)
9001{
9002 struct nlattr *tb[NFTA_DATA_MAX + 1];
9003 int err;
9004
8cb08174
JB
9005 err = nla_parse_nested_deprecated(tb, NFTA_DATA_MAX, nla,
9006 nft_data_policy, NULL);
96518518
PM
9007 if (err < 0)
9008 return err;
9009
9010 if (tb[NFTA_DATA_VALUE])
d0a11fc3
PM
9011 return nft_value_init(ctx, data, size, desc,
9012 tb[NFTA_DATA_VALUE]);
96518518
PM
9013 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
9014 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
9015 return -EINVAL;
9016}
9017EXPORT_SYMBOL_GPL(nft_data_init);
9018
9019/**
59105446 9020 * nft_data_release - release a nft_data item
96518518
PM
9021 *
9022 * @data: struct nft_data to release
9023 * @type: type of data
9024 *
9025 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
9026 * all others need to be released by calling this function.
9027 */
59105446 9028void nft_data_release(const struct nft_data *data, enum nft_data_types type)
96518518 9029{
960bd2c2 9030 if (type < NFT_DATA_VERDICT)
96518518 9031 return;
960bd2c2 9032 switch (type) {
96518518
PM
9033 case NFT_DATA_VERDICT:
9034 return nft_verdict_uninit(data);
9035 default:
9036 WARN_ON(1);
9037 }
9038}
59105446 9039EXPORT_SYMBOL_GPL(nft_data_release);
96518518
PM
9040
9041int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
9042 enum nft_data_types type, unsigned int len)
9043{
9044 struct nlattr *nest;
9045 int err;
9046
ae0be8de 9047 nest = nla_nest_start_noflag(skb, attr);
96518518
PM
9048 if (nest == NULL)
9049 return -1;
9050
9051 switch (type) {
9052 case NFT_DATA_VALUE:
9053 err = nft_value_dump(skb, data, len);
9054 break;
9055 case NFT_DATA_VERDICT:
33d5a7b1 9056 err = nft_verdict_dump(skb, NFTA_DATA_VERDICT, &data->verdict);
96518518
PM
9057 break;
9058 default:
9059 err = -EINVAL;
9060 WARN_ON(1);
9061 }
9062
9063 nla_nest_end(skb, nest);
9064 return err;
9065}
9066EXPORT_SYMBOL_GPL(nft_data_dump);
9067
5ebe0b0e
PNA
9068int __nft_release_basechain(struct nft_ctx *ctx)
9069{
9070 struct nft_rule *rule, *nr;
9071
fa5950e4
FW
9072 if (WARN_ON(!nft_is_base_chain(ctx->chain)))
9073 return 0;
5ebe0b0e 9074
c974a3a3 9075 nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
5ebe0b0e
PNA
9076 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
9077 list_del(&rule->list);
9078 ctx->chain->use--;
bb7b40ae 9079 nf_tables_rule_release(ctx, rule);
5ebe0b0e 9080 }
1b2470e5 9081 nft_chain_del(ctx->chain);
5ebe0b0e 9082 ctx->table->use--;
43a605f2 9083 nf_tables_chain_destroy(ctx);
5ebe0b0e
PNA
9084
9085 return 0;
9086}
9087EXPORT_SYMBOL_GPL(__nft_release_basechain);
9088
00dfe9be
PNA
9089static void __nft_release_hook(struct net *net, struct nft_table *table)
9090{
9091 struct nft_chain *chain;
9092
9093 list_for_each_entry(chain, &table->chains, list)
9094 nf_tables_unregister_hook(net, table, chain);
9095}
9096
767d1216
PNA
9097static void __nft_release_hooks(struct net *net)
9098{
0854db2a 9099 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
767d1216 9100 struct nft_table *table;
767d1216 9101
0854db2a 9102 list_for_each_entry(table, &nft_net->tables, list) {
2888b080
PNA
9103 if (nft_table_has_owner(table))
9104 continue;
9105
00dfe9be 9106 __nft_release_hook(net, table);
2888b080 9107 }
767d1216
PNA
9108}
9109
fd020332 9110static void __nft_release_table(struct net *net, struct nft_table *table)
df05ef87 9111{
3b49e2e9 9112 struct nft_flowtable *flowtable, *nf;
df05ef87 9113 struct nft_chain *chain, *nc;
e5009240 9114 struct nft_object *obj, *ne;
df05ef87
PNA
9115 struct nft_rule *rule, *nr;
9116 struct nft_set *set, *ns;
9117 struct nft_ctx ctx = {
9118 .net = net,
43a605f2 9119 .family = NFPROTO_NETDEV,
df05ef87
PNA
9120 };
9121
fd020332
PNA
9122 ctx.family = table->family;
9123 ctx.table = table;
9124 list_for_each_entry(chain, &table->chains, list) {
9125 ctx.chain = chain;
9126 list_for_each_entry_safe(rule, nr, &chain->rules, list) {
9127 list_del(&rule->list);
9128 chain->use--;
9129 nf_tables_rule_release(&ctx, rule);
df05ef87 9130 }
df05ef87 9131 }
fd020332
PNA
9132 list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
9133 list_del(&flowtable->list);
9134 table->use--;
9135 nf_tables_flowtable_destroy(flowtable);
9136 }
9137 list_for_each_entry_safe(set, ns, &table->sets, list) {
9138 list_del(&set->list);
9139 table->use--;
9140 nft_set_destroy(&ctx, set);
9141 }
9142 list_for_each_entry_safe(obj, ne, &table->objects, list) {
9143 nft_obj_del(obj);
9144 table->use--;
9145 nft_obj_destroy(&ctx, obj);
9146 }
9147 list_for_each_entry_safe(chain, nc, &table->chains, list) {
9148 ctx.chain = chain;
9149 nft_chain_del(chain);
9150 table->use--;
9151 nf_tables_chain_destroy(&ctx);
9152 }
9153 list_del(&table->list);
9154 nf_tables_table_destroy(&ctx);
9155}
9156
bd1777b3 9157static void __nft_release_tables(struct net *net)
fd020332 9158{
0854db2a 9159 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
fd020332
PNA
9160 struct nft_table *table, *nt;
9161
0854db2a 9162 list_for_each_entry_safe(table, nt, &nft_net->tables, list) {
bd1777b3 9163 if (nft_table_has_owner(table))
6001a930
PNA
9164 continue;
9165
fd020332 9166 __nft_release_table(net, table);
6001a930
PNA
9167 }
9168}
9169
9170static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
9171 void *ptr)
9172{
0854db2a 9173 struct nftables_pernet *nft_net;
6001a930
PNA
9174 struct netlink_notify *n = ptr;
9175 struct nft_table *table, *nt;
9176 struct net *net = n->net;
9177 bool release = false;
9178
9179 if (event != NETLINK_URELEASE || n->protocol != NETLINK_NETFILTER)
9180 return NOTIFY_DONE;
9181
0854db2a
FW
9182 nft_net = net_generic(net, nf_tables_net_id);
9183 mutex_lock(&nft_net->commit_mutex);
9184 list_for_each_entry(table, &nft_net->tables, list) {
6001a930
PNA
9185 if (nft_table_has_owner(table) &&
9186 n->portid == table->nlpid) {
9187 __nft_release_hook(net, table);
9188 release = true;
9189 }
9190 }
9191 if (release) {
9192 synchronize_rcu();
0854db2a 9193 list_for_each_entry_safe(table, nt, &nft_net->tables, list) {
6001a930
PNA
9194 if (nft_table_has_owner(table) &&
9195 n->portid == table->nlpid)
9196 __nft_release_table(net, table);
9197 }
9198 }
0854db2a 9199 mutex_unlock(&nft_net->commit_mutex);
6001a930
PNA
9200
9201 return NOTIFY_DONE;
df05ef87
PNA
9202}
9203
6001a930
PNA
9204static struct notifier_block nft_nl_notifier = {
9205 .notifier_call = nft_rcv_nl_event,
9206};
9207
dd4cbef7
PNA
9208static int __net_init nf_tables_init_net(struct net *net)
9209{
0854db2a
FW
9210 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
9211
9212 INIT_LIST_HEAD(&nft_net->tables);
9213 INIT_LIST_HEAD(&nft_net->commit_list);
9214 INIT_LIST_HEAD(&nft_net->module_list);
9215 INIT_LIST_HEAD(&nft_net->notify_list);
9216 mutex_init(&nft_net->commit_mutex);
9217 nft_net->base_seq = 1;
9218 nft_net->validate_state = NFT_VALIDATE_SKIP;
a654de8f 9219
dd4cbef7
PNA
9220 return 0;
9221}
9222
767d1216
PNA
9223static void __net_exit nf_tables_pre_exit_net(struct net *net)
9224{
9225 __nft_release_hooks(net);
9226}
9227
dd4cbef7
PNA
9228static void __net_exit nf_tables_exit_net(struct net *net)
9229{
0854db2a
FW
9230 struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
9231
9232 mutex_lock(&nft_net->commit_mutex);
9233 if (!list_empty(&nft_net->commit_list))
c0391b6a 9234 __nf_tables_abort(net, NFNL_ABORT_NONE);
bd1777b3 9235 __nft_release_tables(net);
0854db2a
FW
9236 mutex_unlock(&nft_net->commit_mutex);
9237 WARN_ON_ONCE(!list_empty(&nft_net->tables));
9238 WARN_ON_ONCE(!list_empty(&nft_net->module_list));
9239 WARN_ON_ONCE(!list_empty(&nft_net->notify_list));
dd4cbef7
PNA
9240}
9241
99633ab2 9242static struct pernet_operations nf_tables_net_ops = {
767d1216
PNA
9243 .init = nf_tables_init_net,
9244 .pre_exit = nf_tables_pre_exit_net,
9245 .exit = nf_tables_exit_net,
0854db2a
FW
9246 .id = &nf_tables_net_id,
9247 .size = sizeof(struct nftables_pernet),
99633ab2
PNA
9248};
9249
96518518
PM
9250static int __init nf_tables_module_init(void)
9251{
9252 int err;
9253
d209df3e
FW
9254 err = register_pernet_subsys(&nf_tables_net_ops);
9255 if (err < 0)
9256 return err;
9257
9258 err = nft_chain_filter_init();
9259 if (err < 0)
6001a930 9260 goto err_chain_filter;
02c7b25e 9261
96518518
PM
9262 err = nf_tables_core_module_init();
9263 if (err < 0)
6001a930 9264 goto err_core_module;
96518518 9265
d209df3e 9266 err = register_netdevice_notifier(&nf_tables_flowtable_notifier);
96518518 9267 if (err < 0)
6001a930 9268 goto err_netdev_notifier;
96518518 9269
4d44175a
FW
9270 err = rhltable_init(&nft_objname_ht, &nft_objname_ht_params);
9271 if (err < 0)
6001a930 9272 goto err_rht_objname;
4d44175a 9273
06d392cb 9274 err = nft_offload_init();
9275 if (err < 0)
6001a930
PNA
9276 goto err_offload;
9277
9278 err = netlink_register_notifier(&nft_nl_notifier);
9279 if (err < 0)
9280 goto err_netlink_notifier;
06d392cb 9281
d209df3e
FW
9282 /* must be last */
9283 err = nfnetlink_subsys_register(&nf_tables_subsys);
9284 if (err < 0)
6001a930 9285 goto err_nfnl_subsys;
3b49e2e9 9286
c1deb065 9287 nft_chain_route_init();
3474a2c6 9288
d209df3e 9289 return err;
6001a930
PNA
9290
9291err_nfnl_subsys:
9292 netlink_unregister_notifier(&nft_nl_notifier);
9293err_netlink_notifier:
06d392cb 9294 nft_offload_exit();
6001a930 9295err_offload:
4d44175a 9296 rhltable_destroy(&nft_objname_ht);
6001a930 9297err_rht_objname:
d209df3e 9298 unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
6001a930 9299err_netdev_notifier:
96518518 9300 nf_tables_core_module_exit();
6001a930 9301err_core_module:
d209df3e 9302 nft_chain_filter_fini();
6001a930 9303err_chain_filter:
d209df3e 9304 unregister_pernet_subsys(&nf_tables_net_ops);
96518518
PM
9305 return err;
9306}
9307
9308static void __exit nf_tables_module_exit(void)
9309{
9310 nfnetlink_subsys_unregister(&nf_tables_subsys);
6001a930 9311 netlink_unregister_notifier(&nft_nl_notifier);
06d392cb 9312 nft_offload_exit();
3b49e2e9 9313 unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
0a2cf5ee 9314 nft_chain_filter_fini();
c1deb065 9315 nft_chain_route_fini();
71ad00c5 9316 unregister_pernet_subsys(&nf_tables_net_ops);
0935d558 9317 cancel_work_sync(&trans_destroy_work);
1b1bc49c 9318 rcu_barrier();
4d44175a 9319 rhltable_destroy(&nft_objname_ht);
96518518 9320 nf_tables_core_module_exit();
96518518
PM
9321}
9322
9323module_init(nf_tables_module_init);
9324module_exit(nf_tables_module_exit);
9325
9326MODULE_LICENSE("GPL");
9327MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
9328MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);