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