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