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