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