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