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