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