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