]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - net/netfilter/nf_tables_api.c
netfilter: nf_tables: pass context to object destroy indirection
[mirror_ubuntu-hirsute-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
PM
3361 INIT_LIST_HEAD(&set->bindings);
3362 set->ops = ops;
3363 set->ktype = ktype;
c50b960c 3364 set->klen = desc.klen;
20a69341 3365 set->dtype = dtype;
8aeff920 3366 set->objtype = objtype;
c50b960c 3367 set->dlen = desc.dlen;
20a69341 3368 set->flags = flags;
c50b960c 3369 set->size = desc.size;
9363dc4b 3370 set->policy = policy;
e6d8ecac
CFG
3371 set->udlen = udlen;
3372 set->udata = udata;
761da293
PM
3373 set->timeout = timeout;
3374 set->gc_int = gc_int;
3ecbfd65 3375 set->handle = nf_tables_alloc_handle(table);
20a69341 3376
c50b960c 3377 err = ops->init(set, &desc, nla);
20a69341 3378 if (err < 0)
2f6adf48 3379 goto err3;
20a69341 3380
958bee14 3381 err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
20a69341 3382 if (err < 0)
2f6adf48 3383 goto err4;
20a69341 3384
e688a7f8 3385 list_add_tail_rcu(&set->list, &table->sets);
4fefee57 3386 table->use++;
20a69341
PM
3387 return 0;
3388
2f6adf48 3389err4:
c17c3cdf 3390 ops->destroy(set);
2f6adf48
FW
3391err3:
3392 kfree(set->name);
20a69341 3393err2:
1ff75a3e 3394 kvfree(set);
20a69341 3395err1:
71cc0873 3396 module_put(to_set_type(ops)->owner);
20a69341
PM
3397 return err;
3398}
3399
958bee14 3400static void nft_set_destroy(struct nft_set *set)
20a69341 3401{
20a69341 3402 set->ops->destroy(set);
71cc0873 3403 module_put(to_set_type(set->ops)->owner);
38745490 3404 kfree(set->name);
1ff75a3e 3405 kvfree(set);
20a69341
PM
3406}
3407
958bee14
PNA
3408static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
3409{
e688a7f8 3410 list_del_rcu(&set->list);
31f8441c 3411 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC);
958bee14
PNA
3412 nft_set_destroy(set);
3413}
3414
633c9a84
PNA
3415static int nf_tables_delset(struct net *net, struct sock *nlsk,
3416 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3417 const struct nlattr * const nla[],
3418 struct netlink_ext_ack *extack)
20a69341 3419{
c9c8e485 3420 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3421 u8 genmask = nft_genmask_next(net);
36dd1bcc 3422 const struct nlattr *attr;
20a69341
PM
3423 struct nft_set *set;
3424 struct nft_ctx ctx;
3425 int err;
3426
ec2c9935
PM
3427 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
3428 return -EAFNOSUPPORT;
20a69341
PM
3429 if (nla[NFTA_SET_TABLE] == NULL)
3430 return -EINVAL;
3431
36dd1bcc
PNA
3432 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, extack,
3433 genmask);
20a69341
PM
3434 if (err < 0)
3435 return err;
3436
36dd1bcc
PNA
3437 if (nla[NFTA_SET_HANDLE]) {
3438 attr = nla[NFTA_SET_HANDLE];
3439 set = nft_set_lookup_byhandle(ctx.table, attr, genmask);
3440 } else {
3441 attr = nla[NFTA_SET_NAME];
3442 set = nft_set_lookup(ctx.table, attr, genmask);
3443 }
a8278400 3444
36dd1bcc
PNA
3445 if (IS_ERR(set)) {
3446 NL_SET_BAD_ATTR(extack, attr);
3447 return PTR_ERR(set);
3448 }
a8278400 3449 if (!list_empty(&set->bindings) ||
36dd1bcc
PNA
3450 (nlh->nlmsg_flags & NLM_F_NONREC && atomic_read(&set->nelems) > 0)) {
3451 NL_SET_BAD_ATTR(extack, attr);
20a69341 3452 return -EBUSY;
36dd1bcc 3453 }
20a69341 3454
ee01d542 3455 return nft_delset(&ctx, set);
20a69341
PM
3456}
3457
3458static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
de70185d 3459 struct nft_set *set,
20a69341 3460 const struct nft_set_iter *iter,
de70185d 3461 struct nft_set_elem *elem)
20a69341 3462{
fe2811eb 3463 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3464 enum nft_registers dreg;
3465
3466 dreg = nft_type_to_reg(set->dtype);
1ec10212
PM
3467 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
3468 set->dtype == NFT_DATA_VERDICT ?
3469 NFT_DATA_VERDICT : NFT_DATA_VALUE,
3470 set->dlen);
20a69341
PM
3471}
3472
3473int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
3474 struct nft_set_binding *binding)
3475{
3476 struct nft_set_binding *i;
3477 struct nft_set_iter iter;
3478
408070d6 3479 if (!list_empty(&set->bindings) && nft_set_is_anonymous(set))
20a69341
PM
3480 return -EBUSY;
3481
11113e19 3482 if (binding->flags & NFT_SET_MAP) {
20a69341
PM
3483 /* If the set is already bound to the same chain all
3484 * jumps are already validated for that chain.
3485 */
3486 list_for_each_entry(i, &set->bindings, list) {
a4684402 3487 if (i->flags & NFT_SET_MAP &&
11113e19 3488 i->chain == binding->chain)
20a69341
PM
3489 goto bind;
3490 }
3491
8588ac09 3492 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
3493 iter.skip = 0;
3494 iter.count = 0;
3495 iter.err = 0;
3496 iter.fn = nf_tables_bind_check_setelem;
3497
3498 set->ops->walk(ctx, set, &iter);
a02f4248 3499 if (iter.err < 0)
20a69341 3500 return iter.err;
20a69341
PM
3501 }
3502bind:
3503 binding->chain = ctx->chain;
e688a7f8 3504 list_add_tail_rcu(&binding->list, &set->bindings);
20a69341
PM
3505 return 0;
3506}
63aea290 3507EXPORT_SYMBOL_GPL(nf_tables_bind_set);
20a69341
PM
3508
3509void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
3510 struct nft_set_binding *binding)
3511{
e688a7f8 3512 list_del_rcu(&binding->list);
20a69341 3513
408070d6 3514 if (list_empty(&set->bindings) && nft_set_is_anonymous(set) &&
37a9cc52 3515 nft_is_active(ctx->net, set))
20a69341
PM
3516 nf_tables_set_destroy(ctx, set);
3517}
63aea290 3518EXPORT_SYMBOL_GPL(nf_tables_unbind_set);
20a69341 3519
3ac4c07a
PM
3520const struct nft_set_ext_type nft_set_ext_types[] = {
3521 [NFT_SET_EXT_KEY] = {
7d740264 3522 .align = __alignof__(u32),
3ac4c07a
PM
3523 },
3524 [NFT_SET_EXT_DATA] = {
7d740264 3525 .align = __alignof__(u32),
3ac4c07a 3526 },
f25ad2e9
PM
3527 [NFT_SET_EXT_EXPR] = {
3528 .align = __alignof__(struct nft_expr),
3529 },
8aeff920
PNA
3530 [NFT_SET_EXT_OBJREF] = {
3531 .len = sizeof(struct nft_object *),
3532 .align = __alignof__(struct nft_object *),
3533 },
3ac4c07a
PM
3534 [NFT_SET_EXT_FLAGS] = {
3535 .len = sizeof(u8),
3536 .align = __alignof__(u8),
3537 },
c3e1b005
PM
3538 [NFT_SET_EXT_TIMEOUT] = {
3539 .len = sizeof(u64),
3540 .align = __alignof__(u64),
3541 },
3542 [NFT_SET_EXT_EXPIRATION] = {
8e1102d5
FW
3543 .len = sizeof(u64),
3544 .align = __alignof__(u64),
c3e1b005 3545 },
68e942e8
PM
3546 [NFT_SET_EXT_USERDATA] = {
3547 .len = sizeof(struct nft_userdata),
3548 .align = __alignof__(struct nft_userdata),
3549 },
3ac4c07a
PM
3550};
3551EXPORT_SYMBOL_GPL(nft_set_ext_types);
3552
20a69341
PM
3553/*
3554 * Set elements
3555 */
3556
3557static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
3558 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
3559 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
3560 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
c3e1b005 3561 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
68e942e8
PM
3562 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY,
3563 .len = NFT_USERDATA_MAXLEN },
467697d2
FW
3564 [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED },
3565 [NFTA_SET_ELEM_OBJREF] = { .type = NLA_STRING },
20a69341
PM
3566};
3567
3568static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
b2fbd044
LZ
3569 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING,
3570 .len = NFT_TABLE_MAXNAMELEN - 1 },
3571 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING,
3572 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341 3573 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
958bee14 3574 [NFTA_SET_ELEM_LIST_SET_ID] = { .type = NLA_U32 },
20a69341
PM
3575};
3576
633c9a84 3577static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
3578 const struct sk_buff *skb,
3579 const struct nlmsghdr *nlh,
f2a6d766 3580 const struct nlattr * const nla[],
36dd1bcc 3581 struct netlink_ext_ack *extack,
f2a6d766 3582 u8 genmask)
20a69341
PM
3583{
3584 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
98319cb9 3585 int family = nfmsg->nfgen_family;
7c95f6d8 3586 struct nft_table *table;
20a69341 3587
cac20fcd
PNA
3588 table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family,
3589 genmask);
36dd1bcc
PNA
3590 if (IS_ERR(table)) {
3591 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]);
20a69341 3592 return PTR_ERR(table);
36dd1bcc 3593 }
20a69341 3594
98319cb9 3595 nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla);
20a69341
PM
3596 return 0;
3597}
3598
3599static int nf_tables_fill_setelem(struct sk_buff *skb,
3600 const struct nft_set *set,
3601 const struct nft_set_elem *elem)
3602{
fe2811eb 3603 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3604 unsigned char *b = skb_tail_pointer(skb);
3605 struct nlattr *nest;
3606
3607 nest = nla_nest_start(skb, NFTA_LIST_ELEM);
3608 if (nest == NULL)
3609 goto nla_put_failure;
3610
fe2811eb
PM
3611 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, nft_set_ext_key(ext),
3612 NFT_DATA_VALUE, set->klen) < 0)
20a69341
PM
3613 goto nla_put_failure;
3614
fe2811eb
PM
3615 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3616 nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
20a69341
PM
3617 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
3618 set->dlen) < 0)
3619 goto nla_put_failure;
3620
f25ad2e9
PM
3621 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
3622 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
3623 goto nla_put_failure;
3624
8aeff920
PNA
3625 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3626 nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
3627 (*nft_set_ext_obj(ext))->name) < 0)
3628 goto nla_put_failure;
3629
fe2811eb
PM
3630 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
3631 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
3632 htonl(*nft_set_ext_flags(ext))))
3633 goto nla_put_failure;
20a69341 3634
c3e1b005
PM
3635 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
3636 nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
8e1102d5 3637 nf_jiffies64_to_msecs(*nft_set_ext_timeout(ext)),
b46f6ded 3638 NFTA_SET_ELEM_PAD))
c3e1b005
PM
3639 goto nla_put_failure;
3640
3641 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
8e1102d5 3642 u64 expires, now = get_jiffies_64();
c3e1b005
PM
3643
3644 expires = *nft_set_ext_expiration(ext);
8e1102d5 3645 if (time_before64(now, expires))
c3e1b005
PM
3646 expires -= now;
3647 else
3648 expires = 0;
3649
3650 if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
8e1102d5 3651 nf_jiffies64_to_msecs(expires),
b46f6ded 3652 NFTA_SET_ELEM_PAD))
c3e1b005
PM
3653 goto nla_put_failure;
3654 }
3655
68e942e8
PM
3656 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
3657 struct nft_userdata *udata;
3658
3659 udata = nft_set_ext_userdata(ext);
3660 if (nla_put(skb, NFTA_SET_ELEM_USERDATA,
3661 udata->len + 1, udata->data))
3662 goto nla_put_failure;
3663 }
3664
20a69341
PM
3665 nla_nest_end(skb, nest);
3666 return 0;
3667
3668nla_put_failure:
3669 nlmsg_trim(skb, b);
3670 return -EMSGSIZE;
3671}
3672
3673struct nft_set_dump_args {
3674 const struct netlink_callback *cb;
3675 struct nft_set_iter iter;
3676 struct sk_buff *skb;
3677};
3678
3679static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
de70185d 3680 struct nft_set *set,
20a69341 3681 const struct nft_set_iter *iter,
de70185d 3682 struct nft_set_elem *elem)
20a69341
PM
3683{
3684 struct nft_set_dump_args *args;
3685
3686 args = container_of(iter, struct nft_set_dump_args, iter);
3687 return nf_tables_fill_setelem(args->skb, set, elem);
3688}
3689
fa803605
LZ
3690struct nft_set_dump_ctx {
3691 const struct nft_set *set;
3692 struct nft_ctx ctx;
3693};
3694
20a69341
PM
3695static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3696{
fa803605 3697 struct nft_set_dump_ctx *dump_ctx = cb->data;
633c9a84 3698 struct net *net = sock_net(skb->sk);
fa803605 3699 struct nft_table *table;
de70185d 3700 struct nft_set *set;
20a69341 3701 struct nft_set_dump_args args;
fa803605 3702 bool set_found = false;
20a69341
PM
3703 struct nfgenmsg *nfmsg;
3704 struct nlmsghdr *nlh;
3705 struct nlattr *nest;
3706 u32 portid, seq;
fa803605 3707 int event;
20a69341 3708
fa803605 3709 rcu_read_lock();
36596dad
PNA
3710 list_for_each_entry_rcu(table, &net->nft.tables, list) {
3711 if (dump_ctx->ctx.family != NFPROTO_UNSPEC &&
98319cb9 3712 dump_ctx->ctx.family != table->family)
fa803605 3713 continue;
20a69341 3714
36596dad
PNA
3715 if (table != dump_ctx->ctx.table)
3716 continue;
20a69341 3717
36596dad
PNA
3718 list_for_each_entry_rcu(set, &table->sets, list) {
3719 if (set == dump_ctx->set) {
3720 set_found = true;
3721 break;
fa803605 3722 }
fa803605
LZ
3723 }
3724 break;
3725 }
3726
3727 if (!set_found) {
3728 rcu_read_unlock();
3729 return -ENOENT;
3730 }
20a69341 3731
dedb67c4 3732 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSETELEM);
20a69341
PM
3733 portid = NETLINK_CB(cb->skb).portid;
3734 seq = cb->nlh->nlmsg_seq;
3735
3736 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3737 NLM_F_MULTI);
3738 if (nlh == NULL)
3739 goto nla_put_failure;
3740
3741 nfmsg = nlmsg_data(nlh);
98319cb9 3742 nfmsg->nfgen_family = table->family;
20a69341 3743 nfmsg->version = NFNETLINK_V0;
fa803605 3744 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
20a69341 3745
fa803605 3746 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, table->name))
20a69341
PM
3747 goto nla_put_failure;
3748 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
3749 goto nla_put_failure;
3750
3751 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3752 if (nest == NULL)
3753 goto nla_put_failure;
3754
8588ac09
PNA
3755 args.cb = cb;
3756 args.skb = skb;
fa803605 3757 args.iter.genmask = nft_genmask_cur(net);
8588ac09
PNA
3758 args.iter.skip = cb->args[0];
3759 args.iter.count = 0;
3760 args.iter.err = 0;
3761 args.iter.fn = nf_tables_dump_setelem;
fa803605
LZ
3762 set->ops->walk(&dump_ctx->ctx, set, &args.iter);
3763 rcu_read_unlock();
20a69341
PM
3764
3765 nla_nest_end(skb, nest);
3766 nlmsg_end(skb, nlh);
3767
3768 if (args.iter.err && args.iter.err != -EMSGSIZE)
3769 return args.iter.err;
3770 if (args.iter.count == cb->args[0])
3771 return 0;
3772
3773 cb->args[0] = args.iter.count;
3774 return skb->len;
3775
3776nla_put_failure:
fa803605 3777 rcu_read_unlock();
20a69341
PM
3778 return -ENOSPC;
3779}
3780
fa803605
LZ
3781static int nf_tables_dump_set_done(struct netlink_callback *cb)
3782{
3783 kfree(cb->data);
3784 return 0;
3785}
3786
d60ce62f
AB
3787static int nf_tables_fill_setelem_info(struct sk_buff *skb,
3788 const struct nft_ctx *ctx, u32 seq,
3789 u32 portid, int event, u16 flags,
3790 const struct nft_set *set,
3791 const struct nft_set_elem *elem)
3792{
3793 struct nfgenmsg *nfmsg;
3794 struct nlmsghdr *nlh;
3795 struct nlattr *nest;
3796 int err;
3797
dedb67c4 3798 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
d60ce62f
AB
3799 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3800 flags);
3801 if (nlh == NULL)
3802 goto nla_put_failure;
3803
3804 nfmsg = nlmsg_data(nlh);
36596dad 3805 nfmsg->nfgen_family = ctx->family;
d60ce62f 3806 nfmsg->version = NFNETLINK_V0;
84d7fce6 3807 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
d60ce62f
AB
3808
3809 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
3810 goto nla_put_failure;
3811 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
3812 goto nla_put_failure;
3813
3814 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3815 if (nest == NULL)
3816 goto nla_put_failure;
3817
3818 err = nf_tables_fill_setelem(skb, set, elem);
3819 if (err < 0)
3820 goto nla_put_failure;
3821
3822 nla_nest_end(skb, nest);
3823
053c095a
JB
3824 nlmsg_end(skb, nlh);
3825 return 0;
d60ce62f
AB
3826
3827nla_put_failure:
3828 nlmsg_trim(skb, nlh);
3829 return -1;
3830}
3831
ba0e4d99
PNA
3832static int nft_setelem_parse_flags(const struct nft_set *set,
3833 const struct nlattr *attr, u32 *flags)
3834{
3835 if (attr == NULL)
3836 return 0;
3837
3838 *flags = ntohl(nla_get_be32(attr));
3839 if (*flags & ~NFT_SET_ELEM_INTERVAL_END)
3840 return -EINVAL;
3841 if (!(set->flags & NFT_SET_INTERVAL) &&
3842 *flags & NFT_SET_ELEM_INTERVAL_END)
3843 return -EINVAL;
3844
3845 return 0;
3846}
3847
3848static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3849 const struct nlattr *attr)
3850{
3851 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3852 const struct nft_set_ext *ext;
3853 struct nft_data_desc desc;
3854 struct nft_set_elem elem;
3855 struct sk_buff *skb;
3856 uint32_t flags = 0;
3857 void *priv;
3858 int err;
3859
3860 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
3861 nft_set_elem_policy, NULL);
3862 if (err < 0)
3863 return err;
3864
3865 if (!nla[NFTA_SET_ELEM_KEY])
3866 return -EINVAL;
3867
3868 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
3869 if (err < 0)
3870 return err;
3871
3872 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
3873 nla[NFTA_SET_ELEM_KEY]);
3874 if (err < 0)
3875 return err;
3876
3877 err = -EINVAL;
3878 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
3879 return err;
3880
3881 priv = set->ops->get(ctx->net, set, &elem, flags);
3882 if (IS_ERR(priv))
3883 return PTR_ERR(priv);
3884
3885 elem.priv = priv;
3886 ext = nft_set_elem_ext(set, &elem);
3887
3888 err = -ENOMEM;
d9adf22a 3889 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
ba0e4d99
PNA
3890 if (skb == NULL)
3891 goto err1;
3892
3893 err = nf_tables_fill_setelem_info(skb, ctx, ctx->seq, ctx->portid,
3894 NFT_MSG_NEWSETELEM, 0, set, &elem);
3895 if (err < 0)
3896 goto err2;
3897
3898 err = nfnetlink_unicast(skb, ctx->net, ctx->portid, MSG_DONTWAIT);
3899 /* This avoids a loop in nfnetlink. */
3900 if (err < 0)
3901 goto err1;
3902
3903 return 0;
3904err2:
3905 kfree_skb(skb);
3906err1:
3907 /* this avoids a loop in nfnetlink. */
3908 return err == -EAGAIN ? -ENOBUFS : err;
3909}
3910
d9adf22a 3911/* called with rcu_read_lock held */
ba0e4d99
PNA
3912static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
3913 struct sk_buff *skb, const struct nlmsghdr *nlh,
3914 const struct nlattr * const nla[],
3915 struct netlink_ext_ack *extack)
3916{
3917 u8 genmask = nft_genmask_cur(net);
3918 struct nft_set *set;
3919 struct nlattr *attr;
3920 struct nft_ctx ctx;
3921 int rem, err = 0;
3922
36dd1bcc
PNA
3923 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
3924 genmask);
ba0e4d99
PNA
3925 if (err < 0)
3926 return err;
3927
cac20fcd 3928 set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
ba0e4d99
PNA
3929 if (IS_ERR(set))
3930 return PTR_ERR(set);
3931
3932 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3933 struct netlink_dump_control c = {
3934 .dump = nf_tables_dump_set,
3935 .done = nf_tables_dump_set_done,
d9adf22a 3936 .module = THIS_MODULE,
ba0e4d99
PNA
3937 };
3938 struct nft_set_dump_ctx *dump_ctx;
3939
d9adf22a 3940 dump_ctx = kmalloc(sizeof(*dump_ctx), GFP_ATOMIC);
ba0e4d99
PNA
3941 if (!dump_ctx)
3942 return -ENOMEM;
3943
3944 dump_ctx->set = set;
3945 dump_ctx->ctx = ctx;
3946
3947 c.data = dump_ctx;
d9adf22a 3948 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
ba0e4d99
PNA
3949 }
3950
3951 if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
3952 return -EINVAL;
3953
3954 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3955 err = nft_get_set_elem(&ctx, set, attr);
3956 if (err < 0)
3957 break;
3958 }
3959
3960 return err;
3961}
3962
25e94a99
PNA
3963static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
3964 const struct nft_set *set,
3965 const struct nft_set_elem *elem,
3966 int event, u16 flags)
d60ce62f 3967{
128ad332
PNA
3968 struct net *net = ctx->net;
3969 u32 portid = ctx->portid;
d60ce62f
AB
3970 struct sk_buff *skb;
3971 int err;
3972
128ad332 3973 if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 3974 return;
d60ce62f 3975
d60ce62f
AB
3976 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3977 if (skb == NULL)
3978 goto err;
3979
3980 err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
3981 set, elem);
3982 if (err < 0) {
3983 kfree_skb(skb);
3984 goto err;
3985 }
3986
25e94a99
PNA
3987 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
3988 GFP_KERNEL);
3989 return;
d60ce62f 3990err:
25e94a99 3991 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
d60ce62f
AB
3992}
3993
60319eb1
PNA
3994static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3995 int msg_type,
3996 struct nft_set *set)
3997{
3998 struct nft_trans *trans;
3999
4000 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_elem));
4001 if (trans == NULL)
4002 return NULL;
4003
4004 nft_trans_elem_set(trans) = set;
4005 return trans;
4006}
4007
22fe54d5
PM
4008void *nft_set_elem_init(const struct nft_set *set,
4009 const struct nft_set_ext_tmpl *tmpl,
49499c3e 4010 const u32 *key, const u32 *data,
22fe54d5 4011 u64 timeout, gfp_t gfp)
fe2811eb
PM
4012{
4013 struct nft_set_ext *ext;
4014 void *elem;
4015
4016 elem = kzalloc(set->ops->elemsize + tmpl->len, gfp);
4017 if (elem == NULL)
4018 return NULL;
4019
4020 ext = nft_set_elem_ext(set, elem);
4021 nft_set_ext_init(ext, tmpl);
4022
4023 memcpy(nft_set_ext_key(ext), key, set->klen);
4024 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4025 memcpy(nft_set_ext_data(ext), data, set->dlen);
c3e1b005
PM
4026 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
4027 *nft_set_ext_expiration(ext) =
8e1102d5 4028 get_jiffies_64() + timeout;
c3e1b005
PM
4029 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
4030 *nft_set_ext_timeout(ext) = timeout;
fe2811eb
PM
4031
4032 return elem;
4033}
4034
61f9e292
LZ
4035void nft_set_elem_destroy(const struct nft_set *set, void *elem,
4036 bool destroy_expr)
61edafbb
PM
4037{
4038 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
4039
59105446 4040 nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
61edafbb 4041 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
59105446 4042 nft_data_release(nft_set_ext_data(ext), set->dtype);
61f9e292 4043 if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
f25ad2e9 4044 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
8aeff920
PNA
4045 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4046 (*nft_set_ext_obj(ext))->use--;
61edafbb
PM
4047 kfree(elem);
4048}
4049EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
4050
59105446
PNA
4051/* Only called from commit path, nft_set_elem_deactivate() already deals with
4052 * the refcounting from the preparation phase.
4053 */
4054static void nf_tables_set_elem_destroy(const struct nft_set *set, void *elem)
4055{
4056 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
4057
4058 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
4059 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
4060 kfree(elem);
4061}
4062
60319eb1 4063static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
c016c7e4 4064 const struct nlattr *attr, u32 nlmsg_flags)
20a69341
PM
4065{
4066 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
8aeff920 4067 u8 genmask = nft_genmask_next(ctx->net);
20a69341 4068 struct nft_data_desc d1, d2;
fe2811eb 4069 struct nft_set_ext_tmpl tmpl;
c016c7e4 4070 struct nft_set_ext *ext, *ext2;
20a69341
PM
4071 struct nft_set_elem elem;
4072 struct nft_set_binding *binding;
8aeff920 4073 struct nft_object *obj = NULL;
68e942e8 4074 struct nft_userdata *udata;
fe2811eb 4075 struct nft_data data;
20a69341 4076 enum nft_registers dreg;
60319eb1 4077 struct nft_trans *trans;
0e9091d6 4078 u32 flags = 0;
c3e1b005 4079 u64 timeout;
68e942e8 4080 u8 ulen;
20a69341
PM
4081 int err;
4082
4083 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
fceb6435 4084 nft_set_elem_policy, NULL);
20a69341
PM
4085 if (err < 0)
4086 return err;
4087
4088 if (nla[NFTA_SET_ELEM_KEY] == NULL)
4089 return -EINVAL;
4090
fe2811eb
PM
4091 nft_set_ext_prepare(&tmpl);
4092
0e9091d6
PNA
4093 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
4094 if (err < 0)
4095 return err;
4096 if (flags != 0)
4097 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
20a69341
PM
4098
4099 if (set->flags & NFT_SET_MAP) {
4100 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
fe2811eb 4101 !(flags & NFT_SET_ELEM_INTERVAL_END))
20a69341 4102 return -EINVAL;
bd7fc645 4103 if (nla[NFTA_SET_ELEM_DATA] != NULL &&
fe2811eb 4104 flags & NFT_SET_ELEM_INTERVAL_END)
bd7fc645 4105 return -EINVAL;
20a69341
PM
4106 } else {
4107 if (nla[NFTA_SET_ELEM_DATA] != NULL)
4108 return -EINVAL;
4109 }
4110
c3e1b005
PM
4111 timeout = 0;
4112 if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
4113 if (!(set->flags & NFT_SET_TIMEOUT))
4114 return -EINVAL;
8e1102d5
FW
4115 err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_TIMEOUT],
4116 &timeout);
4117 if (err)
4118 return err;
c3e1b005
PM
4119 } else if (set->flags & NFT_SET_TIMEOUT) {
4120 timeout = set->timeout;
4121 }
4122
7d740264 4123 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
d0a11fc3 4124 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
4125 if (err < 0)
4126 goto err1;
4127 err = -EINVAL;
4128 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
4129 goto err2;
4130
7d740264 4131 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
c3e1b005
PM
4132 if (timeout > 0) {
4133 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
4134 if (timeout != set->timeout)
4135 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
4136 }
fe2811eb 4137
8aeff920
PNA
4138 if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
4139 if (!(set->flags & NFT_SET_OBJECT)) {
4140 err = -EINVAL;
4141 goto err2;
4142 }
cac20fcd
PNA
4143 obj = nft_obj_lookup(ctx->table, nla[NFTA_SET_ELEM_OBJREF],
4144 set->objtype, genmask);
8aeff920
PNA
4145 if (IS_ERR(obj)) {
4146 err = PTR_ERR(obj);
4147 goto err2;
4148 }
4149 nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
4150 }
4151
20a69341 4152 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
d0a11fc3
PM
4153 err = nft_data_init(ctx, &data, sizeof(data), &d2,
4154 nla[NFTA_SET_ELEM_DATA]);
20a69341
PM
4155 if (err < 0)
4156 goto err2;
4157
4158 err = -EINVAL;
4159 if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
4160 goto err3;
4161
4162 dreg = nft_type_to_reg(set->dtype);
4163 list_for_each_entry(binding, &set->bindings, list) {
4164 struct nft_ctx bind_ctx = {
58c78e10 4165 .net = ctx->net,
36596dad 4166 .family = ctx->family,
20a69341 4167 .table = ctx->table,
7c95f6d8 4168 .chain = (struct nft_chain *)binding->chain,
20a69341
PM
4169 };
4170
11113e19
PM
4171 if (!(binding->flags & NFT_SET_MAP))
4172 continue;
4173
1ec10212
PM
4174 err = nft_validate_register_store(&bind_ctx, dreg,
4175 &data,
4176 d2.type, d2.len);
20a69341
PM
4177 if (err < 0)
4178 goto err3;
a654de8f
PNA
4179
4180 if (d2.type == NFT_DATA_VERDICT &&
4181 (data.verdict.code == NFT_GOTO ||
4182 data.verdict.code == NFT_JUMP))
4183 nft_validate_state_update(ctx->net,
4184 NFT_VALIDATE_NEED);
20a69341 4185 }
fe2811eb 4186
7d740264 4187 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
20a69341
PM
4188 }
4189
68e942e8
PM
4190 /* The full maximum length of userdata can exceed the maximum
4191 * offset value (U8_MAX) for following extensions, therefor it
4192 * must be the last extension added.
4193 */
4194 ulen = 0;
4195 if (nla[NFTA_SET_ELEM_USERDATA] != NULL) {
4196 ulen = nla_len(nla[NFTA_SET_ELEM_USERDATA]);
4197 if (ulen > 0)
4198 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_USERDATA,
4199 ulen);
4200 }
4201
fe2811eb 4202 err = -ENOMEM;
7d740264 4203 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
c3e1b005 4204 timeout, GFP_KERNEL);
fe2811eb
PM
4205 if (elem.priv == NULL)
4206 goto err3;
4207
4208 ext = nft_set_elem_ext(set, elem.priv);
4209 if (flags)
4210 *nft_set_ext_flags(ext) = flags;
68e942e8
PM
4211 if (ulen > 0) {
4212 udata = nft_set_ext_userdata(ext);
4213 udata->len = ulen - 1;
4214 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
4215 }
8aeff920
PNA
4216 if (obj) {
4217 *nft_set_ext_obj(ext) = obj;
4218 obj->use++;
4219 }
fe2811eb 4220
60319eb1
PNA
4221 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
4222 if (trans == NULL)
fe2811eb 4223 goto err4;
60319eb1 4224
69086658 4225 ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
c016c7e4
PNA
4226 err = set->ops->insert(ctx->net, set, &elem, &ext2);
4227 if (err) {
4228 if (err == -EEXIST) {
9744a6fc
PNA
4229 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
4230 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
4231 nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
f0dfd7a2
CIK
4232 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF)) {
4233 err = -EBUSY;
4234 goto err5;
4235 }
8aeff920
PNA
4236 if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
4237 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
4238 memcmp(nft_set_ext_data(ext),
4239 nft_set_ext_data(ext2), set->dlen) != 0) ||
4240 (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
4241 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
4242 *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
c016c7e4
PNA
4243 err = -EBUSY;
4244 else if (!(nlmsg_flags & NLM_F_EXCL))
4245 err = 0;
4246 }
fe2811eb 4247 goto err5;
c016c7e4 4248 }
20a69341 4249
35d0ac90
PNA
4250 if (set->size &&
4251 !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) {
4252 err = -ENFILE;
4253 goto err6;
4254 }
4255
60319eb1 4256 nft_trans_elem(trans) = elem;
46bbafce 4257 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
20a69341
PM
4258 return 0;
4259
35d0ac90 4260err6:
5cb82a38 4261 set->ops->remove(ctx->net, set, &elem);
fe2811eb 4262err5:
60319eb1 4263 kfree(trans);
fe2811eb
PM
4264err4:
4265 kfree(elem.priv);
20a69341
PM
4266err3:
4267 if (nla[NFTA_SET_ELEM_DATA] != NULL)
59105446 4268 nft_data_release(&data, d2.type);
20a69341 4269err2:
59105446 4270 nft_data_release(&elem.key.val, d1.type);
20a69341
PM
4271err1:
4272 return err;
4273}
4274
633c9a84
PNA
4275static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
4276 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4277 const struct nlattr * const nla[],
4278 struct netlink_ext_ack *extack)
20a69341 4279{
f2a6d766 4280 u8 genmask = nft_genmask_next(net);
20a69341
PM
4281 const struct nlattr *attr;
4282 struct nft_set *set;
4283 struct nft_ctx ctx;
a654de8f 4284 int rem, err;
20a69341 4285
7d5570ca
PNA
4286 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
4287 return -EINVAL;
4288
36dd1bcc
PNA
4289 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
4290 genmask);
20a69341
PM
4291 if (err < 0)
4292 return err;
4293
a3073c17
PNA
4294 set = nft_set_lookup_global(net, ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
4295 nla[NFTA_SET_ELEM_LIST_SET_ID], genmask);
4296 if (IS_ERR(set))
4297 return PTR_ERR(set);
958bee14 4298
20a69341
PM
4299 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4300 return -EBUSY;
4301
4302 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
c016c7e4 4303 err = nft_add_set_elem(&ctx, set, attr, nlh->nlmsg_flags);
35d0ac90 4304 if (err < 0)
a654de8f 4305 return err;
20a69341 4306 }
a654de8f
PNA
4307
4308 if (net->nft.validate_state == NFT_VALIDATE_DO)
4309 return nft_table_validate(net, ctx.table);
4310
4311 return 0;
20a69341
PM
4312}
4313
59105446
PNA
4314/**
4315 * nft_data_hold - hold a nft_data item
4316 *
4317 * @data: struct nft_data to release
4318 * @type: type of data
4319 *
4320 * Hold a nft_data item. NFT_DATA_VALUE types can be silently discarded,
4321 * NFT_DATA_VERDICT bumps the reference to chains in case of NFT_JUMP and
4322 * NFT_GOTO verdicts. This function must be called on active data objects
4323 * from the second phase of the commit protocol.
4324 */
bb7b40ae 4325void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
59105446
PNA
4326{
4327 if (type == NFT_DATA_VERDICT) {
4328 switch (data->verdict.code) {
4329 case NFT_JUMP:
4330 case NFT_GOTO:
4331 data->verdict.chain->use++;
4332 break;
4333 }
4334 }
4335}
4336
4337static void nft_set_elem_activate(const struct net *net,
4338 const struct nft_set *set,
4339 struct nft_set_elem *elem)
4340{
4341 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4342
4343 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4344 nft_data_hold(nft_set_ext_data(ext), set->dtype);
4345 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4346 (*nft_set_ext_obj(ext))->use++;
4347}
4348
4349static void nft_set_elem_deactivate(const struct net *net,
4350 const struct nft_set *set,
4351 struct nft_set_elem *elem)
4352{
4353 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4354
4355 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4356 nft_data_release(nft_set_ext_data(ext), set->dtype);
4357 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4358 (*nft_set_ext_obj(ext))->use--;
4359}
4360
60319eb1 4361static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
20a69341
PM
4362 const struct nlattr *attr)
4363{
4364 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3971ca14 4365 struct nft_set_ext_tmpl tmpl;
20a69341
PM
4366 struct nft_data_desc desc;
4367 struct nft_set_elem elem;
3971ca14 4368 struct nft_set_ext *ext;
60319eb1 4369 struct nft_trans *trans;
3971ca14
PNA
4370 u32 flags = 0;
4371 void *priv;
20a69341
PM
4372 int err;
4373
4374 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
fceb6435 4375 nft_set_elem_policy, NULL);
20a69341
PM
4376 if (err < 0)
4377 goto err1;
4378
4379 err = -EINVAL;
4380 if (nla[NFTA_SET_ELEM_KEY] == NULL)
4381 goto err1;
4382
3971ca14
PNA
4383 nft_set_ext_prepare(&tmpl);
4384
4385 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
4386 if (err < 0)
4387 return err;
4388 if (flags != 0)
4389 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
4390
7d740264 4391 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
d0a11fc3 4392 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
4393 if (err < 0)
4394 goto err1;
4395
4396 err = -EINVAL;
4397 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
4398 goto err2;
4399
3971ca14
PNA
4400 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
4401
4402 err = -ENOMEM;
4403 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
4404 GFP_KERNEL);
4405 if (elem.priv == NULL)
4406 goto err2;
4407
4408 ext = nft_set_elem_ext(set, elem.priv);
4409 if (flags)
4410 *nft_set_ext_flags(ext) = flags;
4411
60319eb1 4412 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
609ccf08
JL
4413 if (trans == NULL) {
4414 err = -ENOMEM;
3971ca14 4415 goto err3;
609ccf08 4416 }
20a69341 4417
42a55769 4418 priv = set->ops->deactivate(ctx->net, set, &elem);
3971ca14 4419 if (priv == NULL) {
cc02e457 4420 err = -ENOENT;
3971ca14 4421 goto err4;
cc02e457 4422 }
3971ca14
PNA
4423 kfree(elem.priv);
4424 elem.priv = priv;
cc02e457 4425
59105446
PNA
4426 nft_set_elem_deactivate(ctx->net, set, &elem);
4427
60319eb1 4428 nft_trans_elem(trans) = elem;
46bbafce 4429 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
0dc13625 4430 return 0;
cc02e457 4431
3971ca14 4432err4:
cc02e457 4433 kfree(trans);
3971ca14
PNA
4434err3:
4435 kfree(elem.priv);
20a69341 4436err2:
59105446 4437 nft_data_release(&elem.key.val, desc.type);
20a69341
PM
4438err1:
4439 return err;
4440}
4441
8411b644 4442static int nft_flush_set(const struct nft_ctx *ctx,
de70185d 4443 struct nft_set *set,
8411b644 4444 const struct nft_set_iter *iter,
de70185d 4445 struct nft_set_elem *elem)
8411b644
PNA
4446{
4447 struct nft_trans *trans;
4448 int err;
4449
4450 trans = nft_trans_alloc_gfp(ctx, NFT_MSG_DELSETELEM,
4451 sizeof(struct nft_trans_elem), GFP_ATOMIC);
4452 if (!trans)
4453 return -ENOMEM;
4454
1ba1c414 4455 if (!set->ops->flush(ctx->net, set, elem->priv)) {
8411b644
PNA
4456 err = -ENOENT;
4457 goto err1;
4458 }
b2c11e4b 4459 set->ndeact++;
8411b644 4460
de70185d
PNA
4461 nft_trans_elem_set(trans) = set;
4462 nft_trans_elem(trans) = *elem;
8411b644
PNA
4463 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
4464
4465 return 0;
4466err1:
4467 kfree(trans);
4468 return err;
4469}
4470
633c9a84
PNA
4471static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
4472 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4473 const struct nlattr * const nla[],
4474 struct netlink_ext_ack *extack)
20a69341 4475{
f2a6d766 4476 u8 genmask = nft_genmask_next(net);
20a69341
PM
4477 const struct nlattr *attr;
4478 struct nft_set *set;
4479 struct nft_ctx ctx;
60319eb1 4480 int rem, err = 0;
20a69341 4481
36dd1bcc
PNA
4482 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
4483 genmask);
20a69341
PM
4484 if (err < 0)
4485 return err;
4486
cac20fcd 4487 set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
20a69341
PM
4488 if (IS_ERR(set))
4489 return PTR_ERR(set);
4490 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4491 return -EBUSY;
4492
8411b644 4493 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
baa2d42c
PNA
4494 struct nft_set_iter iter = {
4495 .genmask = genmask,
4496 .fn = nft_flush_set,
8411b644 4497 };
baa2d42c 4498 set->ops->walk(&ctx, set, &iter);
8411b644 4499
baa2d42c 4500 return iter.err;
8411b644
PNA
4501 }
4502
20a69341
PM
4503 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
4504 err = nft_del_setelem(&ctx, set, attr);
4505 if (err < 0)
60319eb1 4506 break;
4fefee57 4507
3dd0673a 4508 set->ndeact++;
20a69341 4509 }
60319eb1 4510 return err;
20a69341
PM
4511}
4512
cfed7e1b
PM
4513void nft_set_gc_batch_release(struct rcu_head *rcu)
4514{
4515 struct nft_set_gc_batch *gcb;
4516 unsigned int i;
4517
4518 gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
4519 for (i = 0; i < gcb->head.cnt; i++)
61f9e292 4520 nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
cfed7e1b
PM
4521 kfree(gcb);
4522}
4523EXPORT_SYMBOL_GPL(nft_set_gc_batch_release);
4524
4525struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
4526 gfp_t gfp)
4527{
4528 struct nft_set_gc_batch *gcb;
4529
4530 gcb = kzalloc(sizeof(*gcb), gfp);
4531 if (gcb == NULL)
4532 return gcb;
4533 gcb->head.set = set;
4534 return gcb;
4535}
4536EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
4537
e5009240
PNA
4538/*
4539 * Stateful objects
4540 */
4541
4542/**
4543 * nft_register_obj- register nf_tables stateful object type
4544 * @obj: object type
4545 *
4546 * Registers the object type for use with nf_tables. Returns zero on
4547 * success or a negative errno code otherwise.
4548 */
4549int nft_register_obj(struct nft_object_type *obj_type)
4550{
4551 if (obj_type->type == NFT_OBJECT_UNSPEC)
4552 return -EINVAL;
4553
4554 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4555 list_add_rcu(&obj_type->list, &nf_tables_objects);
4556 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4557 return 0;
4558}
4559EXPORT_SYMBOL_GPL(nft_register_obj);
4560
4561/**
4562 * nft_unregister_obj - unregister nf_tables object type
4563 * @obj: object type
4564 *
4565 * Unregisters the object type for use with nf_tables.
4566 */
4567void nft_unregister_obj(struct nft_object_type *obj_type)
4568{
4569 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4570 list_del_rcu(&obj_type->list);
4571 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4572}
4573EXPORT_SYMBOL_GPL(nft_unregister_obj);
4574
cac20fcd
PNA
4575struct nft_object *nft_obj_lookup(const struct nft_table *table,
4576 const struct nlattr *nla, u32 objtype,
4577 u8 genmask)
e5009240
PNA
4578{
4579 struct nft_object *obj;
4580
d9adf22a 4581 list_for_each_entry_rcu(obj, &table->objects, list) {
e5009240 4582 if (!nla_strcmp(nla, obj->name) &&
dfc46034 4583 objtype == obj->ops->type->type &&
e5009240
PNA
4584 nft_active_genmask(obj, genmask))
4585 return obj;
4586 }
4587 return ERR_PTR(-ENOENT);
4588}
cac20fcd 4589EXPORT_SYMBOL_GPL(nft_obj_lookup);
e5009240 4590
cac20fcd
PNA
4591static struct nft_object *nft_obj_lookup_byhandle(const struct nft_table *table,
4592 const struct nlattr *nla,
4593 u32 objtype, u8 genmask)
3ecbfd65
HS
4594{
4595 struct nft_object *obj;
4596
4597 list_for_each_entry(obj, &table->objects, list) {
4598 if (be64_to_cpu(nla_get_be64(nla)) == obj->handle &&
4599 objtype == obj->ops->type->type &&
4600 nft_active_genmask(obj, genmask))
4601 return obj;
4602 }
4603 return ERR_PTR(-ENOENT);
4604}
4605
e5009240 4606static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
b2fbd044
LZ
4607 [NFTA_OBJ_TABLE] = { .type = NLA_STRING,
4608 .len = NFT_TABLE_MAXNAMELEN - 1 },
4609 [NFTA_OBJ_NAME] = { .type = NLA_STRING,
4610 .len = NFT_OBJ_MAXNAMELEN - 1 },
e5009240
PNA
4611 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
4612 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
3ecbfd65 4613 [NFTA_OBJ_HANDLE] = { .type = NLA_U64},
e5009240
PNA
4614};
4615
84fba055
FW
4616static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,
4617 const struct nft_object_type *type,
e5009240
PNA
4618 const struct nlattr *attr)
4619{
5b4c6e38 4620 struct nlattr **tb;
dfc46034 4621 const struct nft_object_ops *ops;
e5009240 4622 struct nft_object *obj;
5b4c6e38
GS
4623 int err = -ENOMEM;
4624
4625 tb = kmalloc_array(type->maxattr + 1, sizeof(*tb), GFP_KERNEL);
4626 if (!tb)
4627 goto err1;
e5009240
PNA
4628
4629 if (attr) {
fceb6435
JB
4630 err = nla_parse_nested(tb, type->maxattr, attr, type->policy,
4631 NULL);
e5009240 4632 if (err < 0)
5b4c6e38 4633 goto err2;
e5009240
PNA
4634 } else {
4635 memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));
4636 }
4637
dfc46034
PBG
4638 if (type->select_ops) {
4639 ops = type->select_ops(ctx, (const struct nlattr * const *)tb);
4640 if (IS_ERR(ops)) {
4641 err = PTR_ERR(ops);
5b4c6e38 4642 goto err2;
dfc46034
PBG
4643 }
4644 } else {
4645 ops = type->ops;
4646 }
4647
e5009240 4648 err = -ENOMEM;
dfc46034 4649 obj = kzalloc(sizeof(*obj) + ops->size, GFP_KERNEL);
5b4c6e38
GS
4650 if (!obj)
4651 goto err2;
e5009240 4652
dfc46034 4653 err = ops->init(ctx, (const struct nlattr * const *)tb, obj);
e5009240 4654 if (err < 0)
5b4c6e38 4655 goto err3;
e5009240 4656
dfc46034
PBG
4657 obj->ops = ops;
4658
5b4c6e38 4659 kfree(tb);
e5009240 4660 return obj;
5b4c6e38 4661err3:
e5009240 4662 kfree(obj);
5b4c6e38
GS
4663err2:
4664 kfree(tb);
e5009240
PNA
4665err1:
4666 return ERR_PTR(err);
4667}
4668
4669static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
43da04a5 4670 struct nft_object *obj, bool reset)
e5009240
PNA
4671{
4672 struct nlattr *nest;
4673
4674 nest = nla_nest_start(skb, attr);
4675 if (!nest)
4676 goto nla_put_failure;
dfc46034 4677 if (obj->ops->dump(skb, obj, reset) < 0)
e5009240
PNA
4678 goto nla_put_failure;
4679 nla_nest_end(skb, nest);
4680 return 0;
4681
4682nla_put_failure:
4683 return -1;
4684}
4685
4686static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
4687{
4688 const struct nft_object_type *type;
4689
4690 list_for_each_entry(type, &nf_tables_objects, list) {
4691 if (objtype == type->type)
4692 return type;
4693 }
4694 return NULL;
4695}
4696
4697static const struct nft_object_type *nft_obj_type_get(u32 objtype)
4698{
4699 const struct nft_object_type *type;
4700
4701 type = __nft_obj_type_get(objtype);
4702 if (type != NULL && try_module_get(type->owner))
4703 return type;
4704
4705#ifdef CONFIG_MODULES
4706 if (type == NULL) {
4707 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4708 request_module("nft-obj-%u", objtype);
4709 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4710 if (__nft_obj_type_get(objtype))
4711 return ERR_PTR(-EAGAIN);
4712 }
4713#endif
4714 return ERR_PTR(-ENOENT);
4715}
4716
4717static int nf_tables_newobj(struct net *net, struct sock *nlsk,
4718 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4719 const struct nlattr * const nla[],
4720 struct netlink_ext_ack *extack)
e5009240
PNA
4721{
4722 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4723 const struct nft_object_type *type;
4724 u8 genmask = nft_genmask_next(net);
4725 int family = nfmsg->nfgen_family;
e5009240
PNA
4726 struct nft_table *table;
4727 struct nft_object *obj;
4728 struct nft_ctx ctx;
4729 u32 objtype;
4730 int err;
4731
4732 if (!nla[NFTA_OBJ_TYPE] ||
4733 !nla[NFTA_OBJ_NAME] ||
4734 !nla[NFTA_OBJ_DATA])
4735 return -EINVAL;
4736
cac20fcd 4737 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask);
36dd1bcc
PNA
4738 if (IS_ERR(table)) {
4739 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 4740 return PTR_ERR(table);
36dd1bcc 4741 }
e5009240
PNA
4742
4743 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
cac20fcd 4744 obj = nft_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
e5009240
PNA
4745 if (IS_ERR(obj)) {
4746 err = PTR_ERR(obj);
36dd1bcc
PNA
4747 if (err != -ENOENT) {
4748 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 4749 return err;
36dd1bcc 4750 }
1a28ad74 4751 } else {
36dd1bcc
PNA
4752 if (nlh->nlmsg_flags & NLM_F_EXCL) {
4753 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 4754 return -EEXIST;
36dd1bcc 4755 }
e5009240
PNA
4756 return 0;
4757 }
4758
98319cb9 4759 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e5009240
PNA
4760
4761 type = nft_obj_type_get(objtype);
4762 if (IS_ERR(type))
4763 return PTR_ERR(type);
4764
84fba055 4765 obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
e5009240
PNA
4766 if (IS_ERR(obj)) {
4767 err = PTR_ERR(obj);
4768 goto err1;
4769 }
18965317 4770 obj->table = table;
3ecbfd65
HS
4771 obj->handle = nf_tables_alloc_handle(table);
4772
61509575
PS
4773 obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
4774 if (!obj->name) {
4775 err = -ENOMEM;
4776 goto err2;
4777 }
e5009240
PNA
4778
4779 err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj);
4780 if (err < 0)
61509575 4781 goto err3;
e5009240
PNA
4782
4783 list_add_tail_rcu(&obj->list, &table->objects);
4784 table->use++;
4785 return 0;
61509575
PS
4786err3:
4787 kfree(obj->name);
e5009240 4788err2:
dfc46034 4789 if (obj->ops->destroy)
00bfb320 4790 obj->ops->destroy(&ctx, obj);
e5009240
PNA
4791 kfree(obj);
4792err1:
4793 module_put(type->owner);
4794 return err;
4795}
4796
4797static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
4798 u32 portid, u32 seq, int event, u32 flags,
4799 int family, const struct nft_table *table,
43da04a5 4800 struct nft_object *obj, bool reset)
e5009240
PNA
4801{
4802 struct nfgenmsg *nfmsg;
4803 struct nlmsghdr *nlh;
4804
dedb67c4 4805 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
e5009240
PNA
4806 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
4807 if (nlh == NULL)
4808 goto nla_put_failure;
4809
4810 nfmsg = nlmsg_data(nlh);
4811 nfmsg->nfgen_family = family;
4812 nfmsg->version = NFNETLINK_V0;
4813 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4814
4815 if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
4816 nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
dfc46034 4817 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
e5009240 4818 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
3ecbfd65
HS
4819 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) ||
4820 nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle),
4821 NFTA_OBJ_PAD))
e5009240
PNA
4822 goto nla_put_failure;
4823
4824 nlmsg_end(skb, nlh);
4825 return 0;
4826
4827nla_put_failure:
4828 nlmsg_trim(skb, nlh);
4829 return -1;
4830}
4831
a9fea2a3 4832struct nft_obj_filter {
e46abbcc 4833 char *table;
a9fea2a3
PNA
4834 u32 type;
4835};
4836
e5009240
PNA
4837static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
4838{
4839 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
e5009240 4840 const struct nft_table *table;
e5009240 4841 unsigned int idx = 0, s_idx = cb->args[0];
a9fea2a3 4842 struct nft_obj_filter *filter = cb->data;
e5009240
PNA
4843 struct net *net = sock_net(skb->sk);
4844 int family = nfmsg->nfgen_family;
43da04a5
PNA
4845 struct nft_object *obj;
4846 bool reset = false;
4847
4848 if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4849 reset = true;
e5009240
PNA
4850
4851 rcu_read_lock();
4852 cb->seq = net->nft.base_seq;
4853
36596dad 4854 list_for_each_entry_rcu(table, &net->nft.tables, list) {
98319cb9 4855 if (family != NFPROTO_UNSPEC && family != table->family)
e5009240
PNA
4856 continue;
4857
36596dad
PNA
4858 list_for_each_entry_rcu(obj, &table->objects, list) {
4859 if (!nft_is_active(net, obj))
4860 goto cont;
4861 if (idx < s_idx)
4862 goto cont;
4863 if (idx > s_idx)
4864 memset(&cb->args[1], 0,
4865 sizeof(cb->args) - sizeof(cb->args[0]));
4866 if (filter && filter->table[0] &&
4867 strcmp(filter->table, table->name))
4868 goto cont;
4869 if (filter &&
4870 filter->type != NFT_OBJECT_UNSPEC &&
4871 obj->ops->type->type != filter->type)
4872 goto cont;
a9fea2a3 4873
36596dad
PNA
4874 if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
4875 cb->nlh->nlmsg_seq,
4876 NFT_MSG_NEWOBJ,
4877 NLM_F_MULTI | NLM_F_APPEND,
98319cb9 4878 table->family, table,
36596dad
PNA
4879 obj, reset) < 0)
4880 goto done;
e5009240 4881
36596dad 4882 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
e5009240 4883cont:
36596dad 4884 idx++;
e5009240
PNA
4885 }
4886 }
4887done:
4888 rcu_read_unlock();
4889
4890 cb->args[0] = idx;
4891 return skb->len;
4892}
4893
a9fea2a3
PNA
4894static int nf_tables_dump_obj_done(struct netlink_callback *cb)
4895{
e46abbcc
PS
4896 struct nft_obj_filter *filter = cb->data;
4897
8bea728d
HL
4898 if (filter) {
4899 kfree(filter->table);
4900 kfree(filter);
4901 }
a9fea2a3
PNA
4902
4903 return 0;
4904}
4905
4906static struct nft_obj_filter *
4907nft_obj_filter_alloc(const struct nlattr * const nla[])
4908{
4909 struct nft_obj_filter *filter;
4910
d9adf22a 4911 filter = kzalloc(sizeof(*filter), GFP_ATOMIC);
a9fea2a3
PNA
4912 if (!filter)
4913 return ERR_PTR(-ENOMEM);
4914
e46abbcc 4915 if (nla[NFTA_OBJ_TABLE]) {
d9adf22a 4916 filter->table = nla_strdup(nla[NFTA_OBJ_TABLE], GFP_ATOMIC);
e46abbcc
PS
4917 if (!filter->table) {
4918 kfree(filter);
4919 return ERR_PTR(-ENOMEM);
4920 }
4921 }
a9fea2a3
PNA
4922 if (nla[NFTA_OBJ_TYPE])
4923 filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4924
4925 return filter;
4926}
4927
d9adf22a 4928/* called with rcu_read_lock held */
e5009240
PNA
4929static int nf_tables_getobj(struct net *net, struct sock *nlsk,
4930 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4931 const struct nlattr * const nla[],
4932 struct netlink_ext_ack *extack)
e5009240
PNA
4933{
4934 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4935 u8 genmask = nft_genmask_cur(net);
4936 int family = nfmsg->nfgen_family;
e5009240
PNA
4937 const struct nft_table *table;
4938 struct nft_object *obj;
4939 struct sk_buff *skb2;
43da04a5 4940 bool reset = false;
e5009240
PNA
4941 u32 objtype;
4942 int err;
4943
4944 if (nlh->nlmsg_flags & NLM_F_DUMP) {
4945 struct netlink_dump_control c = {
4946 .dump = nf_tables_dump_obj,
a9fea2a3 4947 .done = nf_tables_dump_obj_done,
d9adf22a 4948 .module = THIS_MODULE,
e5009240 4949 };
a9fea2a3
PNA
4950
4951 if (nla[NFTA_OBJ_TABLE] ||
4952 nla[NFTA_OBJ_TYPE]) {
4953 struct nft_obj_filter *filter;
4954
4955 filter = nft_obj_filter_alloc(nla);
4956 if (IS_ERR(filter))
4957 return -ENOMEM;
4958
4959 c.data = filter;
4960 }
d9adf22a 4961 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
e5009240
PNA
4962 }
4963
4964 if (!nla[NFTA_OBJ_NAME] ||
4965 !nla[NFTA_OBJ_TYPE])
4966 return -EINVAL;
4967
cac20fcd 4968 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask);
36dd1bcc
PNA
4969 if (IS_ERR(table)) {
4970 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 4971 return PTR_ERR(table);
36dd1bcc 4972 }
e5009240
PNA
4973
4974 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
cac20fcd 4975 obj = nft_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
36dd1bcc
PNA
4976 if (IS_ERR(obj)) {
4977 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 4978 return PTR_ERR(obj);
36dd1bcc 4979 }
e5009240 4980
d9adf22a 4981 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
e5009240
PNA
4982 if (!skb2)
4983 return -ENOMEM;
4984
43da04a5
PNA
4985 if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4986 reset = true;
4987
e5009240
PNA
4988 err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
4989 nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
43da04a5 4990 family, table, obj, reset);
e5009240
PNA
4991 if (err < 0)
4992 goto err;
4993
4994 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4995err:
4996 kfree_skb(skb2);
4997 return err;
e5009240
PNA
4998}
4999
00bfb320 5000static void nft_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
e5009240 5001{
dfc46034 5002 if (obj->ops->destroy)
00bfb320 5003 obj->ops->destroy(ctx, obj);
e5009240 5004
dfc46034 5005 module_put(obj->ops->type->owner);
61509575 5006 kfree(obj->name);
e5009240
PNA
5007 kfree(obj);
5008}
5009
5010static int nf_tables_delobj(struct net *net, struct sock *nlsk,
04ba724b
PNA
5011 struct sk_buff *skb, const struct nlmsghdr *nlh,
5012 const struct nlattr * const nla[],
5013 struct netlink_ext_ack *extack)
e5009240
PNA
5014{
5015 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5016 u8 genmask = nft_genmask_next(net);
5017 int family = nfmsg->nfgen_family;
36dd1bcc 5018 const struct nlattr *attr;
e5009240
PNA
5019 struct nft_table *table;
5020 struct nft_object *obj;
5021 struct nft_ctx ctx;
5022 u32 objtype;
5023
5024 if (!nla[NFTA_OBJ_TYPE] ||
3ecbfd65 5025 (!nla[NFTA_OBJ_NAME] && !nla[NFTA_OBJ_HANDLE]))
e5009240
PNA
5026 return -EINVAL;
5027
cac20fcd 5028 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask);
36dd1bcc
PNA
5029 if (IS_ERR(table)) {
5030 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 5031 return PTR_ERR(table);
36dd1bcc 5032 }
e5009240
PNA
5033
5034 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
36dd1bcc
PNA
5035 if (nla[NFTA_OBJ_HANDLE]) {
5036 attr = nla[NFTA_OBJ_HANDLE];
5037 obj = nft_obj_lookup_byhandle(table, attr, objtype, genmask);
5038 } else {
5039 attr = nla[NFTA_OBJ_NAME];
5040 obj = nft_obj_lookup(table, attr, objtype, genmask);
5041 }
5042
5043 if (IS_ERR(obj)) {
5044 NL_SET_BAD_ATTR(extack, attr);
e5009240 5045 return PTR_ERR(obj);
36dd1bcc
PNA
5046 }
5047 if (obj->use > 0) {
5048 NL_SET_BAD_ATTR(extack, attr);
e5009240 5049 return -EBUSY;
36dd1bcc 5050 }
e5009240 5051
98319cb9 5052 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e5009240
PNA
5053
5054 return nft_delobj(&ctx, obj);
5055}
5056
25e94a99
PNA
5057void nft_obj_notify(struct net *net, struct nft_table *table,
5058 struct nft_object *obj, u32 portid, u32 seq, int event,
5059 int family, int report, gfp_t gfp)
e5009240
PNA
5060{
5061 struct sk_buff *skb;
5062 int err;
5063
2599e989
PNA
5064 if (!report &&
5065 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 5066 return;
e5009240 5067
2599e989 5068 skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
e5009240
PNA
5069 if (skb == NULL)
5070 goto err;
5071
2599e989
PNA
5072 err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
5073 table, obj, false);
e5009240
PNA
5074 if (err < 0) {
5075 kfree_skb(skb);
5076 goto err;
5077 }
5078
25e94a99
PNA
5079 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
5080 return;
e5009240 5081err:
25e94a99 5082 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
e5009240 5083}
2599e989
PNA
5084EXPORT_SYMBOL_GPL(nft_obj_notify);
5085
25e94a99
PNA
5086static void nf_tables_obj_notify(const struct nft_ctx *ctx,
5087 struct nft_object *obj, int event)
2599e989 5088{
25e94a99 5089 nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
36596dad 5090 ctx->family, ctx->report, GFP_KERNEL);
2599e989 5091}
e5009240 5092
3b49e2e9
PNA
5093/*
5094 * Flow tables
5095 */
5096void nft_register_flowtable_type(struct nf_flowtable_type *type)
5097{
5098 nfnl_lock(NFNL_SUBSYS_NFTABLES);
5099 list_add_tail_rcu(&type->list, &nf_tables_flowtables);
5100 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5101}
5102EXPORT_SYMBOL_GPL(nft_register_flowtable_type);
5103
5104void nft_unregister_flowtable_type(struct nf_flowtable_type *type)
5105{
5106 nfnl_lock(NFNL_SUBSYS_NFTABLES);
5107 list_del_rcu(&type->list);
5108 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5109}
5110EXPORT_SYMBOL_GPL(nft_unregister_flowtable_type);
5111
5112static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = {
5113 [NFTA_FLOWTABLE_TABLE] = { .type = NLA_STRING,
5114 .len = NFT_NAME_MAXLEN - 1 },
5115 [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING,
5116 .len = NFT_NAME_MAXLEN - 1 },
5117 [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED },
3ecbfd65 5118 [NFTA_FLOWTABLE_HANDLE] = { .type = NLA_U64 },
3b49e2e9
PNA
5119};
5120
cac20fcd
PNA
5121struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table,
5122 const struct nlattr *nla, u8 genmask)
3b49e2e9
PNA
5123{
5124 struct nft_flowtable *flowtable;
5125
d9adf22a 5126 list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
3b49e2e9
PNA
5127 if (!nla_strcmp(nla, flowtable->name) &&
5128 nft_active_genmask(flowtable, genmask))
5129 return flowtable;
5130 }
5131 return ERR_PTR(-ENOENT);
5132}
cac20fcd 5133EXPORT_SYMBOL_GPL(nft_flowtable_lookup);
3b49e2e9 5134
ae0662f8 5135static struct nft_flowtable *
cac20fcd
PNA
5136nft_flowtable_lookup_byhandle(const struct nft_table *table,
5137 const struct nlattr *nla, u8 genmask)
3ecbfd65
HS
5138{
5139 struct nft_flowtable *flowtable;
5140
5141 list_for_each_entry(flowtable, &table->flowtables, list) {
5142 if (be64_to_cpu(nla_get_be64(nla)) == flowtable->handle &&
5143 nft_active_genmask(flowtable, genmask))
5144 return flowtable;
5145 }
5146 return ERR_PTR(-ENOENT);
5147}
5148
3b49e2e9
PNA
5149static int nf_tables_parse_devices(const struct nft_ctx *ctx,
5150 const struct nlattr *attr,
5151 struct net_device *dev_array[], int *len)
5152{
5153 const struct nlattr *tmp;
5154 struct net_device *dev;
5155 char ifname[IFNAMSIZ];
5156 int rem, n = 0, err;
5157
5158 nla_for_each_nested(tmp, attr, rem) {
5159 if (nla_type(tmp) != NFTA_DEVICE_NAME) {
5160 err = -EINVAL;
5161 goto err1;
5162 }
5163
5164 nla_strlcpy(ifname, tmp, IFNAMSIZ);
90d2723c 5165 dev = __dev_get_by_name(ctx->net, ifname);
3b49e2e9
PNA
5166 if (!dev) {
5167 err = -ENOENT;
5168 goto err1;
5169 }
5170
5171 dev_array[n++] = dev;
5172 if (n == NFT_FLOWTABLE_DEVICE_MAX) {
5173 err = -EFBIG;
5174 goto err1;
5175 }
5176 }
5177 if (!len)
5178 return -EINVAL;
5179
5180 err = 0;
5181err1:
5182 *len = n;
5183 return err;
5184}
5185
5186static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX + 1] = {
5187 [NFTA_FLOWTABLE_HOOK_NUM] = { .type = NLA_U32 },
5188 [NFTA_FLOWTABLE_HOOK_PRIORITY] = { .type = NLA_U32 },
5189 [NFTA_FLOWTABLE_HOOK_DEVS] = { .type = NLA_NESTED },
5190};
5191
5192static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx,
5193 const struct nlattr *attr,
5194 struct nft_flowtable *flowtable)
5195{
5196 struct net_device *dev_array[NFT_FLOWTABLE_DEVICE_MAX];
5197 struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1];
5198 struct nf_hook_ops *ops;
5199 int hooknum, priority;
5200 int err, n = 0, i;
5201
5202 err = nla_parse_nested(tb, NFTA_FLOWTABLE_HOOK_MAX, attr,
5203 nft_flowtable_hook_policy, NULL);
5204 if (err < 0)
5205 return err;
5206
5207 if (!tb[NFTA_FLOWTABLE_HOOK_NUM] ||
5208 !tb[NFTA_FLOWTABLE_HOOK_PRIORITY] ||
5209 !tb[NFTA_FLOWTABLE_HOOK_DEVS])
5210 return -EINVAL;
5211
5212 hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
fe19c04c 5213 if (hooknum != NF_NETDEV_INGRESS)
3b49e2e9
PNA
5214 return -EINVAL;
5215
5216 priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));
5217
5218 err = nf_tables_parse_devices(ctx, tb[NFTA_FLOWTABLE_HOOK_DEVS],
5219 dev_array, &n);
5220 if (err < 0)
d92191aa 5221 return err;
3b49e2e9
PNA
5222
5223 ops = kzalloc(sizeof(struct nf_hook_ops) * n, GFP_KERNEL);
90d2723c
PNA
5224 if (!ops)
5225 return -ENOMEM;
3b49e2e9 5226
0e839dfa
PNA
5227 flowtable->hooknum = hooknum;
5228 flowtable->priority = priority;
3b49e2e9
PNA
5229 flowtable->ops = ops;
5230 flowtable->ops_len = n;
5231
5232 for (i = 0; i < n; i++) {
5233 flowtable->ops[i].pf = NFPROTO_NETDEV;
5234 flowtable->ops[i].hooknum = hooknum;
5235 flowtable->ops[i].priority = priority;
17857d92 5236 flowtable->ops[i].priv = &flowtable->data;
3b49e2e9
PNA
5237 flowtable->ops[i].hook = flowtable->data.type->hook;
5238 flowtable->ops[i].dev = dev_array[i];
d92191aa
PNA
5239 flowtable->dev_name[i] = kstrdup(dev_array[i]->name,
5240 GFP_KERNEL);
3b49e2e9
PNA
5241 }
5242
3b49e2e9
PNA
5243 return err;
5244}
5245
98319cb9 5246static const struct nf_flowtable_type *__nft_flowtable_type_get(u8 family)
3b49e2e9
PNA
5247{
5248 const struct nf_flowtable_type *type;
5249
5250 list_for_each_entry(type, &nf_tables_flowtables, list) {
98319cb9 5251 if (family == type->family)
3b49e2e9
PNA
5252 return type;
5253 }
5254 return NULL;
5255}
5256
98319cb9 5257static const struct nf_flowtable_type *nft_flowtable_type_get(u8 family)
3b49e2e9
PNA
5258{
5259 const struct nf_flowtable_type *type;
5260
98319cb9 5261 type = __nft_flowtable_type_get(family);
3b49e2e9
PNA
5262 if (type != NULL && try_module_get(type->owner))
5263 return type;
5264
5265#ifdef CONFIG_MODULES
5266 if (type == NULL) {
5267 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
98319cb9 5268 request_module("nf-flowtable-%u", family);
3b49e2e9 5269 nfnl_lock(NFNL_SUBSYS_NFTABLES);
98319cb9 5270 if (__nft_flowtable_type_get(family))
3b49e2e9
PNA
5271 return ERR_PTR(-EAGAIN);
5272 }
5273#endif
5274 return ERR_PTR(-ENOENT);
5275}
5276
3b49e2e9
PNA
5277static void nft_unregister_flowtable_net_hooks(struct net *net,
5278 struct nft_flowtable *flowtable)
5279{
5280 int i;
5281
5282 for (i = 0; i < flowtable->ops_len; i++) {
5283 if (!flowtable->ops[i].dev)
5284 continue;
5285
5286 nf_unregister_net_hook(net, &flowtable->ops[i]);
5287 }
5288}
5289
5290static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
5291 struct sk_buff *skb,
5292 const struct nlmsghdr *nlh,
5293 const struct nlattr * const nla[],
5294 struct netlink_ext_ack *extack)
5295{
5296 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5297 const struct nf_flowtable_type *type;
32fc7187 5298 struct nft_flowtable *flowtable, *ft;
3b49e2e9
PNA
5299 u8 genmask = nft_genmask_next(net);
5300 int family = nfmsg->nfgen_family;
3b49e2e9
PNA
5301 struct nft_table *table;
5302 struct nft_ctx ctx;
5303 int err, i, k;
5304
5305 if (!nla[NFTA_FLOWTABLE_TABLE] ||
5306 !nla[NFTA_FLOWTABLE_NAME] ||
5307 !nla[NFTA_FLOWTABLE_HOOK])
5308 return -EINVAL;
5309
cac20fcd
PNA
5310 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
5311 genmask);
36dd1bcc
PNA
5312 if (IS_ERR(table)) {
5313 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_TABLE]);
3b49e2e9 5314 return PTR_ERR(table);
36dd1bcc 5315 }
3b49e2e9 5316
cac20fcd
PNA
5317 flowtable = nft_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME],
5318 genmask);
3b49e2e9
PNA
5319 if (IS_ERR(flowtable)) {
5320 err = PTR_ERR(flowtable);
36dd1bcc
PNA
5321 if (err != -ENOENT) {
5322 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_NAME]);
3b49e2e9 5323 return err;
36dd1bcc 5324 }
3b49e2e9 5325 } else {
36dd1bcc
PNA
5326 if (nlh->nlmsg_flags & NLM_F_EXCL) {
5327 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_NAME]);
3b49e2e9 5328 return -EEXIST;
36dd1bcc 5329 }
3b49e2e9
PNA
5330
5331 return 0;
5332 }
5333
98319cb9 5334 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
3b49e2e9
PNA
5335
5336 flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
5337 if (!flowtable)
5338 return -ENOMEM;
5339
5340 flowtable->table = table;
3ecbfd65
HS
5341 flowtable->handle = nf_tables_alloc_handle(table);
5342
3b49e2e9
PNA
5343 flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL);
5344 if (!flowtable->name) {
5345 err = -ENOMEM;
5346 goto err1;
5347 }
5348
98319cb9 5349 type = nft_flowtable_type_get(family);
3b49e2e9
PNA
5350 if (IS_ERR(type)) {
5351 err = PTR_ERR(type);
5352 goto err2;
5353 }
5354
5355 flowtable->data.type = type;
a268de77 5356 err = type->init(&flowtable->data);
3b49e2e9
PNA
5357 if (err < 0)
5358 goto err3;
5359
5360 err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK],
5361 flowtable);
5362 if (err < 0)
a268de77 5363 goto err4;
3b49e2e9
PNA
5364
5365 for (i = 0; i < flowtable->ops_len; i++) {
32fc7187
PNA
5366 if (!flowtable->ops[i].dev)
5367 continue;
5368
5369 list_for_each_entry(ft, &table->flowtables, list) {
5370 for (k = 0; k < ft->ops_len; k++) {
5371 if (!ft->ops[k].dev)
5372 continue;
5373
5374 if (flowtable->ops[i].dev == ft->ops[k].dev &&
5375 flowtable->ops[i].pf == ft->ops[k].pf) {
5376 err = -EBUSY;
a268de77 5377 goto err5;
32fc7187
PNA
5378 }
5379 }
5380 }
5381
3b49e2e9
PNA
5382 err = nf_register_net_hook(net, &flowtable->ops[i]);
5383 if (err < 0)
a268de77 5384 goto err5;
3b49e2e9
PNA
5385 }
5386
5387 err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable);
5388 if (err < 0)
a268de77 5389 goto err6;
3b49e2e9
PNA
5390
5391 list_add_tail_rcu(&flowtable->list, &table->flowtables);
5392 table->use++;
5393
5394 return 0;
a268de77 5395err6:
3b49e2e9 5396 i = flowtable->ops_len;
a268de77 5397err5:
d92191aa
PNA
5398 for (k = i - 1; k >= 0; k--) {
5399 kfree(flowtable->dev_name[k]);
0e0d5002 5400 nf_unregister_net_hook(net, &flowtable->ops[k]);
d92191aa 5401 }
3b49e2e9
PNA
5402
5403 kfree(flowtable->ops);
a268de77
FF
5404err4:
5405 flowtable->data.type->free(&flowtable->data);
3b49e2e9
PNA
5406err3:
5407 module_put(type->owner);
5408err2:
5409 kfree(flowtable->name);
5410err1:
5411 kfree(flowtable);
5412 return err;
5413}
5414
5415static int nf_tables_delflowtable(struct net *net, struct sock *nlsk,
5416 struct sk_buff *skb,
5417 const struct nlmsghdr *nlh,
5418 const struct nlattr * const nla[],
5419 struct netlink_ext_ack *extack)
5420{
5421 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5422 u8 genmask = nft_genmask_next(net);
5423 int family = nfmsg->nfgen_family;
5424 struct nft_flowtable *flowtable;
36dd1bcc 5425 const struct nlattr *attr;
3b49e2e9
PNA
5426 struct nft_table *table;
5427 struct nft_ctx ctx;
5428
e603ea4b
PNA
5429 if (!nla[NFTA_FLOWTABLE_TABLE] ||
5430 (!nla[NFTA_FLOWTABLE_NAME] &&
5431 !nla[NFTA_FLOWTABLE_HANDLE]))
5432 return -EINVAL;
5433
cac20fcd
PNA
5434 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
5435 genmask);
36dd1bcc
PNA
5436 if (IS_ERR(table)) {
5437 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_TABLE]);
3b49e2e9 5438 return PTR_ERR(table);
36dd1bcc 5439 }
3b49e2e9 5440
36dd1bcc
PNA
5441 if (nla[NFTA_FLOWTABLE_HANDLE]) {
5442 attr = nla[NFTA_FLOWTABLE_HANDLE];
5443 flowtable = nft_flowtable_lookup_byhandle(table, attr, genmask);
5444 } else {
5445 attr = nla[NFTA_FLOWTABLE_NAME];
5446 flowtable = nft_flowtable_lookup(table, attr, genmask);
5447 }
5448
5449 if (IS_ERR(flowtable)) {
5450 NL_SET_BAD_ATTR(extack, attr);
5451 return PTR_ERR(flowtable);
5452 }
5453 if (flowtable->use > 0) {
5454 NL_SET_BAD_ATTR(extack, attr);
3b49e2e9 5455 return -EBUSY;
36dd1bcc 5456 }
3b49e2e9 5457
98319cb9 5458 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
3b49e2e9
PNA
5459
5460 return nft_delflowtable(&ctx, flowtable);
5461}
5462
5463static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
5464 u32 portid, u32 seq, int event,
5465 u32 flags, int family,
5466 struct nft_flowtable *flowtable)
5467{
5468 struct nlattr *nest, *nest_devs;
5469 struct nfgenmsg *nfmsg;
5470 struct nlmsghdr *nlh;
5471 int i;
5472
5473 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
5474 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
5475 if (nlh == NULL)
5476 goto nla_put_failure;
5477
5478 nfmsg = nlmsg_data(nlh);
5479 nfmsg->nfgen_family = family;
5480 nfmsg->version = NFNETLINK_V0;
5481 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
5482
5483 if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) ||
5484 nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
3ecbfd65
HS
5485 nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
5486 nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
5487 NFTA_FLOWTABLE_PAD))
3b49e2e9
PNA
5488 goto nla_put_failure;
5489
5490 nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK);
5491 if (nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_NUM, htonl(flowtable->hooknum)) ||
5492 nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_PRIORITY, htonl(flowtable->priority)))
5493 goto nla_put_failure;
5494
5495 nest_devs = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK_DEVS);
5496 if (!nest_devs)
5497 goto nla_put_failure;
5498
5499 for (i = 0; i < flowtable->ops_len; i++) {
d92191aa 5500 if (flowtable->dev_name[i][0] &&
3b49e2e9 5501 nla_put_string(skb, NFTA_DEVICE_NAME,
d92191aa 5502 flowtable->dev_name[i]))
3b49e2e9
PNA
5503 goto nla_put_failure;
5504 }
5505 nla_nest_end(skb, nest_devs);
5506 nla_nest_end(skb, nest);
5507
5508 nlmsg_end(skb, nlh);
5509 return 0;
5510
5511nla_put_failure:
5512 nlmsg_trim(skb, nlh);
5513 return -1;
5514}
5515
5516struct nft_flowtable_filter {
5517 char *table;
5518};
5519
5520static int nf_tables_dump_flowtable(struct sk_buff *skb,
5521 struct netlink_callback *cb)
5522{
5523 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
5524 struct nft_flowtable_filter *filter = cb->data;
5525 unsigned int idx = 0, s_idx = cb->args[0];
5526 struct net *net = sock_net(skb->sk);
5527 int family = nfmsg->nfgen_family;
5528 struct nft_flowtable *flowtable;
3b49e2e9
PNA
5529 const struct nft_table *table;
5530
5531 rcu_read_lock();
5532 cb->seq = net->nft.base_seq;
5533
36596dad 5534 list_for_each_entry_rcu(table, &net->nft.tables, list) {
98319cb9 5535 if (family != NFPROTO_UNSPEC && family != table->family)
3b49e2e9
PNA
5536 continue;
5537
36596dad
PNA
5538 list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
5539 if (!nft_is_active(net, flowtable))
5540 goto cont;
5541 if (idx < s_idx)
5542 goto cont;
5543 if (idx > s_idx)
5544 memset(&cb->args[1], 0,
5545 sizeof(cb->args) - sizeof(cb->args[0]));
5546 if (filter && filter->table[0] &&
5547 strcmp(filter->table, table->name))
5548 goto cont;
3b49e2e9 5549
36596dad
PNA
5550 if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid,
5551 cb->nlh->nlmsg_seq,
5552 NFT_MSG_NEWFLOWTABLE,
5553 NLM_F_MULTI | NLM_F_APPEND,
98319cb9 5554 table->family, flowtable) < 0)
36596dad 5555 goto done;
3b49e2e9 5556
36596dad 5557 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
3b49e2e9 5558cont:
36596dad 5559 idx++;
3b49e2e9
PNA
5560 }
5561 }
5562done:
5563 rcu_read_unlock();
5564
5565 cb->args[0] = idx;
5566 return skb->len;
5567}
5568
5569static int nf_tables_dump_flowtable_done(struct netlink_callback *cb)
5570{
5571 struct nft_flowtable_filter *filter = cb->data;
5572
5573 if (!filter)
5574 return 0;
5575
5576 kfree(filter->table);
5577 kfree(filter);
5578
5579 return 0;
5580}
5581
5582static struct nft_flowtable_filter *
5583nft_flowtable_filter_alloc(const struct nlattr * const nla[])
5584{
5585 struct nft_flowtable_filter *filter;
5586
d9adf22a 5587 filter = kzalloc(sizeof(*filter), GFP_ATOMIC);
3b49e2e9
PNA
5588 if (!filter)
5589 return ERR_PTR(-ENOMEM);
5590
5591 if (nla[NFTA_FLOWTABLE_TABLE]) {
5592 filter->table = nla_strdup(nla[NFTA_FLOWTABLE_TABLE],
d9adf22a 5593 GFP_ATOMIC);
3b49e2e9
PNA
5594 if (!filter->table) {
5595 kfree(filter);
5596 return ERR_PTR(-ENOMEM);
5597 }
5598 }
5599 return filter;
5600}
5601
d9adf22a 5602/* called with rcu_read_lock held */
3b49e2e9
PNA
5603static int nf_tables_getflowtable(struct net *net, struct sock *nlsk,
5604 struct sk_buff *skb,
5605 const struct nlmsghdr *nlh,
5606 const struct nlattr * const nla[],
5607 struct netlink_ext_ack *extack)
5608{
5609 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5610 u8 genmask = nft_genmask_cur(net);
5611 int family = nfmsg->nfgen_family;
5612 struct nft_flowtable *flowtable;
3b49e2e9
PNA
5613 const struct nft_table *table;
5614 struct sk_buff *skb2;
5615 int err;
5616
5617 if (nlh->nlmsg_flags & NLM_F_DUMP) {
5618 struct netlink_dump_control c = {
5619 .dump = nf_tables_dump_flowtable,
5620 .done = nf_tables_dump_flowtable_done,
d9adf22a 5621 .module = THIS_MODULE,
3b49e2e9
PNA
5622 };
5623
5624 if (nla[NFTA_FLOWTABLE_TABLE]) {
5625 struct nft_flowtable_filter *filter;
5626
5627 filter = nft_flowtable_filter_alloc(nla);
5628 if (IS_ERR(filter))
5629 return -ENOMEM;
5630
5631 c.data = filter;
5632 }
d9adf22a 5633 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
3b49e2e9
PNA
5634 }
5635
5636 if (!nla[NFTA_FLOWTABLE_NAME])
5637 return -EINVAL;
5638
cac20fcd
PNA
5639 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
5640 genmask);
3b49e2e9
PNA
5641 if (IS_ERR(table))
5642 return PTR_ERR(table);
5643
cac20fcd
PNA
5644 flowtable = nft_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME],
5645 genmask);
03a0120f 5646 if (IS_ERR(flowtable))
3b49e2e9
PNA
5647 return PTR_ERR(flowtable);
5648
d9adf22a 5649 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
3b49e2e9
PNA
5650 if (!skb2)
5651 return -ENOMEM;
5652
5653 err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid,
5654 nlh->nlmsg_seq,
5655 NFT_MSG_NEWFLOWTABLE, 0, family,
5656 flowtable);
5657 if (err < 0)
5658 goto err;
5659
5660 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
5661err:
5662 kfree_skb(skb2);
5663 return err;
5664}
5665
5666static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
5667 struct nft_flowtable *flowtable,
5668 int event)
5669{
5670 struct sk_buff *skb;
5671 int err;
5672
5673 if (ctx->report &&
5674 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
5675 return;
5676
5677 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
5678 if (skb == NULL)
5679 goto err;
5680
5681 err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid,
5682 ctx->seq, event, 0,
36596dad 5683 ctx->family, flowtable);
3b49e2e9
PNA
5684 if (err < 0) {
5685 kfree_skb(skb);
5686 goto err;
5687 }
5688
5689 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
5690 ctx->report, GFP_KERNEL);
5691 return;
5692err:
5693 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
5694}
5695
3b49e2e9
PNA
5696static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
5697{
c04a3f73 5698 kfree(flowtable->ops);
3b49e2e9 5699 kfree(flowtable->name);
b408c5b0 5700 flowtable->data.type->free(&flowtable->data);
3b49e2e9
PNA
5701 module_put(flowtable->data.type->owner);
5702}
5703
84d7fce6
PNA
5704static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
5705 u32 portid, u32 seq)
5706{
5707 struct nlmsghdr *nlh;
5708 struct nfgenmsg *nfmsg;
784b4e61 5709 char buf[TASK_COMM_LEN];
dedb67c4 5710 int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN);
84d7fce6
PNA
5711
5712 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0);
5713 if (nlh == NULL)
5714 goto nla_put_failure;
5715
5716 nfmsg = nlmsg_data(nlh);
5717 nfmsg->nfgen_family = AF_UNSPEC;
5718 nfmsg->version = NFNETLINK_V0;
5719 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
5720
784b4e61
PS
5721 if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) ||
5722 nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
5723 nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
84d7fce6
PNA
5724 goto nla_put_failure;
5725
053c095a
JB
5726 nlmsg_end(skb, nlh);
5727 return 0;
84d7fce6
PNA
5728
5729nla_put_failure:
5730 nlmsg_trim(skb, nlh);
5731 return -EMSGSIZE;
5732}
5733
3b49e2e9
PNA
5734static void nft_flowtable_event(unsigned long event, struct net_device *dev,
5735 struct nft_flowtable *flowtable)
5736{
5737 int i;
5738
5739 for (i = 0; i < flowtable->ops_len; i++) {
5740 if (flowtable->ops[i].dev != dev)
5741 continue;
5742
5743 nf_unregister_net_hook(dev_net(dev), &flowtable->ops[i]);
d92191aa 5744 flowtable->dev_name[i][0] = '\0';
3b49e2e9
PNA
5745 flowtable->ops[i].dev = NULL;
5746 break;
5747 }
5748}
5749
5750static int nf_tables_flowtable_event(struct notifier_block *this,
5751 unsigned long event, void *ptr)
5752{
5753 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
5754 struct nft_flowtable *flowtable;
5755 struct nft_table *table;
3b49e2e9
PNA
5756
5757 if (event != NETDEV_UNREGISTER)
5758 return 0;
5759
5760 nfnl_lock(NFNL_SUBSYS_NFTABLES);
36596dad
PNA
5761 list_for_each_entry(table, &dev_net(dev)->nft.tables, list) {
5762 list_for_each_entry(flowtable, &table->flowtables, list) {
5763 nft_flowtable_event(event, dev, flowtable);
3b49e2e9
PNA
5764 }
5765 }
5766 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5767
5768 return NOTIFY_DONE;
5769}
5770
5771static struct notifier_block nf_tables_flowtable_notifier = {
5772 .notifier_call = nf_tables_flowtable_event,
5773};
5774
25e94a99
PNA
5775static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
5776 int event)
84d7fce6
PNA
5777{
5778 struct nlmsghdr *nlh = nlmsg_hdr(skb);
5779 struct sk_buff *skb2;
5780 int err;
5781
5782 if (nlmsg_report(nlh) &&
5783 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 5784 return;
84d7fce6 5785
84d7fce6
PNA
5786 skb2 = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
5787 if (skb2 == NULL)
5788 goto err;
5789
5790 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
5791 nlh->nlmsg_seq);
5792 if (err < 0) {
5793 kfree_skb(skb2);
5794 goto err;
5795 }
5796
25e94a99
PNA
5797 nfnetlink_send(skb2, net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
5798 nlmsg_report(nlh), GFP_KERNEL);
5799 return;
84d7fce6 5800err:
25e94a99
PNA
5801 nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
5802 -ENOBUFS);
84d7fce6
PNA
5803}
5804
7b8002a1
PNA
5805static int nf_tables_getgen(struct net *net, struct sock *nlsk,
5806 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
5807 const struct nlattr * const nla[],
5808 struct netlink_ext_ack *extack)
84d7fce6 5809{
84d7fce6
PNA
5810 struct sk_buff *skb2;
5811 int err;
5812
d9adf22a 5813 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
84d7fce6
PNA
5814 if (skb2 == NULL)
5815 return -ENOMEM;
5816
5817 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
5818 nlh->nlmsg_seq);
5819 if (err < 0)
5820 goto err;
5821
5822 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
5823err:
5824 kfree_skb(skb2);
5825 return err;
5826}
5827
96518518
PM
5828static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
5829 [NFT_MSG_NEWTABLE] = {
55dd6f93 5830 .call_batch = nf_tables_newtable,
96518518
PM
5831 .attr_count = NFTA_TABLE_MAX,
5832 .policy = nft_table_policy,
5833 },
5834 [NFT_MSG_GETTABLE] = {
d9adf22a 5835 .call_rcu = nf_tables_gettable,
96518518
PM
5836 .attr_count = NFTA_TABLE_MAX,
5837 .policy = nft_table_policy,
5838 },
5839 [NFT_MSG_DELTABLE] = {
55dd6f93 5840 .call_batch = nf_tables_deltable,
96518518
PM
5841 .attr_count = NFTA_TABLE_MAX,
5842 .policy = nft_table_policy,
5843 },
5844 [NFT_MSG_NEWCHAIN] = {
91c7b38d 5845 .call_batch = nf_tables_newchain,
96518518
PM
5846 .attr_count = NFTA_CHAIN_MAX,
5847 .policy = nft_chain_policy,
5848 },
5849 [NFT_MSG_GETCHAIN] = {
d9adf22a 5850 .call_rcu = nf_tables_getchain,
96518518
PM
5851 .attr_count = NFTA_CHAIN_MAX,
5852 .policy = nft_chain_policy,
5853 },
5854 [NFT_MSG_DELCHAIN] = {
91c7b38d 5855 .call_batch = nf_tables_delchain,
96518518
PM
5856 .attr_count = NFTA_CHAIN_MAX,
5857 .policy = nft_chain_policy,
5858 },
5859 [NFT_MSG_NEWRULE] = {
0628b123 5860 .call_batch = nf_tables_newrule,
96518518
PM
5861 .attr_count = NFTA_RULE_MAX,
5862 .policy = nft_rule_policy,
5863 },
5864 [NFT_MSG_GETRULE] = {
d9adf22a 5865 .call_rcu = nf_tables_getrule,
96518518
PM
5866 .attr_count = NFTA_RULE_MAX,
5867 .policy = nft_rule_policy,
5868 },
5869 [NFT_MSG_DELRULE] = {
0628b123 5870 .call_batch = nf_tables_delrule,
96518518
PM
5871 .attr_count = NFTA_RULE_MAX,
5872 .policy = nft_rule_policy,
5873 },
20a69341 5874 [NFT_MSG_NEWSET] = {
958bee14 5875 .call_batch = nf_tables_newset,
20a69341
PM
5876 .attr_count = NFTA_SET_MAX,
5877 .policy = nft_set_policy,
5878 },
5879 [NFT_MSG_GETSET] = {
d9adf22a 5880 .call_rcu = nf_tables_getset,
20a69341
PM
5881 .attr_count = NFTA_SET_MAX,
5882 .policy = nft_set_policy,
5883 },
5884 [NFT_MSG_DELSET] = {
958bee14 5885 .call_batch = nf_tables_delset,
20a69341
PM
5886 .attr_count = NFTA_SET_MAX,
5887 .policy = nft_set_policy,
5888 },
5889 [NFT_MSG_NEWSETELEM] = {
958bee14 5890 .call_batch = nf_tables_newsetelem,
20a69341
PM
5891 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5892 .policy = nft_set_elem_list_policy,
5893 },
5894 [NFT_MSG_GETSETELEM] = {
d9adf22a 5895 .call_rcu = nf_tables_getsetelem,
20a69341
PM
5896 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5897 .policy = nft_set_elem_list_policy,
5898 },
5899 [NFT_MSG_DELSETELEM] = {
958bee14 5900 .call_batch = nf_tables_delsetelem,
20a69341
PM
5901 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5902 .policy = nft_set_elem_list_policy,
5903 },
84d7fce6 5904 [NFT_MSG_GETGEN] = {
d9adf22a 5905 .call_rcu = nf_tables_getgen,
84d7fce6 5906 },
e5009240
PNA
5907 [NFT_MSG_NEWOBJ] = {
5908 .call_batch = nf_tables_newobj,
5909 .attr_count = NFTA_OBJ_MAX,
5910 .policy = nft_obj_policy,
5911 },
5912 [NFT_MSG_GETOBJ] = {
d9adf22a 5913 .call_rcu = nf_tables_getobj,
e5009240
PNA
5914 .attr_count = NFTA_OBJ_MAX,
5915 .policy = nft_obj_policy,
5916 },
5917 [NFT_MSG_DELOBJ] = {
5918 .call_batch = nf_tables_delobj,
5919 .attr_count = NFTA_OBJ_MAX,
5920 .policy = nft_obj_policy,
5921 },
43da04a5 5922 [NFT_MSG_GETOBJ_RESET] = {
d9adf22a 5923 .call_rcu = nf_tables_getobj,
43da04a5
PNA
5924 .attr_count = NFTA_OBJ_MAX,
5925 .policy = nft_obj_policy,
5926 },
3b49e2e9
PNA
5927 [NFT_MSG_NEWFLOWTABLE] = {
5928 .call_batch = nf_tables_newflowtable,
5929 .attr_count = NFTA_FLOWTABLE_MAX,
5930 .policy = nft_flowtable_policy,
5931 },
5932 [NFT_MSG_GETFLOWTABLE] = {
d9adf22a 5933 .call_rcu = nf_tables_getflowtable,
3b49e2e9
PNA
5934 .attr_count = NFTA_FLOWTABLE_MAX,
5935 .policy = nft_flowtable_policy,
5936 },
5937 [NFT_MSG_DELFLOWTABLE] = {
5938 .call_batch = nf_tables_delflowtable,
5939 .attr_count = NFTA_FLOWTABLE_MAX,
5940 .policy = nft_flowtable_policy,
5941 },
96518518
PM
5942};
5943
a654de8f
PNA
5944static int nf_tables_validate(struct net *net)
5945{
5946 struct nft_table *table;
5947
5948 switch (net->nft.validate_state) {
5949 case NFT_VALIDATE_SKIP:
5950 break;
5951 case NFT_VALIDATE_NEED:
5952 nft_validate_state_update(net, NFT_VALIDATE_DO);
5953 /* fall through */
5954 case NFT_VALIDATE_DO:
5955 list_for_each_entry(table, &net->nft.tables, list) {
5956 if (nft_table_validate(net, table) < 0)
5957 return -EAGAIN;
5958 }
5959 break;
5960 }
5961
5962 return 0;
5963}
5964
91c7b38d
PNA
5965static void nft_chain_commit_update(struct nft_trans *trans)
5966{
5967 struct nft_base_chain *basechain;
5968
b7263e07 5969 if (nft_trans_chain_name(trans))
d71efb59 5970 swap(trans->ctx.chain->name, nft_trans_chain_name(trans));
91c7b38d 5971
f323d954 5972 if (!nft_is_base_chain(trans->ctx.chain))
91c7b38d
PNA
5973 return;
5974
5975 basechain = nft_base_chain(trans->ctx.chain);
5976 nft_chain_stats_replace(basechain, nft_trans_chain_stats(trans));
5977
5978 switch (nft_trans_chain_policy(trans)) {
5979 case NF_DROP:
5980 case NF_ACCEPT:
5981 basechain->policy = nft_trans_chain_policy(trans);
5982 break;
5983 }
5984}
5985
2f99aa31 5986static void nft_commit_release(struct nft_trans *trans)
c7c32e72 5987{
c7c32e72
PNA
5988 switch (trans->msg_type) {
5989 case NFT_MSG_DELTABLE:
5990 nf_tables_table_destroy(&trans->ctx);
5991 break;
5992 case NFT_MSG_DELCHAIN:
43a605f2 5993 nf_tables_chain_destroy(&trans->ctx);
c7c32e72
PNA
5994 break;
5995 case NFT_MSG_DELRULE:
5996 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
5997 break;
5998 case NFT_MSG_DELSET:
5999 nft_set_destroy(nft_trans_set(trans));
6000 break;
61edafbb 6001 case NFT_MSG_DELSETELEM:
59105446
PNA
6002 nf_tables_set_elem_destroy(nft_trans_elem_set(trans),
6003 nft_trans_elem(trans).priv);
61edafbb 6004 break;
e5009240 6005 case NFT_MSG_DELOBJ:
00bfb320 6006 nft_obj_destroy(&trans->ctx, nft_trans_obj(trans));
e5009240 6007 break;
3b49e2e9
PNA
6008 case NFT_MSG_DELFLOWTABLE:
6009 nf_tables_flowtable_destroy(nft_trans_flowtable(trans));
6010 break;
c7c32e72
PNA
6011 }
6012 kfree(trans);
6013}
6014
2f99aa31
FW
6015static void nf_tables_commit_release(struct net *net)
6016{
6017 struct nft_trans *trans, *next;
6018
6019 if (list_empty(&net->nft.commit_list))
6020 return;
6021
6022 synchronize_rcu();
6023
6024 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
6025 list_del(&trans->list);
6026 nft_commit_release(trans);
6027 }
6028}
6029
0cbc06b3
FW
6030static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *chain)
6031{
6032 struct nft_rule *rule;
6033 unsigned int alloc = 0;
6034 int i;
6035
6036 /* already handled or inactive chain? */
6037 if (chain->rules_next || !nft_is_active_next(net, chain))
6038 return 0;
6039
6040 rule = list_entry(&chain->rules, struct nft_rule, list);
6041 i = 0;
6042
6043 list_for_each_entry_continue(rule, &chain->rules, list) {
6044 if (nft_is_active_next(net, rule))
6045 alloc++;
6046 }
6047
6048 chain->rules_next = nf_tables_chain_alloc_rules(chain, alloc);
6049 if (!chain->rules_next)
6050 return -ENOMEM;
6051
6052 list_for_each_entry_continue(rule, &chain->rules, list) {
6053 if (nft_is_active_next(net, rule))
6054 chain->rules_next[i++] = rule;
6055 }
6056
6057 chain->rules_next[i] = NULL;
6058 return 0;
6059}
6060
6061static void nf_tables_commit_chain_prepare_cancel(struct net *net)
6062{
6063 struct nft_trans *trans, *next;
6064
6065 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
6066 struct nft_chain *chain = trans->ctx.chain;
6067
6068 if (trans->msg_type == NFT_MSG_NEWRULE ||
6069 trans->msg_type == NFT_MSG_DELRULE) {
6070 kvfree(chain->rules_next);
6071 chain->rules_next = NULL;
6072 }
6073 }
6074}
6075
6076static void __nf_tables_commit_chain_free_rules_old(struct rcu_head *h)
6077{
6078 struct nft_rules_old *o = container_of(h, struct nft_rules_old, h);
6079
6080 kvfree(o->start);
6081}
6082
6083static void nf_tables_commit_chain_free_rules_old(struct nft_rule **rules)
6084{
6085 struct nft_rule **r = rules;
6086 struct nft_rules_old *old;
6087
6088 while (*r)
6089 r++;
6090
6091 r++; /* rcu_head is after end marker */
6092 old = (void *) r;
6093 old->start = rules;
6094
6095 call_rcu(&old->h, __nf_tables_commit_chain_free_rules_old);
6096}
6097
6098static void nf_tables_commit_chain_active(struct net *net, struct nft_chain *chain)
6099{
6100 struct nft_rule **g0, **g1;
6101 bool next_genbit;
6102
6103 next_genbit = nft_gencursor_next(net);
6104
6105 g0 = rcu_dereference_protected(chain->rules_gen_0,
6106 lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES));
6107 g1 = rcu_dereference_protected(chain->rules_gen_1,
6108 lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES));
6109
6110 /* No changes to this chain? */
6111 if (chain->rules_next == NULL) {
6112 /* chain had no change in last or next generation */
6113 if (g0 == g1)
6114 return;
6115 /*
6116 * chain had no change in this generation; make sure next
6117 * one uses same rules as current generation.
6118 */
6119 if (next_genbit) {
6120 rcu_assign_pointer(chain->rules_gen_1, g0);
6121 nf_tables_commit_chain_free_rules_old(g1);
6122 } else {
6123 rcu_assign_pointer(chain->rules_gen_0, g1);
6124 nf_tables_commit_chain_free_rules_old(g0);
6125 }
6126
6127 return;
6128 }
6129
6130 if (next_genbit)
6131 rcu_assign_pointer(chain->rules_gen_1, chain->rules_next);
6132 else
6133 rcu_assign_pointer(chain->rules_gen_0, chain->rules_next);
6134
6135 chain->rules_next = NULL;
6136
6137 if (g0 == g1)
6138 return;
6139
6140 if (next_genbit)
6141 nf_tables_commit_chain_free_rules_old(g1);
6142 else
6143 nf_tables_commit_chain_free_rules_old(g0);
6144}
6145
5913beaf 6146static int nf_tables_commit(struct net *net, struct sk_buff *skb)
37082f93 6147{
37082f93 6148 struct nft_trans *trans, *next;
a3716e70 6149 struct nft_trans_elem *te;
0cbc06b3
FW
6150 struct nft_chain *chain;
6151 struct nft_table *table;
37082f93 6152
a654de8f
PNA
6153 /* 0. Validate ruleset, otherwise roll back for error reporting. */
6154 if (nf_tables_validate(net) < 0)
6155 return -EAGAIN;
6156
0cbc06b3
FW
6157 /* 1. Allocate space for next generation rules_gen_X[] */
6158 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
6159 int ret;
37082f93 6160
0cbc06b3
FW
6161 if (trans->msg_type == NFT_MSG_NEWRULE ||
6162 trans->msg_type == NFT_MSG_DELRULE) {
6163 chain = trans->ctx.chain;
6164
6165 ret = nf_tables_commit_chain_prepare(net, chain);
6166 if (ret < 0) {
6167 nf_tables_commit_chain_prepare_cancel(net);
6168 return ret;
6169 }
6170 }
6171 }
37082f93 6172
0cbc06b3
FW
6173 /* step 2. Make rules_gen_X visible to packet path */
6174 list_for_each_entry(table, &net->nft.tables, list) {
6175 list_for_each_entry(chain, &table->chains, list) {
6176 if (!nft_is_active_next(net, chain))
6177 continue;
6178 nf_tables_commit_chain_active(net, chain);
6179 }
6180 }
6181
6182 /*
6183 * Bump generation counter, invalidate any dump in progress.
6184 * Cannot fail after this point.
37082f93 6185 */
0cbc06b3
FW
6186 while (++net->nft.base_seq == 0);
6187
6188 /* step 3. Start new generation, rules_gen_X now in use. */
6189 net->nft.gencursor = nft_gencursor_next(net);
37082f93
PNA
6190
6191 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
b380e5c7 6192 switch (trans->msg_type) {
55dd6f93
PNA
6193 case NFT_MSG_NEWTABLE:
6194 if (nft_trans_table_update(trans)) {
6195 if (!nft_trans_table_enable(trans)) {
664b0f8c 6196 nf_tables_table_disable(net,
55dd6f93
PNA
6197 trans->ctx.table);
6198 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
6199 }
6200 } else {
f2a6d766 6201 nft_clear(net, trans->ctx.table);
55dd6f93 6202 }
35151d84 6203 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
55dd6f93
PNA
6204 nft_trans_destroy(trans);
6205 break;
6206 case NFT_MSG_DELTABLE:
f2a6d766 6207 list_del_rcu(&trans->ctx.table->list);
35151d84 6208 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
55dd6f93 6209 break;
91c7b38d
PNA
6210 case NFT_MSG_NEWCHAIN:
6211 if (nft_trans_chain_update(trans))
6212 nft_chain_commit_update(trans);
4fefee57 6213 else
664b0f8c 6214 nft_clear(net, trans->ctx.chain);
4fefee57 6215
35151d84 6216 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
91c7b38d
PNA
6217 nft_trans_destroy(trans);
6218 break;
6219 case NFT_MSG_DELCHAIN:
664b0f8c 6220 list_del_rcu(&trans->ctx.chain->list);
35151d84 6221 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
c974a3a3
PNA
6222 nf_tables_unregister_hook(trans->ctx.net,
6223 trans->ctx.table,
6224 trans->ctx.chain);
91c7b38d 6225 break;
b380e5c7 6226 case NFT_MSG_NEWRULE:
889f7ee7 6227 nft_clear(trans->ctx.net, nft_trans_rule(trans));
35151d84 6228 nf_tables_rule_notify(&trans->ctx,
37082f93 6229 nft_trans_rule(trans),
35151d84 6230 NFT_MSG_NEWRULE);
37082f93 6231 nft_trans_destroy(trans);
b380e5c7
PNA
6232 break;
6233 case NFT_MSG_DELRULE:
6234 list_del_rcu(&nft_trans_rule(trans)->list);
35151d84
PNA
6235 nf_tables_rule_notify(&trans->ctx,
6236 nft_trans_rule(trans),
6237 NFT_MSG_DELRULE);
b380e5c7 6238 break;
958bee14 6239 case NFT_MSG_NEWSET:
37a9cc52 6240 nft_clear(net, nft_trans_set(trans));
4fefee57
PNA
6241 /* This avoids hitting -EBUSY when deleting the table
6242 * from the transaction.
6243 */
408070d6 6244 if (nft_set_is_anonymous(nft_trans_set(trans)) &&
4fefee57
PNA
6245 !list_empty(&nft_trans_set(trans)->bindings))
6246 trans->ctx.table->use--;
6247
958bee14 6248 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 6249 NFT_MSG_NEWSET, GFP_KERNEL);
958bee14
PNA
6250 nft_trans_destroy(trans);
6251 break;
6252 case NFT_MSG_DELSET:
37a9cc52 6253 list_del_rcu(&nft_trans_set(trans)->list);
958bee14 6254 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 6255 NFT_MSG_DELSET, GFP_KERNEL);
958bee14 6256 break;
60319eb1 6257 case NFT_MSG_NEWSETELEM:
cc02e457
PM
6258 te = (struct nft_trans_elem *)trans->data;
6259
42a55769 6260 te->set->ops->activate(net, te->set, &te->elem);
cc02e457
PM
6261 nf_tables_setelem_notify(&trans->ctx, te->set,
6262 &te->elem,
60319eb1
PNA
6263 NFT_MSG_NEWSETELEM, 0);
6264 nft_trans_destroy(trans);
6265 break;
6266 case NFT_MSG_DELSETELEM:
a3716e70 6267 te = (struct nft_trans_elem *)trans->data;
fe2811eb 6268
a3716e70
PNA
6269 nf_tables_setelem_notify(&trans->ctx, te->set,
6270 &te->elem,
60319eb1 6271 NFT_MSG_DELSETELEM, 0);
5cb82a38 6272 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a
PM
6273 atomic_dec(&te->set->nelems);
6274 te->set->ndeact--;
60319eb1 6275 break;
e5009240
PNA
6276 case NFT_MSG_NEWOBJ:
6277 nft_clear(net, nft_trans_obj(trans));
6278 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
6279 NFT_MSG_NEWOBJ);
6280 nft_trans_destroy(trans);
6281 break;
6282 case NFT_MSG_DELOBJ:
6283 list_del_rcu(&nft_trans_obj(trans)->list);
6284 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
6285 NFT_MSG_DELOBJ);
6286 break;
3b49e2e9
PNA
6287 case NFT_MSG_NEWFLOWTABLE:
6288 nft_clear(net, nft_trans_flowtable(trans));
6289 nf_tables_flowtable_notify(&trans->ctx,
6290 nft_trans_flowtable(trans),
6291 NFT_MSG_NEWFLOWTABLE);
6292 nft_trans_destroy(trans);
6293 break;
6294 case NFT_MSG_DELFLOWTABLE:
6295 list_del_rcu(&nft_trans_flowtable(trans)->list);
6296 nf_tables_flowtable_notify(&trans->ctx,
6297 nft_trans_flowtable(trans),
6298 NFT_MSG_DELFLOWTABLE);
6299 nft_unregister_flowtable_net_hooks(net,
6300 nft_trans_flowtable(trans));
6301 break;
37082f93 6302 }
37082f93
PNA
6303 }
6304
2f99aa31 6305 nf_tables_commit_release(net);
84d7fce6 6306 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
37082f93
PNA
6307
6308 return 0;
6309}
6310
b326dd37 6311static void nf_tables_abort_release(struct nft_trans *trans)
c7c32e72 6312{
c7c32e72
PNA
6313 switch (trans->msg_type) {
6314 case NFT_MSG_NEWTABLE:
6315 nf_tables_table_destroy(&trans->ctx);
6316 break;
6317 case NFT_MSG_NEWCHAIN:
43a605f2 6318 nf_tables_chain_destroy(&trans->ctx);
c7c32e72
PNA
6319 break;
6320 case NFT_MSG_NEWRULE:
6321 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
6322 break;
6323 case NFT_MSG_NEWSET:
6324 nft_set_destroy(nft_trans_set(trans));
6325 break;
61edafbb
PM
6326 case NFT_MSG_NEWSETELEM:
6327 nft_set_elem_destroy(nft_trans_elem_set(trans),
61f9e292 6328 nft_trans_elem(trans).priv, true);
61edafbb 6329 break;
e5009240 6330 case NFT_MSG_NEWOBJ:
00bfb320 6331 nft_obj_destroy(&trans->ctx, nft_trans_obj(trans));
e5009240 6332 break;
3b49e2e9
PNA
6333 case NFT_MSG_NEWFLOWTABLE:
6334 nf_tables_flowtable_destroy(nft_trans_flowtable(trans));
6335 break;
c7c32e72
PNA
6336 }
6337 kfree(trans);
6338}
6339
5913beaf 6340static int nf_tables_abort(struct net *net, struct sk_buff *skb)
37082f93 6341{
37082f93 6342 struct nft_trans *trans, *next;
02263db0 6343 struct nft_trans_elem *te;
37082f93 6344
a907e36d
XL
6345 list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
6346 list) {
b380e5c7 6347 switch (trans->msg_type) {
55dd6f93
PNA
6348 case NFT_MSG_NEWTABLE:
6349 if (nft_trans_table_update(trans)) {
6350 if (nft_trans_table_enable(trans)) {
664b0f8c 6351 nf_tables_table_disable(net,
55dd6f93
PNA
6352 trans->ctx.table);
6353 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
6354 }
6355 nft_trans_destroy(trans);
6356 } else {
e688a7f8 6357 list_del_rcu(&trans->ctx.table->list);
55dd6f93
PNA
6358 }
6359 break;
6360 case NFT_MSG_DELTABLE:
f2a6d766 6361 nft_clear(trans->ctx.net, trans->ctx.table);
55dd6f93
PNA
6362 nft_trans_destroy(trans);
6363 break;
91c7b38d
PNA
6364 case NFT_MSG_NEWCHAIN:
6365 if (nft_trans_chain_update(trans)) {
982f4051 6366 free_percpu(nft_trans_chain_stats(trans));
91c7b38d
PNA
6367
6368 nft_trans_destroy(trans);
6369 } else {
4fefee57 6370 trans->ctx.table->use--;
e688a7f8 6371 list_del_rcu(&trans->ctx.chain->list);
c974a3a3
PNA
6372 nf_tables_unregister_hook(trans->ctx.net,
6373 trans->ctx.table,
6374 trans->ctx.chain);
91c7b38d
PNA
6375 }
6376 break;
6377 case NFT_MSG_DELCHAIN:
4fefee57 6378 trans->ctx.table->use++;
664b0f8c 6379 nft_clear(trans->ctx.net, trans->ctx.chain);
91c7b38d
PNA
6380 nft_trans_destroy(trans);
6381 break;
b380e5c7 6382 case NFT_MSG_NEWRULE:
4fefee57 6383 trans->ctx.chain->use--;
b380e5c7 6384 list_del_rcu(&nft_trans_rule(trans)->list);
bb7b40ae 6385 nft_rule_expr_deactivate(&trans->ctx, nft_trans_rule(trans));
b380e5c7
PNA
6386 break;
6387 case NFT_MSG_DELRULE:
4fefee57 6388 trans->ctx.chain->use++;
889f7ee7 6389 nft_clear(trans->ctx.net, nft_trans_rule(trans));
bb7b40ae 6390 nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
37082f93 6391 nft_trans_destroy(trans);
b380e5c7 6392 break;
958bee14 6393 case NFT_MSG_NEWSET:
4fefee57 6394 trans->ctx.table->use--;
e688a7f8 6395 list_del_rcu(&nft_trans_set(trans)->list);
958bee14
PNA
6396 break;
6397 case NFT_MSG_DELSET:
4fefee57 6398 trans->ctx.table->use++;
37a9cc52 6399 nft_clear(trans->ctx.net, nft_trans_set(trans));
958bee14
PNA
6400 nft_trans_destroy(trans);
6401 break;
60319eb1 6402 case NFT_MSG_NEWSETELEM:
02263db0 6403 te = (struct nft_trans_elem *)trans->data;
fe2811eb 6404
5cb82a38 6405 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a 6406 atomic_dec(&te->set->nelems);
60319eb1
PNA
6407 break;
6408 case NFT_MSG_DELSETELEM:
cc02e457
PM
6409 te = (struct nft_trans_elem *)trans->data;
6410
59105446 6411 nft_set_elem_activate(net, te->set, &te->elem);
42a55769 6412 te->set->ops->activate(net, te->set, &te->elem);
3dd0673a 6413 te->set->ndeact--;
cc02e457 6414
e5009240
PNA
6415 nft_trans_destroy(trans);
6416 break;
6417 case NFT_MSG_NEWOBJ:
6418 trans->ctx.table->use--;
6419 list_del_rcu(&nft_trans_obj(trans)->list);
6420 break;
6421 case NFT_MSG_DELOBJ:
6422 trans->ctx.table->use++;
6423 nft_clear(trans->ctx.net, nft_trans_obj(trans));
60319eb1
PNA
6424 nft_trans_destroy(trans);
6425 break;
3b49e2e9
PNA
6426 case NFT_MSG_NEWFLOWTABLE:
6427 trans->ctx.table->use--;
6428 list_del_rcu(&nft_trans_flowtable(trans)->list);
6429 nft_unregister_flowtable_net_hooks(net,
6430 nft_trans_flowtable(trans));
6431 break;
6432 case NFT_MSG_DELFLOWTABLE:
6433 trans->ctx.table->use++;
6434 nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
6435 nft_trans_destroy(trans);
6436 break;
37082f93 6437 }
37082f93
PNA
6438 }
6439
b326dd37
PNA
6440 synchronize_rcu();
6441
a1cee076
PNA
6442 list_for_each_entry_safe_reverse(trans, next,
6443 &net->nft.commit_list, list) {
c7c32e72 6444 list_del(&trans->list);
b326dd37 6445 nf_tables_abort_release(trans);
37082f93
PNA
6446 }
6447
6448 return 0;
6449}
6450
a654de8f
PNA
6451static void nf_tables_cleanup(struct net *net)
6452{
6453 nft_validate_state_update(net, NFT_VALIDATE_SKIP);
6454}
6455
74e8bcd2
PNA
6456static bool nf_tables_valid_genid(struct net *net, u32 genid)
6457{
6458 return net->nft.base_seq == genid;
6459}
6460
96518518
PM
6461static const struct nfnetlink_subsystem nf_tables_subsys = {
6462 .name = "nf_tables",
6463 .subsys_id = NFNL_SUBSYS_NFTABLES,
6464 .cb_count = NFT_MSG_MAX,
6465 .cb = nf_tables_cb,
0628b123
PNA
6466 .commit = nf_tables_commit,
6467 .abort = nf_tables_abort,
a654de8f 6468 .cleanup = nf_tables_cleanup,
74e8bcd2 6469 .valid_genid = nf_tables_valid_genid,
96518518
PM
6470};
6471
7210e4e3 6472int nft_chain_validate_dependency(const struct nft_chain *chain,
32537e91 6473 enum nft_chain_types type)
7210e4e3
PNA
6474{
6475 const struct nft_base_chain *basechain;
6476
f323d954 6477 if (nft_is_base_chain(chain)) {
7210e4e3
PNA
6478 basechain = nft_base_chain(chain);
6479 if (basechain->type->type != type)
6480 return -EOPNOTSUPP;
6481 }
6482 return 0;
6483}
6484EXPORT_SYMBOL_GPL(nft_chain_validate_dependency);
6485
75e8d06d
PNA
6486int nft_chain_validate_hooks(const struct nft_chain *chain,
6487 unsigned int hook_flags)
6488{
6489 struct nft_base_chain *basechain;
6490
f323d954 6491 if (nft_is_base_chain(chain)) {
75e8d06d
PNA
6492 basechain = nft_base_chain(chain);
6493
c974a3a3 6494 if ((1 << basechain->ops.hooknum) & hook_flags)
75e8d06d
PNA
6495 return 0;
6496
6497 return -EOPNOTSUPP;
6498 }
6499
6500 return 0;
6501}
6502EXPORT_SYMBOL_GPL(nft_chain_validate_hooks);
6503
20a69341
PM
6504/*
6505 * Loop detection - walk through the ruleset beginning at the destination chain
6506 * of a new jump until either the source chain is reached (loop) or all
6507 * reachable chains have been traversed.
6508 *
6509 * The loop check is performed whenever a new jump verdict is added to an
6510 * expression or verdict map or a verdict map is bound to a new chain.
6511 */
6512
6513static int nf_tables_check_loops(const struct nft_ctx *ctx,
6514 const struct nft_chain *chain);
6515
6516static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
de70185d 6517 struct nft_set *set,
20a69341 6518 const struct nft_set_iter *iter,
de70185d 6519 struct nft_set_elem *elem)
20a69341 6520{
fe2811eb
PM
6521 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
6522 const struct nft_data *data;
6523
6524 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
6525 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
62f9c8b4
PNA
6526 return 0;
6527
fe2811eb 6528 data = nft_set_ext_data(ext);
1ca2e170 6529 switch (data->verdict.code) {
20a69341
PM
6530 case NFT_JUMP:
6531 case NFT_GOTO:
1ca2e170 6532 return nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
6533 default:
6534 return 0;
6535 }
6536}
6537
6538static int nf_tables_check_loops(const struct nft_ctx *ctx,
6539 const struct nft_chain *chain)
6540{
6541 const struct nft_rule *rule;
6542 const struct nft_expr *expr, *last;
de70185d 6543 struct nft_set *set;
20a69341
PM
6544 struct nft_set_binding *binding;
6545 struct nft_set_iter iter;
20a69341
PM
6546
6547 if (ctx->chain == chain)
6548 return -ELOOP;
6549
6550 list_for_each_entry(rule, &chain->rules, list) {
6551 nft_rule_for_each_expr(expr, last, rule) {
a654de8f
PNA
6552 struct nft_immediate_expr *priv;
6553 const struct nft_data *data;
0ca743a5
PNA
6554 int err;
6555
a654de8f 6556 if (strcmp(expr->ops->type->name, "immediate"))
20a69341
PM
6557 continue;
6558
a654de8f
PNA
6559 priv = nft_expr_priv(expr);
6560 if (priv->dreg != NFT_REG_VERDICT)
0ca743a5 6561 continue;
20a69341 6562
a654de8f 6563 data = &priv->data;
1ca2e170 6564 switch (data->verdict.code) {
20a69341
PM
6565 case NFT_JUMP:
6566 case NFT_GOTO:
1ca2e170
PM
6567 err = nf_tables_check_loops(ctx,
6568 data->verdict.chain);
20a69341
PM
6569 if (err < 0)
6570 return err;
6571 default:
6572 break;
6573 }
6574 }
6575 }
6576
6577 list_for_each_entry(set, &ctx->table->sets, list) {
37a9cc52
PNA
6578 if (!nft_is_active_next(ctx->net, set))
6579 continue;
20a69341
PM
6580 if (!(set->flags & NFT_SET_MAP) ||
6581 set->dtype != NFT_DATA_VERDICT)
6582 continue;
6583
6584 list_for_each_entry(binding, &set->bindings, list) {
11113e19
PM
6585 if (!(binding->flags & NFT_SET_MAP) ||
6586 binding->chain != chain)
20a69341
PM
6587 continue;
6588
8588ac09 6589 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
6590 iter.skip = 0;
6591 iter.count = 0;
6592 iter.err = 0;
6593 iter.fn = nf_tables_loop_check_setelem;
6594
6595 set->ops->walk(ctx, set, &iter);
6596 if (iter.err < 0)
6597 return iter.err;
6598 }
6599 }
6600
6601 return 0;
6602}
6603
36b701fa
LGL
6604/**
6605 * nft_parse_u32_check - fetch u32 attribute and check for maximum value
6606 *
6607 * @attr: netlink attribute to fetch value from
6608 * @max: maximum value to be stored in dest
6609 * @dest: pointer to the variable
6610 *
6611 * Parse, check and store a given u32 netlink attribute into variable.
6612 * This function returns -ERANGE if the value goes over maximum value.
6613 * Otherwise a 0 is returned and the attribute value is stored in the
6614 * destination variable.
6615 */
f1d505bb 6616int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
36b701fa 6617{
09525a09 6618 u32 val;
36b701fa
LGL
6619
6620 val = ntohl(nla_get_be32(attr));
6621 if (val > max)
6622 return -ERANGE;
6623
6624 *dest = val;
6625 return 0;
6626}
6627EXPORT_SYMBOL_GPL(nft_parse_u32_check);
6628
49499c3e
PM
6629/**
6630 * nft_parse_register - parse a register value from a netlink attribute
6631 *
6632 * @attr: netlink attribute
6633 *
6634 * Parse and translate a register value from a netlink attribute.
6635 * Registers used to be 128 bit wide, these register numbers will be
6636 * mapped to the corresponding 32 bit register numbers.
6637 */
b1c96ed3
PM
6638unsigned int nft_parse_register(const struct nlattr *attr)
6639{
49499c3e
PM
6640 unsigned int reg;
6641
6642 reg = ntohl(nla_get_be32(attr));
6643 switch (reg) {
6644 case NFT_REG_VERDICT...NFT_REG_4:
6645 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
6646 default:
6647 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
6648 }
b1c96ed3
PM
6649}
6650EXPORT_SYMBOL_GPL(nft_parse_register);
6651
49499c3e
PM
6652/**
6653 * nft_dump_register - dump a register value to a netlink attribute
6654 *
6655 * @skb: socket buffer
6656 * @attr: attribute number
6657 * @reg: register number
6658 *
6659 * Construct a netlink attribute containing the register number. For
6660 * compatibility reasons, register numbers being a multiple of 4 are
6661 * translated to the corresponding 128 bit register numbers.
6662 */
b1c96ed3
PM
6663int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
6664{
49499c3e
PM
6665 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
6666 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
6667 else
6668 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
6669
b1c96ed3
PM
6670 return nla_put_be32(skb, attr, htonl(reg));
6671}
6672EXPORT_SYMBOL_GPL(nft_dump_register);
6673
96518518 6674/**
d07db988 6675 * nft_validate_register_load - validate a load from a register
96518518
PM
6676 *
6677 * @reg: the register number
d07db988 6678 * @len: the length of the data
96518518
PM
6679 *
6680 * Validate that the input register is one of the general purpose
d07db988 6681 * registers and that the length of the load is within the bounds.
96518518 6682 */
d07db988 6683int nft_validate_register_load(enum nft_registers reg, unsigned int len)
96518518 6684{
49499c3e 6685 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
96518518 6686 return -EINVAL;
d07db988
PM
6687 if (len == 0)
6688 return -EINVAL;
49499c3e 6689 if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
d07db988 6690 return -ERANGE;
49499c3e 6691
96518518
PM
6692 return 0;
6693}
d07db988 6694EXPORT_SYMBOL_GPL(nft_validate_register_load);
96518518 6695
96518518 6696/**
1ec10212 6697 * nft_validate_register_store - validate an expressions' register store
96518518
PM
6698 *
6699 * @ctx: context of the expression performing the load
6700 * @reg: the destination register number
6701 * @data: the data to load
6702 * @type: the data type
45d9bcda 6703 * @len: the length of the data
96518518
PM
6704 *
6705 * Validate that a data load uses the appropriate data type for
45d9bcda
PM
6706 * the destination register and the length is within the bounds.
6707 * A value of NULL for the data means that its runtime gathered
58f40ab6 6708 * data.
96518518 6709 */
1ec10212
PM
6710int nft_validate_register_store(const struct nft_ctx *ctx,
6711 enum nft_registers reg,
6712 const struct nft_data *data,
6713 enum nft_data_types type, unsigned int len)
96518518 6714{
20a69341
PM
6715 int err;
6716
96518518
PM
6717 switch (reg) {
6718 case NFT_REG_VERDICT:
58f40ab6 6719 if (type != NFT_DATA_VERDICT)
96518518 6720 return -EINVAL;
20a69341 6721
58f40ab6 6722 if (data != NULL &&
1ca2e170
PM
6723 (data->verdict.code == NFT_GOTO ||
6724 data->verdict.code == NFT_JUMP)) {
6725 err = nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
6726 if (err < 0)
6727 return err;
6728
1ca2e170
PM
6729 if (ctx->chain->level + 1 >
6730 data->verdict.chain->level) {
20a69341
PM
6731 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
6732 return -EMLINK;
1ca2e170 6733 data->verdict.chain->level = ctx->chain->level + 1;
20a69341
PM
6734 }
6735 }
6736
96518518
PM
6737 return 0;
6738 default:
49499c3e 6739 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
27e6d201 6740 return -EINVAL;
45d9bcda
PM
6741 if (len == 0)
6742 return -EINVAL;
49499c3e
PM
6743 if (reg * NFT_REG32_SIZE + len >
6744 FIELD_SIZEOF(struct nft_regs, data))
45d9bcda 6745 return -ERANGE;
27e6d201 6746
96518518
PM
6747 if (data != NULL && type != NFT_DATA_VALUE)
6748 return -EINVAL;
6749 return 0;
6750 }
6751}
1ec10212 6752EXPORT_SYMBOL_GPL(nft_validate_register_store);
96518518
PM
6753
6754static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
6755 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
6756 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
6757 .len = NFT_CHAIN_MAXNAMELEN - 1 },
6758};
6759
6760static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
6761 struct nft_data_desc *desc, const struct nlattr *nla)
6762{
664b0f8c 6763 u8 genmask = nft_genmask_next(ctx->net);
96518518
PM
6764 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
6765 struct nft_chain *chain;
6766 int err;
6767
fceb6435
JB
6768 err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy,
6769 NULL);
96518518
PM
6770 if (err < 0)
6771 return err;
6772
6773 if (!tb[NFTA_VERDICT_CODE])
6774 return -EINVAL;
1ca2e170 6775 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
96518518 6776
1ca2e170 6777 switch (data->verdict.code) {
e0abdadc 6778 default:
1ca2e170 6779 switch (data->verdict.code & NF_VERDICT_MASK) {
e0abdadc
PM
6780 case NF_ACCEPT:
6781 case NF_DROP:
6782 case NF_QUEUE:
6783 break;
6784 default:
6785 return -EINVAL;
6786 }
6787 /* fall through */
96518518
PM
6788 case NFT_CONTINUE:
6789 case NFT_BREAK:
6790 case NFT_RETURN:
96518518
PM
6791 break;
6792 case NFT_JUMP:
6793 case NFT_GOTO:
6794 if (!tb[NFTA_VERDICT_CHAIN])
6795 return -EINVAL;
cac20fcd
PNA
6796 chain = nft_chain_lookup(ctx->table, tb[NFTA_VERDICT_CHAIN],
6797 genmask);
96518518
PM
6798 if (IS_ERR(chain))
6799 return PTR_ERR(chain);
f323d954 6800 if (nft_is_base_chain(chain))
96518518
PM
6801 return -EOPNOTSUPP;
6802
96518518 6803 chain->use++;
1ca2e170 6804 data->verdict.chain = chain;
96518518 6805 break;
96518518
PM
6806 }
6807
4c4ed074 6808 desc->len = sizeof(data->verdict);
96518518
PM
6809 desc->type = NFT_DATA_VERDICT;
6810 return 0;
6811}
6812
6813static void nft_verdict_uninit(const struct nft_data *data)
6814{
1ca2e170 6815 switch (data->verdict.code) {
96518518
PM
6816 case NFT_JUMP:
6817 case NFT_GOTO:
1ca2e170 6818 data->verdict.chain->use--;
96518518
PM
6819 break;
6820 }
6821}
6822
33d5a7b1 6823int nft_verdict_dump(struct sk_buff *skb, int type, const struct nft_verdict *v)
96518518
PM
6824{
6825 struct nlattr *nest;
6826
33d5a7b1 6827 nest = nla_nest_start(skb, type);
96518518
PM
6828 if (!nest)
6829 goto nla_put_failure;
6830
33d5a7b1 6831 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(v->code)))
96518518
PM
6832 goto nla_put_failure;
6833
33d5a7b1 6834 switch (v->code) {
96518518
PM
6835 case NFT_JUMP:
6836 case NFT_GOTO:
1ca2e170 6837 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
33d5a7b1 6838 v->chain->name))
96518518
PM
6839 goto nla_put_failure;
6840 }
6841 nla_nest_end(skb, nest);
6842 return 0;
6843
6844nla_put_failure:
6845 return -1;
6846}
6847
d0a11fc3
PM
6848static int nft_value_init(const struct nft_ctx *ctx,
6849 struct nft_data *data, unsigned int size,
96518518
PM
6850 struct nft_data_desc *desc, const struct nlattr *nla)
6851{
6852 unsigned int len;
6853
6854 len = nla_len(nla);
6855 if (len == 0)
6856 return -EINVAL;
d0a11fc3 6857 if (len > size)
96518518
PM
6858 return -EOVERFLOW;
6859
d0a11fc3 6860 nla_memcpy(data->data, nla, len);
96518518
PM
6861 desc->type = NFT_DATA_VALUE;
6862 desc->len = len;
6863 return 0;
6864}
6865
6866static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
6867 unsigned int len)
6868{
6869 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
6870}
6871
6872static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
d0a11fc3 6873 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
96518518
PM
6874 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
6875};
6876
6877/**
6878 * nft_data_init - parse nf_tables data netlink attributes
6879 *
6880 * @ctx: context of the expression using the data
6881 * @data: destination struct nft_data
d0a11fc3 6882 * @size: maximum data length
96518518
PM
6883 * @desc: data description
6884 * @nla: netlink attribute containing data
6885 *
6886 * Parse the netlink data attributes and initialize a struct nft_data.
6887 * The type and length of data are returned in the data description.
6888 *
6889 * The caller can indicate that it only wants to accept data of type
6890 * NFT_DATA_VALUE by passing NULL for the ctx argument.
6891 */
d0a11fc3
PM
6892int nft_data_init(const struct nft_ctx *ctx,
6893 struct nft_data *data, unsigned int size,
96518518
PM
6894 struct nft_data_desc *desc, const struct nlattr *nla)
6895{
6896 struct nlattr *tb[NFTA_DATA_MAX + 1];
6897 int err;
6898
fceb6435 6899 err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy, NULL);
96518518
PM
6900 if (err < 0)
6901 return err;
6902
6903 if (tb[NFTA_DATA_VALUE])
d0a11fc3
PM
6904 return nft_value_init(ctx, data, size, desc,
6905 tb[NFTA_DATA_VALUE]);
96518518
PM
6906 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
6907 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
6908 return -EINVAL;
6909}
6910EXPORT_SYMBOL_GPL(nft_data_init);
6911
6912/**
59105446 6913 * nft_data_release - release a nft_data item
96518518
PM
6914 *
6915 * @data: struct nft_data to release
6916 * @type: type of data
6917 *
6918 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
6919 * all others need to be released by calling this function.
6920 */
59105446 6921void nft_data_release(const struct nft_data *data, enum nft_data_types type)
96518518 6922{
960bd2c2 6923 if (type < NFT_DATA_VERDICT)
96518518 6924 return;
960bd2c2 6925 switch (type) {
96518518
PM
6926 case NFT_DATA_VERDICT:
6927 return nft_verdict_uninit(data);
6928 default:
6929 WARN_ON(1);
6930 }
6931}
59105446 6932EXPORT_SYMBOL_GPL(nft_data_release);
96518518
PM
6933
6934int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
6935 enum nft_data_types type, unsigned int len)
6936{
6937 struct nlattr *nest;
6938 int err;
6939
6940 nest = nla_nest_start(skb, attr);
6941 if (nest == NULL)
6942 return -1;
6943
6944 switch (type) {
6945 case NFT_DATA_VALUE:
6946 err = nft_value_dump(skb, data, len);
6947 break;
6948 case NFT_DATA_VERDICT:
33d5a7b1 6949 err = nft_verdict_dump(skb, NFTA_DATA_VERDICT, &data->verdict);
96518518
PM
6950 break;
6951 default:
6952 err = -EINVAL;
6953 WARN_ON(1);
6954 }
6955
6956 nla_nest_end(skb, nest);
6957 return err;
6958}
6959EXPORT_SYMBOL_GPL(nft_data_dump);
6960
5ebe0b0e
PNA
6961int __nft_release_basechain(struct nft_ctx *ctx)
6962{
6963 struct nft_rule *rule, *nr;
6964
f323d954 6965 BUG_ON(!nft_is_base_chain(ctx->chain));
5ebe0b0e 6966
c974a3a3 6967 nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
5ebe0b0e
PNA
6968 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
6969 list_del(&rule->list);
6970 ctx->chain->use--;
bb7b40ae 6971 nf_tables_rule_release(ctx, rule);
5ebe0b0e
PNA
6972 }
6973 list_del(&ctx->chain->list);
6974 ctx->table->use--;
43a605f2 6975 nf_tables_chain_destroy(ctx);
5ebe0b0e
PNA
6976
6977 return 0;
6978}
6979EXPORT_SYMBOL_GPL(__nft_release_basechain);
6980
98319cb9 6981static void __nft_release_tables(struct net *net)
df05ef87 6982{
3b49e2e9 6983 struct nft_flowtable *flowtable, *nf;
df05ef87
PNA
6984 struct nft_table *table, *nt;
6985 struct nft_chain *chain, *nc;
e5009240 6986 struct nft_object *obj, *ne;
df05ef87
PNA
6987 struct nft_rule *rule, *nr;
6988 struct nft_set *set, *ns;
6989 struct nft_ctx ctx = {
6990 .net = net,
43a605f2 6991 .family = NFPROTO_NETDEV,
df05ef87
PNA
6992 };
6993
36596dad 6994 list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
98319cb9 6995 ctx.family = table->family;
dd4cbef7 6996
df05ef87 6997 list_for_each_entry(chain, &table->chains, list)
c974a3a3 6998 nf_tables_unregister_hook(net, table, chain);
3b49e2e9
PNA
6999 list_for_each_entry(flowtable, &table->flowtables, list)
7000 nf_unregister_net_hooks(net, flowtable->ops,
7001 flowtable->ops_len);
df05ef87
PNA
7002 /* No packets are walking on these chains anymore. */
7003 ctx.table = table;
7004 list_for_each_entry(chain, &table->chains, list) {
7005 ctx.chain = chain;
7006 list_for_each_entry_safe(rule, nr, &chain->rules, list) {
7007 list_del(&rule->list);
7008 chain->use--;
bb7b40ae 7009 nf_tables_rule_release(&ctx, rule);
df05ef87
PNA
7010 }
7011 }
3b49e2e9
PNA
7012 list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
7013 list_del(&flowtable->list);
7014 table->use--;
7015 nf_tables_flowtable_destroy(flowtable);
7016 }
df05ef87
PNA
7017 list_for_each_entry_safe(set, ns, &table->sets, list) {
7018 list_del(&set->list);
7019 table->use--;
7020 nft_set_destroy(set);
7021 }
e5009240
PNA
7022 list_for_each_entry_safe(obj, ne, &table->objects, list) {
7023 list_del(&obj->list);
7024 table->use--;
00bfb320 7025 nft_obj_destroy(&ctx, obj);
e5009240 7026 }
df05ef87 7027 list_for_each_entry_safe(chain, nc, &table->chains, list) {
43a605f2 7028 ctx.chain = chain;
df05ef87
PNA
7029 list_del(&chain->list);
7030 table->use--;
43a605f2 7031 nf_tables_chain_destroy(&ctx);
df05ef87
PNA
7032 }
7033 list_del(&table->list);
7034 nf_tables_table_destroy(&ctx);
7035 }
7036}
7037
dd4cbef7
PNA
7038static int __net_init nf_tables_init_net(struct net *net)
7039{
7040 INIT_LIST_HEAD(&net->nft.tables);
7041 INIT_LIST_HEAD(&net->nft.commit_list);
7042 net->nft.base_seq = 1;
a654de8f
PNA
7043 net->nft.validate_state = NFT_VALIDATE_SKIP;
7044
dd4cbef7
PNA
7045 return 0;
7046}
7047
7048static void __net_exit nf_tables_exit_net(struct net *net)
7049{
98319cb9 7050 __nft_release_tables(net);
dd4cbef7
PNA
7051 WARN_ON_ONCE(!list_empty(&net->nft.tables));
7052 WARN_ON_ONCE(!list_empty(&net->nft.commit_list));
7053}
7054
99633ab2
PNA
7055static struct pernet_operations nf_tables_net_ops = {
7056 .init = nf_tables_init_net,
613d0776 7057 .exit = nf_tables_exit_net,
99633ab2
PNA
7058};
7059
96518518
PM
7060static int __init nf_tables_module_init(void)
7061{
7062 int err;
7063
02c7b25e
PNA
7064 nft_chain_filter_init();
7065
96518518
PM
7066 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
7067 GFP_KERNEL);
7068 if (info == NULL) {
7069 err = -ENOMEM;
7070 goto err1;
7071 }
7072
7073 err = nf_tables_core_module_init();
7074 if (err < 0)
7075 goto err2;
7076
7077 err = nfnetlink_subsys_register(&nf_tables_subsys);
7078 if (err < 0)
7079 goto err3;
7080
3b49e2e9
PNA
7081 register_netdevice_notifier(&nf_tables_flowtable_notifier);
7082
99633ab2 7083 return register_pernet_subsys(&nf_tables_net_ops);
96518518
PM
7084err3:
7085 nf_tables_core_module_exit();
7086err2:
7087 kfree(info);
7088err1:
7089 return err;
7090}
7091
7092static void __exit nf_tables_module_exit(void)
7093{
99633ab2 7094 unregister_pernet_subsys(&nf_tables_net_ops);
96518518 7095 nfnetlink_subsys_unregister(&nf_tables_subsys);
3b49e2e9 7096 unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
1b1bc49c 7097 rcu_barrier();
96518518
PM
7098 nf_tables_core_module_exit();
7099 kfree(info);
02c7b25e 7100 nft_chain_filter_fini();
96518518
PM
7101}
7102
7103module_init(nf_tables_module_init);
7104module_exit(nf_tables_module_exit);
7105
7106MODULE_LICENSE("GPL");
7107MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
7108MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);