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