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