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