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