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