]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/netfilter/nf_tables_api.c
netfilter: nft_objref: support for stateful object maps
[mirror_ubuntu-jammy-kernel.git] / net / netfilter / nf_tables_api.c
CommitLineData
96518518 1/*
20a69341 2 * Copyright (c) 2007-2009 Patrick McHardy <kaber@trash.net>
96518518
PM
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 */
10
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/list.h>
14#include <linux/skbuff.h>
15#include <linux/netlink.h>
16#include <linux/netfilter.h>
17#include <linux/netfilter/nfnetlink.h>
18#include <linux/netfilter/nf_tables.h>
19#include <net/netfilter/nf_tables_core.h>
20#include <net/netfilter/nf_tables.h>
99633ab2 21#include <net/net_namespace.h>
96518518
PM
22#include <net/sock.h>
23
96518518 24static LIST_HEAD(nf_tables_expressions);
e5009240 25static LIST_HEAD(nf_tables_objects);
96518518
PM
26
27/**
28 * nft_register_afinfo - register nf_tables address family info
29 *
30 * @afi: address family info to register
31 *
32 * Register the address family for use with nf_tables. Returns zero on
33 * success or a negative errno code otherwise.
34 */
99633ab2 35int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
96518518
PM
36{
37 INIT_LIST_HEAD(&afi->tables);
38 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 39 list_add_tail_rcu(&afi->list, &net->nft.af_info);
96518518
PM
40 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
41 return 0;
42}
43EXPORT_SYMBOL_GPL(nft_register_afinfo);
44
df05ef87
PNA
45static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi);
46
96518518
PM
47/**
48 * nft_unregister_afinfo - unregister nf_tables address family info
49 *
50 * @afi: address family info to unregister
51 *
52 * Unregister the address family for use with nf_tables.
53 */
df05ef87 54void nft_unregister_afinfo(struct net *net, struct nft_af_info *afi)
96518518
PM
55{
56 nfnl_lock(NFNL_SUBSYS_NFTABLES);
df05ef87 57 __nft_release_afinfo(net, afi);
e688a7f8 58 list_del_rcu(&afi->list);
96518518
PM
59 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
60}
61EXPORT_SYMBOL_GPL(nft_unregister_afinfo);
62
99633ab2 63static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family)
96518518
PM
64{
65 struct nft_af_info *afi;
66
99633ab2 67 list_for_each_entry(afi, &net->nft.af_info, list) {
96518518
PM
68 if (afi->family == family)
69 return afi;
70 }
71 return NULL;
72}
73
99633ab2
PNA
74static struct nft_af_info *
75nf_tables_afinfo_lookup(struct net *net, int family, bool autoload)
96518518
PM
76{
77 struct nft_af_info *afi;
78
99633ab2 79 afi = nft_afinfo_lookup(net, family);
96518518
PM
80 if (afi != NULL)
81 return afi;
82#ifdef CONFIG_MODULES
83 if (autoload) {
84 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
85 request_module("nft-afinfo-%u", family);
86 nfnl_lock(NFNL_SUBSYS_NFTABLES);
99633ab2 87 afi = nft_afinfo_lookup(net, family);
96518518
PM
88 if (afi != NULL)
89 return ERR_PTR(-EAGAIN);
90 }
91#endif
92 return ERR_PTR(-EAFNOSUPPORT);
93}
94
7c95f6d8 95static void nft_ctx_init(struct nft_ctx *ctx,
633c9a84 96 struct net *net,
7c95f6d8
PNA
97 const struct sk_buff *skb,
98 const struct nlmsghdr *nlh,
99 struct nft_af_info *afi,
100 struct nft_table *table,
101 struct nft_chain *chain,
102 const struct nlattr * const *nla)
103{
633c9a84 104 ctx->net = net;
128ad332
PNA
105 ctx->afi = afi;
106 ctx->table = table;
107 ctx->chain = chain;
108 ctx->nla = nla;
109 ctx->portid = NETLINK_CB(skb).portid;
110 ctx->report = nlmsg_report(nlh);
111 ctx->seq = nlh->nlmsg_seq;
7c95f6d8
PNA
112}
113
b380e5c7
PNA
114static struct nft_trans *nft_trans_alloc(struct nft_ctx *ctx, int msg_type,
115 u32 size)
1081d11b
PNA
116{
117 struct nft_trans *trans;
118
119 trans = kzalloc(sizeof(struct nft_trans) + size, GFP_KERNEL);
120 if (trans == NULL)
121 return NULL;
122
b380e5c7 123 trans->msg_type = msg_type;
1081d11b
PNA
124 trans->ctx = *ctx;
125
126 return trans;
127}
128
129static void nft_trans_destroy(struct nft_trans *trans)
130{
131 list_del(&trans->list);
132 kfree(trans);
133}
134
82bec71d
PNA
135static int nf_tables_register_hooks(struct net *net,
136 const struct nft_table *table,
d8ee8f7c
PNA
137 struct nft_chain *chain,
138 unsigned int hook_nops)
139{
140 if (table->flags & NFT_TABLE_F_DORMANT ||
141 !(chain->flags & NFT_BASE_CHAIN))
142 return 0;
143
82bec71d
PNA
144 return nf_register_net_hooks(net, nft_base_chain(chain)->ops,
145 hook_nops);
d8ee8f7c
PNA
146}
147
82bec71d
PNA
148static void nf_tables_unregister_hooks(struct net *net,
149 const struct nft_table *table,
d8ee8f7c 150 struct nft_chain *chain,
c5598794
AB
151 unsigned int hook_nops)
152{
d8ee8f7c
PNA
153 if (table->flags & NFT_TABLE_F_DORMANT ||
154 !(chain->flags & NFT_BASE_CHAIN))
155 return;
156
82bec71d 157 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, hook_nops);
c5598794
AB
158}
159
ee01d542
AB
160static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
161{
162 struct nft_trans *trans;
163
164 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
165 if (trans == NULL)
166 return -ENOMEM;
167
168 if (msg_type == NFT_MSG_NEWTABLE)
f2a6d766 169 nft_activate_next(ctx->net, ctx->table);
ee01d542
AB
170
171 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
172 return 0;
173}
174
175static int nft_deltable(struct nft_ctx *ctx)
176{
177 int err;
178
179 err = nft_trans_table_add(ctx, NFT_MSG_DELTABLE);
180 if (err < 0)
181 return err;
182
f2a6d766 183 nft_deactivate_next(ctx->net, ctx->table);
ee01d542
AB
184 return err;
185}
186
187static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
188{
189 struct nft_trans *trans;
190
191 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
192 if (trans == NULL)
193 return -ENOMEM;
194
195 if (msg_type == NFT_MSG_NEWCHAIN)
664b0f8c 196 nft_activate_next(ctx->net, ctx->chain);
ee01d542
AB
197
198 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
199 return 0;
200}
201
202static int nft_delchain(struct nft_ctx *ctx)
203{
204 int err;
205
206 err = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
207 if (err < 0)
208 return err;
209
210 ctx->table->use--;
664b0f8c 211 nft_deactivate_next(ctx->net, ctx->chain);
ee01d542
AB
212
213 return err;
214}
215
ee01d542
AB
216static int
217nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
218{
219 /* You cannot delete the same rule twice */
889f7ee7
PNA
220 if (nft_is_active_next(ctx->net, rule)) {
221 nft_deactivate_next(ctx->net, rule);
ee01d542
AB
222 ctx->chain->use--;
223 return 0;
224 }
225 return -ENOENT;
226}
227
228static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
229 struct nft_rule *rule)
230{
231 struct nft_trans *trans;
232
233 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
234 if (trans == NULL)
235 return NULL;
236
237 nft_trans_rule(trans) = rule;
238 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
239
240 return trans;
241}
242
243static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
244{
245 struct nft_trans *trans;
246 int err;
247
248 trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
249 if (trans == NULL)
250 return -ENOMEM;
251
252 err = nf_tables_delrule_deactivate(ctx, rule);
253 if (err < 0) {
254 nft_trans_destroy(trans);
255 return err;
256 }
257
258 return 0;
259}
260
261static int nft_delrule_by_chain(struct nft_ctx *ctx)
262{
263 struct nft_rule *rule;
264 int err;
265
266 list_for_each_entry(rule, &ctx->chain->rules, list) {
267 err = nft_delrule(ctx, rule);
268 if (err < 0)
269 return err;
270 }
271 return 0;
272}
273
ee01d542
AB
274static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
275 struct nft_set *set)
276{
277 struct nft_trans *trans;
278
279 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
280 if (trans == NULL)
281 return -ENOMEM;
282
283 if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
284 nft_trans_set_id(trans) =
285 ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
37a9cc52 286 nft_activate_next(ctx->net, set);
ee01d542
AB
287 }
288 nft_trans_set(trans) = set;
289 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
290
291 return 0;
292}
293
294static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
295{
296 int err;
297
298 err = nft_trans_set_add(ctx, NFT_MSG_DELSET, set);
299 if (err < 0)
300 return err;
301
37a9cc52 302 nft_deactivate_next(ctx->net, set);
ee01d542
AB
303 ctx->table->use--;
304
305 return err;
306}
307
e5009240
PNA
308static int nft_trans_obj_add(struct nft_ctx *ctx, int msg_type,
309 struct nft_object *obj)
310{
311 struct nft_trans *trans;
312
313 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_obj));
314 if (trans == NULL)
315 return -ENOMEM;
316
317 if (msg_type == NFT_MSG_NEWOBJ)
318 nft_activate_next(ctx->net, obj);
319
320 nft_trans_obj(trans) = obj;
321 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
322
323 return 0;
324}
325
326static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj)
327{
328 int err;
329
330 err = nft_trans_obj_add(ctx, NFT_MSG_DELOBJ, obj);
331 if (err < 0)
332 return err;
333
334 nft_deactivate_next(ctx->net, obj);
335 ctx->table->use--;
336
337 return err;
338}
339
96518518
PM
340/*
341 * Tables
342 */
343
344static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
f2a6d766
PNA
345 const struct nlattr *nla,
346 u8 genmask)
96518518
PM
347{
348 struct nft_table *table;
349
350 list_for_each_entry(table, &afi->tables, list) {
f2a6d766
PNA
351 if (!nla_strcmp(nla, table->name) &&
352 nft_active_genmask(table, genmask))
96518518
PM
353 return table;
354 }
355 return NULL;
356}
357
358static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
f2a6d766
PNA
359 const struct nlattr *nla,
360 u8 genmask)
96518518
PM
361{
362 struct nft_table *table;
363
364 if (nla == NULL)
365 return ERR_PTR(-EINVAL);
366
f2a6d766 367 table = nft_table_lookup(afi, nla, genmask);
96518518
PM
368 if (table != NULL)
369 return table;
370
96518518
PM
371 return ERR_PTR(-ENOENT);
372}
373
374static inline u64 nf_tables_alloc_handle(struct nft_table *table)
375{
376 return ++table->hgenerator;
377}
378
2a37d755 379static const struct nf_chain_type *chain_type[AF_MAX][NFT_CHAIN_T_MAX];
9370761c 380
2a37d755 381static const struct nf_chain_type *
baae3e62 382__nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
9370761c
PNA
383{
384 int i;
385
baae3e62 386 for (i = 0; i < NFT_CHAIN_T_MAX; i++) {
9370761c
PNA
387 if (chain_type[family][i] != NULL &&
388 !nla_strcmp(nla, chain_type[family][i]->name))
baae3e62 389 return chain_type[family][i];
9370761c 390 }
baae3e62 391 return NULL;
9370761c
PNA
392}
393
2a37d755 394static const struct nf_chain_type *
baae3e62
PM
395nf_tables_chain_type_lookup(const struct nft_af_info *afi,
396 const struct nlattr *nla,
397 bool autoload)
9370761c 398{
2a37d755 399 const struct nf_chain_type *type;
9370761c
PNA
400
401 type = __nf_tables_chain_type_lookup(afi->family, nla);
93b0806f
PM
402 if (type != NULL)
403 return type;
9370761c 404#ifdef CONFIG_MODULES
93b0806f 405 if (autoload) {
9370761c 406 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2fec6bb6
PNA
407 request_module("nft-chain-%u-%.*s", afi->family,
408 nla_len(nla), (const char *)nla_data(nla));
9370761c
PNA
409 nfnl_lock(NFNL_SUBSYS_NFTABLES);
410 type = __nf_tables_chain_type_lookup(afi->family, nla);
93b0806f
PM
411 if (type != NULL)
412 return ERR_PTR(-EAGAIN);
9370761c
PNA
413 }
414#endif
93b0806f 415 return ERR_PTR(-ENOENT);
9370761c
PNA
416}
417
96518518 418static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
1cae565e
PNA
419 [NFTA_TABLE_NAME] = { .type = NLA_STRING,
420 .len = NFT_TABLE_MAXNAMELEN - 1 },
9ddf6323 421 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
96518518
PM
422};
423
84d7fce6
PNA
424static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
425 u32 portid, u32 seq, int event, u32 flags,
426 int family, const struct nft_table *table)
96518518
PM
427{
428 struct nlmsghdr *nlh;
429 struct nfgenmsg *nfmsg;
430
431 event |= NFNL_SUBSYS_NFTABLES << 8;
432 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
433 if (nlh == NULL)
434 goto nla_put_failure;
435
436 nfmsg = nlmsg_data(nlh);
437 nfmsg->nfgen_family = family;
438 nfmsg->version = NFNETLINK_V0;
84d7fce6 439 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518 440
9ddf6323 441 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
d8bcc768
TB
442 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||
443 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
96518518
PM
444 goto nla_put_failure;
445
053c095a
JB
446 nlmsg_end(skb, nlh);
447 return 0;
96518518
PM
448
449nla_put_failure:
450 nlmsg_trim(skb, nlh);
451 return -1;
452}
453
35151d84 454static int nf_tables_table_notify(const struct nft_ctx *ctx, int event)
96518518
PM
455{
456 struct sk_buff *skb;
96518518
PM
457 int err;
458
128ad332
PNA
459 if (!ctx->report &&
460 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
96518518
PM
461 return 0;
462
463 err = -ENOBUFS;
464 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
465 if (skb == NULL)
466 goto err;
467
84d7fce6
PNA
468 err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
469 event, 0, ctx->afi->family, ctx->table);
96518518
PM
470 if (err < 0) {
471 kfree_skb(skb);
472 goto err;
473 }
474
128ad332
PNA
475 err = nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
476 ctx->report, GFP_KERNEL);
96518518 477err:
128ad332
PNA
478 if (err < 0) {
479 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES,
480 err);
481 }
96518518
PM
482 return err;
483}
484
485static int nf_tables_dump_tables(struct sk_buff *skb,
486 struct netlink_callback *cb)
487{
488 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
489 const struct nft_af_info *afi;
490 const struct nft_table *table;
491 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 492 struct net *net = sock_net(skb->sk);
96518518
PM
493 int family = nfmsg->nfgen_family;
494
e688a7f8 495 rcu_read_lock();
38e029f1
PNA
496 cb->seq = net->nft.base_seq;
497
e688a7f8 498 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
96518518
PM
499 if (family != NFPROTO_UNSPEC && family != afi->family)
500 continue;
501
e688a7f8 502 list_for_each_entry_rcu(table, &afi->tables, list) {
96518518
PM
503 if (idx < s_idx)
504 goto cont;
505 if (idx > s_idx)
506 memset(&cb->args[1], 0,
507 sizeof(cb->args) - sizeof(cb->args[0]));
f2a6d766
PNA
508 if (!nft_is_active(net, table))
509 continue;
84d7fce6 510 if (nf_tables_fill_table_info(skb, net,
96518518
PM
511 NETLINK_CB(cb->skb).portid,
512 cb->nlh->nlmsg_seq,
513 NFT_MSG_NEWTABLE,
514 NLM_F_MULTI,
515 afi->family, table) < 0)
516 goto done;
38e029f1
PNA
517
518 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518
PM
519cont:
520 idx++;
521 }
522 }
523done:
e688a7f8 524 rcu_read_unlock();
96518518
PM
525 cb->args[0] = idx;
526 return skb->len;
527}
528
7b8002a1
PNA
529static int nf_tables_gettable(struct net *net, struct sock *nlsk,
530 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
531 const struct nlattr * const nla[])
532{
533 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 534 u8 genmask = nft_genmask_cur(net);
96518518
PM
535 const struct nft_af_info *afi;
536 const struct nft_table *table;
537 struct sk_buff *skb2;
538 int family = nfmsg->nfgen_family;
539 int err;
540
541 if (nlh->nlmsg_flags & NLM_F_DUMP) {
542 struct netlink_dump_control c = {
543 .dump = nf_tables_dump_tables,
544 };
545 return netlink_dump_start(nlsk, skb, nlh, &c);
546 }
547
99633ab2 548 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
549 if (IS_ERR(afi))
550 return PTR_ERR(afi);
551
f2a6d766 552 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
96518518
PM
553 if (IS_ERR(table))
554 return PTR_ERR(table);
555
556 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
557 if (!skb2)
558 return -ENOMEM;
559
84d7fce6 560 err = nf_tables_fill_table_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
561 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
562 family, table);
563 if (err < 0)
564 goto err;
565
566 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
567
568err:
569 kfree_skb(skb2);
570 return err;
571}
572
664b0f8c
PNA
573static int nf_tables_table_enable(struct net *net,
574 const struct nft_af_info *afi,
115a60b1 575 struct nft_table *table)
9ddf6323
PNA
576{
577 struct nft_chain *chain;
578 int err, i = 0;
579
580 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
581 if (!nft_is_active_next(net, chain))
582 continue;
d2012975
PNA
583 if (!(chain->flags & NFT_BASE_CHAIN))
584 continue;
585
82bec71d
PNA
586 err = nf_register_net_hooks(net, nft_base_chain(chain)->ops,
587 afi->nops);
9ddf6323
PNA
588 if (err < 0)
589 goto err;
590
591 i++;
592 }
593 return 0;
594err:
595 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
596 if (!nft_is_active_next(net, chain))
597 continue;
d2012975
PNA
598 if (!(chain->flags & NFT_BASE_CHAIN))
599 continue;
600
9ddf6323
PNA
601 if (i-- <= 0)
602 break;
603
82bec71d
PNA
604 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
605 afi->nops);
9ddf6323
PNA
606 }
607 return err;
608}
609
664b0f8c
PNA
610static void nf_tables_table_disable(struct net *net,
611 const struct nft_af_info *afi,
d8ee8f7c 612 struct nft_table *table)
9ddf6323
PNA
613{
614 struct nft_chain *chain;
615
d2012975 616 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
617 if (!nft_is_active_next(net, chain))
618 continue;
82bec71d
PNA
619 if (!(chain->flags & NFT_BASE_CHAIN))
620 continue;
621
622 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
623 afi->nops);
d2012975 624 }
9ddf6323
PNA
625}
626
e1aaca93 627static int nf_tables_updtable(struct nft_ctx *ctx)
9ddf6323 628{
55dd6f93 629 struct nft_trans *trans;
e1aaca93 630 u32 flags;
55dd6f93 631 int ret = 0;
9ddf6323 632
e1aaca93
PNA
633 if (!ctx->nla[NFTA_TABLE_FLAGS])
634 return 0;
9ddf6323 635
e1aaca93
PNA
636 flags = ntohl(nla_get_be32(ctx->nla[NFTA_TABLE_FLAGS]));
637 if (flags & ~NFT_TABLE_F_DORMANT)
638 return -EINVAL;
639
63283dd2
PNA
640 if (flags == ctx->table->flags)
641 return 0;
642
55dd6f93
PNA
643 trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
644 sizeof(struct nft_trans_table));
645 if (trans == NULL)
646 return -ENOMEM;
9ddf6323 647
e1aaca93
PNA
648 if ((flags & NFT_TABLE_F_DORMANT) &&
649 !(ctx->table->flags & NFT_TABLE_F_DORMANT)) {
55dd6f93 650 nft_trans_table_enable(trans) = false;
e1aaca93
PNA
651 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
652 ctx->table->flags & NFT_TABLE_F_DORMANT) {
664b0f8c 653 ret = nf_tables_table_enable(ctx->net, ctx->afi, ctx->table);
55dd6f93 654 if (ret >= 0) {
e1aaca93 655 ctx->table->flags &= ~NFT_TABLE_F_DORMANT;
55dd6f93 656 nft_trans_table_enable(trans) = true;
9ddf6323 657 }
9ddf6323 658 }
e1aaca93
PNA
659 if (ret < 0)
660 goto err;
9ddf6323 661
55dd6f93
PNA
662 nft_trans_table_update(trans) = true;
663 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
664 return 0;
9ddf6323 665err:
55dd6f93 666 nft_trans_destroy(trans);
9ddf6323
PNA
667 return ret;
668}
669
633c9a84
PNA
670static int nf_tables_newtable(struct net *net, struct sock *nlsk,
671 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
672 const struct nlattr * const nla[])
673{
674 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 675 u8 genmask = nft_genmask_next(net);
96518518
PM
676 const struct nlattr *name;
677 struct nft_af_info *afi;
678 struct nft_table *table;
679 int family = nfmsg->nfgen_family;
c5c1f975 680 u32 flags = 0;
e1aaca93 681 struct nft_ctx ctx;
55dd6f93 682 int err;
96518518 683
99633ab2 684 afi = nf_tables_afinfo_lookup(net, family, true);
96518518
PM
685 if (IS_ERR(afi))
686 return PTR_ERR(afi);
687
688 name = nla[NFTA_TABLE_NAME];
f2a6d766 689 table = nf_tables_table_lookup(afi, name, genmask);
96518518
PM
690 if (IS_ERR(table)) {
691 if (PTR_ERR(table) != -ENOENT)
692 return PTR_ERR(table);
693 table = NULL;
694 }
695
696 if (table != NULL) {
697 if (nlh->nlmsg_flags & NLM_F_EXCL)
698 return -EEXIST;
699 if (nlh->nlmsg_flags & NLM_F_REPLACE)
700 return -EOPNOTSUPP;
e1aaca93 701
633c9a84 702 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
e1aaca93 703 return nf_tables_updtable(&ctx);
96518518
PM
704 }
705
c5c1f975
PM
706 if (nla[NFTA_TABLE_FLAGS]) {
707 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
708 if (flags & ~NFT_TABLE_F_DORMANT)
709 return -EINVAL;
710 }
711
ebddf1a8 712 err = -EAFNOSUPPORT;
7047f9d0 713 if (!try_module_get(afi->owner))
ebddf1a8 714 goto err1;
7047f9d0 715
ffdb210e 716 err = -ENOMEM;
1cae565e 717 table = kzalloc(sizeof(*table), GFP_KERNEL);
ffdb210e 718 if (table == NULL)
ebddf1a8 719 goto err2;
96518518 720
1cae565e 721 nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN);
96518518 722 INIT_LIST_HEAD(&table->chains);
20a69341 723 INIT_LIST_HEAD(&table->sets);
e5009240 724 INIT_LIST_HEAD(&table->objects);
c5c1f975 725 table->flags = flags;
9ddf6323 726
633c9a84 727 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
55dd6f93 728 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
ffdb210e 729 if (err < 0)
ebddf1a8 730 goto err3;
ffdb210e 731
e688a7f8 732 list_add_tail_rcu(&table->list, &afi->tables);
96518518 733 return 0;
ebddf1a8 734err3:
ffdb210e 735 kfree(table);
ebddf1a8 736err2:
ffdb210e 737 module_put(afi->owner);
ebddf1a8 738err1:
ffdb210e 739 return err;
96518518
PM
740}
741
b9ac12ef
AB
742static int nft_flush_table(struct nft_ctx *ctx)
743{
744 int err;
745 struct nft_chain *chain, *nc;
e5009240 746 struct nft_object *obj, *ne;
b9ac12ef
AB
747 struct nft_set *set, *ns;
748
a2f18db0 749 list_for_each_entry(chain, &ctx->table->chains, list) {
664b0f8c
PNA
750 if (!nft_is_active_next(ctx->net, chain))
751 continue;
752
b9ac12ef
AB
753 ctx->chain = chain;
754
755 err = nft_delrule_by_chain(ctx);
756 if (err < 0)
757 goto out;
b9ac12ef
AB
758 }
759
760 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
37a9cc52
PNA
761 if (!nft_is_active_next(ctx->net, set))
762 continue;
763
b9ac12ef
AB
764 if (set->flags & NFT_SET_ANONYMOUS &&
765 !list_empty(&set->bindings))
766 continue;
767
768 err = nft_delset(ctx, set);
769 if (err < 0)
770 goto out;
771 }
772
e5009240
PNA
773 list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) {
774 err = nft_delobj(ctx, obj);
775 if (err < 0)
776 goto out;
777 }
778
a2f18db0 779 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
664b0f8c
PNA
780 if (!nft_is_active_next(ctx->net, chain))
781 continue;
782
a2f18db0
PNA
783 ctx->chain = chain;
784
785 err = nft_delchain(ctx);
786 if (err < 0)
787 goto out;
788 }
789
b9ac12ef
AB
790 err = nft_deltable(ctx);
791out:
792 return err;
793}
794
795static int nft_flush(struct nft_ctx *ctx, int family)
796{
797 struct nft_af_info *afi;
798 struct nft_table *table, *nt;
799 const struct nlattr * const *nla = ctx->nla;
800 int err = 0;
801
802 list_for_each_entry(afi, &ctx->net->nft.af_info, list) {
803 if (family != AF_UNSPEC && afi->family != family)
804 continue;
805
806 ctx->afi = afi;
807 list_for_each_entry_safe(table, nt, &afi->tables, list) {
f2a6d766
PNA
808 if (!nft_is_active_next(ctx->net, table))
809 continue;
810
b9ac12ef
AB
811 if (nla[NFTA_TABLE_NAME] &&
812 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
813 continue;
814
815 ctx->table = table;
816
817 err = nft_flush_table(ctx);
818 if (err < 0)
819 goto out;
820 }
821 }
822out:
823 return err;
824}
825
633c9a84
PNA
826static int nf_tables_deltable(struct net *net, struct sock *nlsk,
827 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
828 const struct nlattr * const nla[])
829{
830 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 831 u8 genmask = nft_genmask_next(net);
96518518
PM
832 struct nft_af_info *afi;
833 struct nft_table *table;
ee01d542 834 int family = nfmsg->nfgen_family;
55dd6f93 835 struct nft_ctx ctx;
96518518 836
633c9a84 837 nft_ctx_init(&ctx, net, skb, nlh, NULL, NULL, NULL, nla);
b9ac12ef
AB
838 if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)
839 return nft_flush(&ctx, family);
840
99633ab2 841 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
842 if (IS_ERR(afi))
843 return PTR_ERR(afi);
844
f2a6d766 845 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
96518518
PM
846 if (IS_ERR(table))
847 return PTR_ERR(table);
96518518 848
b9ac12ef
AB
849 ctx.afi = afi;
850 ctx.table = table;
55dd6f93 851
b9ac12ef 852 return nft_flush_table(&ctx);
96518518
PM
853}
854
55dd6f93
PNA
855static void nf_tables_table_destroy(struct nft_ctx *ctx)
856{
4fefee57
PNA
857 BUG_ON(ctx->table->use > 0);
858
55dd6f93
PNA
859 kfree(ctx->table);
860 module_put(ctx->afi->owner);
861}
862
2a37d755 863int nft_register_chain_type(const struct nf_chain_type *ctype)
96518518 864{
9370761c 865 int err = 0;
96518518
PM
866
867 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c
PNA
868 if (chain_type[ctype->family][ctype->type] != NULL) {
869 err = -EBUSY;
870 goto out;
96518518 871 }
9370761c
PNA
872 chain_type[ctype->family][ctype->type] = ctype;
873out:
96518518
PM
874 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
875 return err;
876}
9370761c 877EXPORT_SYMBOL_GPL(nft_register_chain_type);
96518518 878
2a37d755 879void nft_unregister_chain_type(const struct nf_chain_type *ctype)
96518518 880{
96518518 881 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c 882 chain_type[ctype->family][ctype->type] = NULL;
96518518
PM
883 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
884}
9370761c 885EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
96518518
PM
886
887/*
888 * Chains
889 */
890
891static struct nft_chain *
664b0f8c
PNA
892nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle,
893 u8 genmask)
96518518
PM
894{
895 struct nft_chain *chain;
896
897 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
898 if (chain->handle == handle &&
899 nft_active_genmask(chain, genmask))
96518518
PM
900 return chain;
901 }
902
903 return ERR_PTR(-ENOENT);
904}
905
906static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
664b0f8c
PNA
907 const struct nlattr *nla,
908 u8 genmask)
96518518
PM
909{
910 struct nft_chain *chain;
911
912 if (nla == NULL)
913 return ERR_PTR(-EINVAL);
914
915 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
916 if (!nla_strcmp(nla, chain->name) &&
917 nft_active_genmask(chain, genmask))
96518518
PM
918 return chain;
919 }
920
921 return ERR_PTR(-ENOENT);
922}
923
924static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
925 [NFTA_CHAIN_TABLE] = { .type = NLA_STRING },
926 [NFTA_CHAIN_HANDLE] = { .type = NLA_U64 },
927 [NFTA_CHAIN_NAME] = { .type = NLA_STRING,
928 .len = NFT_CHAIN_MAXNAMELEN - 1 },
929 [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED },
0ca743a5 930 [NFTA_CHAIN_POLICY] = { .type = NLA_U32 },
4c1f7818 931 [NFTA_CHAIN_TYPE] = { .type = NLA_STRING },
0ca743a5 932 [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED },
96518518
PM
933};
934
935static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
936 [NFTA_HOOK_HOOKNUM] = { .type = NLA_U32 },
937 [NFTA_HOOK_PRIORITY] = { .type = NLA_U32 },
2cbce139
PNA
938 [NFTA_HOOK_DEV] = { .type = NLA_STRING,
939 .len = IFNAMSIZ - 1 },
96518518
PM
940};
941
0ca743a5
PNA
942static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
943{
944 struct nft_stats *cpu_stats, total;
945 struct nlattr *nest;
ce355e20
ED
946 unsigned int seq;
947 u64 pkts, bytes;
0ca743a5
PNA
948 int cpu;
949
950 memset(&total, 0, sizeof(total));
951 for_each_possible_cpu(cpu) {
952 cpu_stats = per_cpu_ptr(stats, cpu);
ce355e20
ED
953 do {
954 seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
955 pkts = cpu_stats->pkts;
956 bytes = cpu_stats->bytes;
957 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
958 total.pkts += pkts;
959 total.bytes += bytes;
0ca743a5
PNA
960 }
961 nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS);
962 if (nest == NULL)
963 goto nla_put_failure;
964
b46f6ded
ND
965 if (nla_put_be64(skb, NFTA_COUNTER_PACKETS, cpu_to_be64(total.pkts),
966 NFTA_COUNTER_PAD) ||
967 nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
968 NFTA_COUNTER_PAD))
0ca743a5
PNA
969 goto nla_put_failure;
970
971 nla_nest_end(skb, nest);
972 return 0;
973
974nla_put_failure:
975 return -ENOSPC;
976}
977
84d7fce6
PNA
978static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
979 u32 portid, u32 seq, int event, u32 flags,
980 int family, const struct nft_table *table,
96518518
PM
981 const struct nft_chain *chain)
982{
983 struct nlmsghdr *nlh;
984 struct nfgenmsg *nfmsg;
985
986 event |= NFNL_SUBSYS_NFTABLES << 8;
987 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
988 if (nlh == NULL)
989 goto nla_put_failure;
990
991 nfmsg = nlmsg_data(nlh);
992 nfmsg->nfgen_family = family;
993 nfmsg->version = NFNETLINK_V0;
84d7fce6 994 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518
PM
995
996 if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
997 goto nla_put_failure;
b46f6ded
ND
998 if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
999 NFTA_CHAIN_PAD))
96518518
PM
1000 goto nla_put_failure;
1001 if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
1002 goto nla_put_failure;
1003
1004 if (chain->flags & NFT_BASE_CHAIN) {
0ca743a5 1005 const struct nft_base_chain *basechain = nft_base_chain(chain);
115a60b1 1006 const struct nf_hook_ops *ops = &basechain->ops[0];
0ca743a5
PNA
1007 struct nlattr *nest;
1008
1009 nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
96518518
PM
1010 if (nest == NULL)
1011 goto nla_put_failure;
1012 if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum)))
1013 goto nla_put_failure;
1014 if (nla_put_be32(skb, NFTA_HOOK_PRIORITY, htonl(ops->priority)))
1015 goto nla_put_failure;
2cbce139
PNA
1016 if (basechain->dev_name[0] &&
1017 nla_put_string(skb, NFTA_HOOK_DEV, basechain->dev_name))
1018 goto nla_put_failure;
96518518 1019 nla_nest_end(skb, nest);
9370761c 1020
0ca743a5
PNA
1021 if (nla_put_be32(skb, NFTA_CHAIN_POLICY,
1022 htonl(basechain->policy)))
1023 goto nla_put_failure;
1024
baae3e62
PM
1025 if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name))
1026 goto nla_put_failure;
0ca743a5
PNA
1027
1028 if (nft_dump_stats(skb, nft_base_chain(chain)->stats))
1029 goto nla_put_failure;
96518518
PM
1030 }
1031
0ca743a5
PNA
1032 if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
1033 goto nla_put_failure;
1034
053c095a
JB
1035 nlmsg_end(skb, nlh);
1036 return 0;
96518518
PM
1037
1038nla_put_failure:
1039 nlmsg_trim(skb, nlh);
1040 return -1;
1041}
1042
35151d84 1043static int nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
96518518
PM
1044{
1045 struct sk_buff *skb;
96518518
PM
1046 int err;
1047
128ad332
PNA
1048 if (!ctx->report &&
1049 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
96518518
PM
1050 return 0;
1051
1052 err = -ENOBUFS;
1053 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1054 if (skb == NULL)
1055 goto err;
1056
84d7fce6
PNA
1057 err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
1058 event, 0, ctx->afi->family, ctx->table,
35151d84 1059 ctx->chain);
96518518
PM
1060 if (err < 0) {
1061 kfree_skb(skb);
1062 goto err;
1063 }
1064
128ad332
PNA
1065 err = nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1066 ctx->report, GFP_KERNEL);
96518518 1067err:
128ad332
PNA
1068 if (err < 0) {
1069 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1070 err);
1071 }
96518518
PM
1072 return err;
1073}
1074
1075static int nf_tables_dump_chains(struct sk_buff *skb,
1076 struct netlink_callback *cb)
1077{
1078 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1079 const struct nft_af_info *afi;
1080 const struct nft_table *table;
1081 const struct nft_chain *chain;
1082 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 1083 struct net *net = sock_net(skb->sk);
96518518
PM
1084 int family = nfmsg->nfgen_family;
1085
e688a7f8 1086 rcu_read_lock();
38e029f1
PNA
1087 cb->seq = net->nft.base_seq;
1088
e688a7f8 1089 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
96518518
PM
1090 if (family != NFPROTO_UNSPEC && family != afi->family)
1091 continue;
1092
e688a7f8
PNA
1093 list_for_each_entry_rcu(table, &afi->tables, list) {
1094 list_for_each_entry_rcu(chain, &table->chains, list) {
96518518
PM
1095 if (idx < s_idx)
1096 goto cont;
1097 if (idx > s_idx)
1098 memset(&cb->args[1], 0,
1099 sizeof(cb->args) - sizeof(cb->args[0]));
664b0f8c
PNA
1100 if (!nft_is_active(net, chain))
1101 continue;
84d7fce6
PNA
1102 if (nf_tables_fill_chain_info(skb, net,
1103 NETLINK_CB(cb->skb).portid,
96518518
PM
1104 cb->nlh->nlmsg_seq,
1105 NFT_MSG_NEWCHAIN,
1106 NLM_F_MULTI,
1107 afi->family, table, chain) < 0)
1108 goto done;
38e029f1
PNA
1109
1110 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518
PM
1111cont:
1112 idx++;
1113 }
1114 }
1115 }
1116done:
e688a7f8 1117 rcu_read_unlock();
96518518
PM
1118 cb->args[0] = idx;
1119 return skb->len;
1120}
1121
7b8002a1
PNA
1122static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1123 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
1124 const struct nlattr * const nla[])
1125{
1126 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1127 u8 genmask = nft_genmask_cur(net);
96518518
PM
1128 const struct nft_af_info *afi;
1129 const struct nft_table *table;
1130 const struct nft_chain *chain;
1131 struct sk_buff *skb2;
1132 int family = nfmsg->nfgen_family;
1133 int err;
1134
1135 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1136 struct netlink_dump_control c = {
1137 .dump = nf_tables_dump_chains,
1138 };
1139 return netlink_dump_start(nlsk, skb, nlh, &c);
1140 }
1141
99633ab2 1142 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
1143 if (IS_ERR(afi))
1144 return PTR_ERR(afi);
1145
f2a6d766 1146 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
96518518
PM
1147 if (IS_ERR(table))
1148 return PTR_ERR(table);
1149
664b0f8c 1150 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
96518518
PM
1151 if (IS_ERR(chain))
1152 return PTR_ERR(chain);
1153
1154 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1155 if (!skb2)
1156 return -ENOMEM;
1157
84d7fce6 1158 err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
1159 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
1160 family, table, chain);
1161 if (err < 0)
1162 goto err;
1163
1164 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1165
1166err:
1167 kfree_skb(skb2);
1168 return err;
1169}
1170
0ca743a5
PNA
1171static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
1172 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
1173 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
1174};
1175
ff3cd7b3 1176static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
0ca743a5
PNA
1177{
1178 struct nlattr *tb[NFTA_COUNTER_MAX+1];
1179 struct nft_stats __percpu *newstats;
1180 struct nft_stats *stats;
1181 int err;
1182
1183 err = nla_parse_nested(tb, NFTA_COUNTER_MAX, attr, nft_counter_policy);
1184 if (err < 0)
ff3cd7b3 1185 return ERR_PTR(err);
0ca743a5
PNA
1186
1187 if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
ff3cd7b3 1188 return ERR_PTR(-EINVAL);
0ca743a5 1189
ce355e20 1190 newstats = netdev_alloc_pcpu_stats(struct nft_stats);
0ca743a5 1191 if (newstats == NULL)
ff3cd7b3 1192 return ERR_PTR(-ENOMEM);
0ca743a5
PNA
1193
1194 /* Restore old counters on this cpu, no problem. Per-cpu statistics
1195 * are not exposed to userspace.
1196 */
e8781f70 1197 preempt_disable();
0ca743a5
PNA
1198 stats = this_cpu_ptr(newstats);
1199 stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
1200 stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
e8781f70 1201 preempt_enable();
0ca743a5 1202
ff3cd7b3
PNA
1203 return newstats;
1204}
1205
1206static void nft_chain_stats_replace(struct nft_base_chain *chain,
1207 struct nft_stats __percpu *newstats)
1208{
b88825de
PNA
1209 if (newstats == NULL)
1210 return;
1211
0ca743a5 1212 if (chain->stats) {
0ca743a5 1213 struct nft_stats __percpu *oldstats =
67a8fc27 1214 nft_dereference(chain->stats);
0ca743a5
PNA
1215
1216 rcu_assign_pointer(chain->stats, newstats);
1217 synchronize_rcu();
1218 free_percpu(oldstats);
1219 } else
1220 rcu_assign_pointer(chain->stats, newstats);
0ca743a5
PNA
1221}
1222
91c7b38d
PNA
1223static void nf_tables_chain_destroy(struct nft_chain *chain)
1224{
1225 BUG_ON(chain->use > 0);
1226
1227 if (chain->flags & NFT_BASE_CHAIN) {
2cbce139
PNA
1228 struct nft_base_chain *basechain = nft_base_chain(chain);
1229
1230 module_put(basechain->type->owner);
1231 free_percpu(basechain->stats);
1232 if (basechain->ops[0].dev != NULL)
1233 dev_put(basechain->ops[0].dev);
1234 kfree(basechain);
91c7b38d
PNA
1235 } else {
1236 kfree(chain);
1237 }
1238}
1239
508f8ccd
PNA
1240struct nft_chain_hook {
1241 u32 num;
1242 u32 priority;
1243 const struct nf_chain_type *type;
1244 struct net_device *dev;
1245};
1246
1247static int nft_chain_parse_hook(struct net *net,
1248 const struct nlattr * const nla[],
1249 struct nft_af_info *afi,
1250 struct nft_chain_hook *hook, bool create)
1251{
1252 struct nlattr *ha[NFTA_HOOK_MAX + 1];
1253 const struct nf_chain_type *type;
1254 struct net_device *dev;
1255 int err;
1256
1257 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
1258 nft_hook_policy);
1259 if (err < 0)
1260 return err;
1261
1262 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
1263 ha[NFTA_HOOK_PRIORITY] == NULL)
1264 return -EINVAL;
1265
1266 hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
1267 if (hook->num >= afi->nhooks)
1268 return -EINVAL;
1269
1270 hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
1271
1272 type = chain_type[afi->family][NFT_CHAIN_T_DEFAULT];
1273 if (nla[NFTA_CHAIN_TYPE]) {
1274 type = nf_tables_chain_type_lookup(afi, nla[NFTA_CHAIN_TYPE],
1275 create);
1276 if (IS_ERR(type))
1277 return PTR_ERR(type);
1278 }
1279 if (!(type->hook_mask & (1 << hook->num)))
1280 return -EOPNOTSUPP;
1281 if (!try_module_get(type->owner))
1282 return -ENOENT;
1283
1284 hook->type = type;
1285
1286 hook->dev = NULL;
1287 if (afi->flags & NFT_AF_NEEDS_DEV) {
1288 char ifname[IFNAMSIZ];
1289
1290 if (!ha[NFTA_HOOK_DEV]) {
1291 module_put(type->owner);
1292 return -EOPNOTSUPP;
1293 }
1294
1295 nla_strlcpy(ifname, ha[NFTA_HOOK_DEV], IFNAMSIZ);
1296 dev = dev_get_by_name(net, ifname);
1297 if (!dev) {
1298 module_put(type->owner);
1299 return -ENOENT;
1300 }
1301 hook->dev = dev;
1302 } else if (ha[NFTA_HOOK_DEV]) {
1303 module_put(type->owner);
1304 return -EOPNOTSUPP;
1305 }
1306
1307 return 0;
1308}
1309
1310static void nft_chain_release_hook(struct nft_chain_hook *hook)
1311{
1312 module_put(hook->type->owner);
1313 if (hook->dev != NULL)
1314 dev_put(hook->dev);
1315}
1316
633c9a84
PNA
1317static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1318 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
1319 const struct nlattr * const nla[])
1320{
1321 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1322 const struct nlattr * uninitialized_var(name);
7c95f6d8 1323 struct nft_af_info *afi;
96518518
PM
1324 struct nft_table *table;
1325 struct nft_chain *chain;
0ca743a5 1326 struct nft_base_chain *basechain = NULL;
f2a6d766 1327 u8 genmask = nft_genmask_next(net);
96518518 1328 int family = nfmsg->nfgen_family;
57de2a0c 1329 u8 policy = NF_ACCEPT;
96518518 1330 u64 handle = 0;
115a60b1 1331 unsigned int i;
ff3cd7b3 1332 struct nft_stats __percpu *stats;
96518518
PM
1333 int err;
1334 bool create;
91c7b38d 1335 struct nft_ctx ctx;
96518518
PM
1336
1337 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
1338
99633ab2 1339 afi = nf_tables_afinfo_lookup(net, family, true);
96518518
PM
1340 if (IS_ERR(afi))
1341 return PTR_ERR(afi);
1342
f2a6d766 1343 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
96518518
PM
1344 if (IS_ERR(table))
1345 return PTR_ERR(table);
1346
96518518
PM
1347 chain = NULL;
1348 name = nla[NFTA_CHAIN_NAME];
1349
1350 if (nla[NFTA_CHAIN_HANDLE]) {
1351 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
664b0f8c 1352 chain = nf_tables_chain_lookup_byhandle(table, handle, genmask);
96518518
PM
1353 if (IS_ERR(chain))
1354 return PTR_ERR(chain);
1355 } else {
664b0f8c 1356 chain = nf_tables_chain_lookup(table, name, genmask);
96518518
PM
1357 if (IS_ERR(chain)) {
1358 if (PTR_ERR(chain) != -ENOENT)
1359 return PTR_ERR(chain);
1360 chain = NULL;
1361 }
1362 }
1363
57de2a0c
PM
1364 if (nla[NFTA_CHAIN_POLICY]) {
1365 if ((chain != NULL &&
d6b6cb1d
PNA
1366 !(chain->flags & NFT_BASE_CHAIN)))
1367 return -EOPNOTSUPP;
1368
1369 if (chain == NULL &&
57de2a0c
PM
1370 nla[NFTA_CHAIN_HOOK] == NULL)
1371 return -EOPNOTSUPP;
1372
8f46df18 1373 policy = ntohl(nla_get_be32(nla[NFTA_CHAIN_POLICY]));
57de2a0c
PM
1374 switch (policy) {
1375 case NF_DROP:
1376 case NF_ACCEPT:
1377 break;
1378 default:
1379 return -EINVAL;
1380 }
1381 }
1382
96518518 1383 if (chain != NULL) {
91c7b38d
PNA
1384 struct nft_stats *stats = NULL;
1385 struct nft_trans *trans;
1386
96518518
PM
1387 if (nlh->nlmsg_flags & NLM_F_EXCL)
1388 return -EEXIST;
1389 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1390 return -EOPNOTSUPP;
1391
6133740d
PNA
1392 if (nla[NFTA_CHAIN_HOOK]) {
1393 struct nft_base_chain *basechain;
1394 struct nft_chain_hook hook;
1395 struct nf_hook_ops *ops;
1396
1397 if (!(chain->flags & NFT_BASE_CHAIN))
1398 return -EBUSY;
1399
1400 err = nft_chain_parse_hook(net, nla, afi, &hook,
1401 create);
1402 if (err < 0)
1403 return err;
1404
1405 basechain = nft_base_chain(chain);
1406 if (basechain->type != hook.type) {
1407 nft_chain_release_hook(&hook);
1408 return -EBUSY;
1409 }
1410
1411 for (i = 0; i < afi->nops; i++) {
1412 ops = &basechain->ops[i];
1413 if (ops->hooknum != hook.num ||
1414 ops->priority != hook.priority ||
1415 ops->dev != hook.dev) {
1416 nft_chain_release_hook(&hook);
1417 return -EBUSY;
1418 }
1419 }
1420 nft_chain_release_hook(&hook);
1421 }
1422
664b0f8c
PNA
1423 if (nla[NFTA_CHAIN_HANDLE] && name) {
1424 struct nft_chain *chain2;
1425
1426 chain2 = nf_tables_chain_lookup(table,
1427 nla[NFTA_CHAIN_NAME],
1428 genmask);
1429 if (IS_ERR(chain2))
1430 return PTR_ERR(chain2);
1431 }
96518518 1432
0ca743a5
PNA
1433 if (nla[NFTA_CHAIN_COUNTERS]) {
1434 if (!(chain->flags & NFT_BASE_CHAIN))
1435 return -EOPNOTSUPP;
1436
ff3cd7b3
PNA
1437 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1438 if (IS_ERR(stats))
1439 return PTR_ERR(stats);
0ca743a5
PNA
1440 }
1441
633c9a84 1442 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
91c7b38d
PNA
1443 trans = nft_trans_alloc(&ctx, NFT_MSG_NEWCHAIN,
1444 sizeof(struct nft_trans_chain));
f5553c19
PNA
1445 if (trans == NULL) {
1446 free_percpu(stats);
91c7b38d 1447 return -ENOMEM;
f5553c19 1448 }
4401a862 1449
91c7b38d
PNA
1450 nft_trans_chain_stats(trans) = stats;
1451 nft_trans_chain_update(trans) = true;
4401a862 1452
91c7b38d
PNA
1453 if (nla[NFTA_CHAIN_POLICY])
1454 nft_trans_chain_policy(trans) = policy;
1455 else
1456 nft_trans_chain_policy(trans) = -1;
96518518 1457
91c7b38d
PNA
1458 if (nla[NFTA_CHAIN_HANDLE] && name) {
1459 nla_strlcpy(nft_trans_chain_name(trans), name,
1460 NFT_CHAIN_MAXNAMELEN);
1461 }
1462 list_add_tail(&trans->list, &net->nft.commit_list);
1463 return 0;
96518518
PM
1464 }
1465
75820676
PM
1466 if (table->use == UINT_MAX)
1467 return -EOVERFLOW;
1468
96518518 1469 if (nla[NFTA_CHAIN_HOOK]) {
508f8ccd 1470 struct nft_chain_hook hook;
96518518 1471 struct nf_hook_ops *ops;
9370761c 1472 nf_hookfn *hookfn;
96518518 1473
508f8ccd 1474 err = nft_chain_parse_hook(net, nla, afi, &hook, create);
96518518
PM
1475 if (err < 0)
1476 return err;
2cbce139 1477
96518518 1478 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
f5553c19 1479 if (basechain == NULL) {
508f8ccd 1480 nft_chain_release_hook(&hook);
96518518 1481 return -ENOMEM;
f5553c19 1482 }
9370761c 1483
508f8ccd
PNA
1484 if (hook.dev != NULL)
1485 strncpy(basechain->dev_name, hook.dev->name, IFNAMSIZ);
2cbce139 1486
4401a862 1487 if (nla[NFTA_CHAIN_COUNTERS]) {
ff3cd7b3
PNA
1488 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1489 if (IS_ERR(stats)) {
508f8ccd 1490 nft_chain_release_hook(&hook);
4401a862 1491 kfree(basechain);
ff3cd7b3 1492 return PTR_ERR(stats);
4401a862 1493 }
ff3cd7b3 1494 basechain->stats = stats;
4401a862 1495 } else {
ce355e20 1496 stats = netdev_alloc_pcpu_stats(struct nft_stats);
c123bb71 1497 if (stats == NULL) {
508f8ccd 1498 nft_chain_release_hook(&hook);
4401a862 1499 kfree(basechain);
c123bb71 1500 return -ENOMEM;
4401a862 1501 }
ff3cd7b3 1502 rcu_assign_pointer(basechain->stats, stats);
4401a862
PM
1503 }
1504
508f8ccd
PNA
1505 hookfn = hook.type->hooks[hook.num];
1506 basechain->type = hook.type;
96518518
PM
1507 chain = &basechain->chain;
1508
115a60b1
PM
1509 for (i = 0; i < afi->nops; i++) {
1510 ops = &basechain->ops[i];
1511 ops->pf = family;
508f8ccd
PNA
1512 ops->hooknum = hook.num;
1513 ops->priority = hook.priority;
115a60b1
PM
1514 ops->priv = chain;
1515 ops->hook = afi->hooks[ops->hooknum];
508f8ccd 1516 ops->dev = hook.dev;
115a60b1
PM
1517 if (hookfn)
1518 ops->hook = hookfn;
1519 if (afi->hook_ops_init)
1520 afi->hook_ops_init(ops, i);
1521 }
96518518
PM
1522
1523 chain->flags |= NFT_BASE_CHAIN;
57de2a0c 1524 basechain->policy = policy;
96518518
PM
1525 } else {
1526 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1527 if (chain == NULL)
1528 return -ENOMEM;
1529 }
1530
1531 INIT_LIST_HEAD(&chain->rules);
1532 chain->handle = nf_tables_alloc_handle(table);
b5bc89bf 1533 chain->table = table;
96518518
PM
1534 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
1535
82bec71d 1536 err = nf_tables_register_hooks(net, table, chain, afi->nops);
d8ee8f7c
PNA
1537 if (err < 0)
1538 goto err1;
96518518 1539
633c9a84 1540 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
91c7b38d
PNA
1541 err = nft_trans_chain_add(&ctx, NFT_MSG_NEWCHAIN);
1542 if (err < 0)
1543 goto err2;
96518518 1544
4fefee57 1545 table->use++;
e688a7f8 1546 list_add_tail_rcu(&chain->list, &table->chains);
91c7b38d
PNA
1547 return 0;
1548err2:
82bec71d 1549 nf_tables_unregister_hooks(net, table, chain, afi->nops);
91c7b38d
PNA
1550err1:
1551 nf_tables_chain_destroy(chain);
1552 return err;
96518518
PM
1553}
1554
633c9a84
PNA
1555static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1556 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
1557 const struct nlattr * const nla[])
1558{
1559 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1560 u8 genmask = nft_genmask_next(net);
7c95f6d8 1561 struct nft_af_info *afi;
96518518
PM
1562 struct nft_table *table;
1563 struct nft_chain *chain;
1564 int family = nfmsg->nfgen_family;
91c7b38d 1565 struct nft_ctx ctx;
96518518 1566
99633ab2 1567 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
1568 if (IS_ERR(afi))
1569 return PTR_ERR(afi);
1570
f2a6d766 1571 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
96518518
PM
1572 if (IS_ERR(table))
1573 return PTR_ERR(table);
1574
664b0f8c 1575 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
96518518
PM
1576 if (IS_ERR(chain))
1577 return PTR_ERR(chain);
4fefee57 1578 if (chain->use > 0)
96518518
PM
1579 return -EBUSY;
1580
633c9a84 1581 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
0165d932 1582
ee01d542 1583 return nft_delchain(&ctx);
96518518
PM
1584}
1585
96518518
PM
1586/*
1587 * Expressions
1588 */
1589
1590/**
ef1f7df9
PM
1591 * nft_register_expr - register nf_tables expr type
1592 * @ops: expr type
96518518 1593 *
ef1f7df9 1594 * Registers the expr type for use with nf_tables. Returns zero on
96518518
PM
1595 * success or a negative errno code otherwise.
1596 */
ef1f7df9 1597int nft_register_expr(struct nft_expr_type *type)
96518518
PM
1598{
1599 nfnl_lock(NFNL_SUBSYS_NFTABLES);
758dbcec 1600 if (type->family == NFPROTO_UNSPEC)
e688a7f8 1601 list_add_tail_rcu(&type->list, &nf_tables_expressions);
758dbcec 1602 else
e688a7f8 1603 list_add_rcu(&type->list, &nf_tables_expressions);
96518518
PM
1604 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1605 return 0;
1606}
1607EXPORT_SYMBOL_GPL(nft_register_expr);
1608
1609/**
ef1f7df9
PM
1610 * nft_unregister_expr - unregister nf_tables expr type
1611 * @ops: expr type
96518518 1612 *
ef1f7df9 1613 * Unregisters the expr typefor use with nf_tables.
96518518 1614 */
ef1f7df9 1615void nft_unregister_expr(struct nft_expr_type *type)
96518518
PM
1616{
1617 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 1618 list_del_rcu(&type->list);
96518518
PM
1619 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1620}
1621EXPORT_SYMBOL_GPL(nft_unregister_expr);
1622
64d46806
PM
1623static const struct nft_expr_type *__nft_expr_type_get(u8 family,
1624 struct nlattr *nla)
96518518 1625{
ef1f7df9 1626 const struct nft_expr_type *type;
96518518 1627
ef1f7df9 1628 list_for_each_entry(type, &nf_tables_expressions, list) {
64d46806
PM
1629 if (!nla_strcmp(nla, type->name) &&
1630 (!type->family || type->family == family))
ef1f7df9 1631 return type;
96518518
PM
1632 }
1633 return NULL;
1634}
1635
64d46806
PM
1636static const struct nft_expr_type *nft_expr_type_get(u8 family,
1637 struct nlattr *nla)
96518518 1638{
ef1f7df9 1639 const struct nft_expr_type *type;
96518518
PM
1640
1641 if (nla == NULL)
1642 return ERR_PTR(-EINVAL);
1643
64d46806 1644 type = __nft_expr_type_get(family, nla);
ef1f7df9
PM
1645 if (type != NULL && try_module_get(type->owner))
1646 return type;
96518518
PM
1647
1648#ifdef CONFIG_MODULES
ef1f7df9 1649 if (type == NULL) {
64d46806
PM
1650 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1651 request_module("nft-expr-%u-%.*s", family,
1652 nla_len(nla), (char *)nla_data(nla));
1653 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1654 if (__nft_expr_type_get(family, nla))
1655 return ERR_PTR(-EAGAIN);
1656
96518518
PM
1657 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1658 request_module("nft-expr-%.*s",
1659 nla_len(nla), (char *)nla_data(nla));
1660 nfnl_lock(NFNL_SUBSYS_NFTABLES);
64d46806 1661 if (__nft_expr_type_get(family, nla))
96518518
PM
1662 return ERR_PTR(-EAGAIN);
1663 }
1664#endif
1665 return ERR_PTR(-ENOENT);
1666}
1667
1668static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
1669 [NFTA_EXPR_NAME] = { .type = NLA_STRING },
1670 [NFTA_EXPR_DATA] = { .type = NLA_NESTED },
1671};
1672
1673static int nf_tables_fill_expr_info(struct sk_buff *skb,
1674 const struct nft_expr *expr)
1675{
ef1f7df9 1676 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
96518518
PM
1677 goto nla_put_failure;
1678
1679 if (expr->ops->dump) {
1680 struct nlattr *data = nla_nest_start(skb, NFTA_EXPR_DATA);
1681 if (data == NULL)
1682 goto nla_put_failure;
1683 if (expr->ops->dump(skb, expr) < 0)
1684 goto nla_put_failure;
1685 nla_nest_end(skb, data);
1686 }
1687
1688 return skb->len;
1689
1690nla_put_failure:
1691 return -1;
1692};
1693
0b2d8a7b
PM
1694int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
1695 const struct nft_expr *expr)
1696{
1697 struct nlattr *nest;
1698
1699 nest = nla_nest_start(skb, attr);
1700 if (!nest)
1701 goto nla_put_failure;
1702 if (nf_tables_fill_expr_info(skb, expr) < 0)
1703 goto nla_put_failure;
1704 nla_nest_end(skb, nest);
1705 return 0;
1706
1707nla_put_failure:
1708 return -1;
1709}
1710
96518518
PM
1711struct nft_expr_info {
1712 const struct nft_expr_ops *ops;
ef1f7df9 1713 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
96518518
PM
1714};
1715
0ca743a5
PNA
1716static int nf_tables_expr_parse(const struct nft_ctx *ctx,
1717 const struct nlattr *nla,
96518518
PM
1718 struct nft_expr_info *info)
1719{
ef1f7df9 1720 const struct nft_expr_type *type;
96518518 1721 const struct nft_expr_ops *ops;
ef1f7df9 1722 struct nlattr *tb[NFTA_EXPR_MAX + 1];
96518518
PM
1723 int err;
1724
ef1f7df9 1725 err = nla_parse_nested(tb, NFTA_EXPR_MAX, nla, nft_expr_policy);
96518518
PM
1726 if (err < 0)
1727 return err;
1728
64d46806 1729 type = nft_expr_type_get(ctx->afi->family, tb[NFTA_EXPR_NAME]);
ef1f7df9
PM
1730 if (IS_ERR(type))
1731 return PTR_ERR(type);
1732
1733 if (tb[NFTA_EXPR_DATA]) {
1734 err = nla_parse_nested(info->tb, type->maxattr,
1735 tb[NFTA_EXPR_DATA], type->policy);
1736 if (err < 0)
1737 goto err1;
1738 } else
1739 memset(info->tb, 0, sizeof(info->tb[0]) * (type->maxattr + 1));
1740
1741 if (type->select_ops != NULL) {
0ca743a5
PNA
1742 ops = type->select_ops(ctx,
1743 (const struct nlattr * const *)info->tb);
ef1f7df9
PM
1744 if (IS_ERR(ops)) {
1745 err = PTR_ERR(ops);
1746 goto err1;
1747 }
1748 } else
1749 ops = type->ops;
1750
96518518
PM
1751 info->ops = ops;
1752 return 0;
ef1f7df9
PM
1753
1754err1:
1755 module_put(type->owner);
1756 return err;
96518518
PM
1757}
1758
1759static int nf_tables_newexpr(const struct nft_ctx *ctx,
ef1f7df9 1760 const struct nft_expr_info *info,
96518518
PM
1761 struct nft_expr *expr)
1762{
1763 const struct nft_expr_ops *ops = info->ops;
1764 int err;
1765
1766 expr->ops = ops;
1767 if (ops->init) {
ef1f7df9 1768 err = ops->init(ctx, expr, (const struct nlattr **)info->tb);
96518518
PM
1769 if (err < 0)
1770 goto err1;
1771 }
1772
96518518
PM
1773 return 0;
1774
1775err1:
1776 expr->ops = NULL;
1777 return err;
1778}
1779
62472bce
PM
1780static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
1781 struct nft_expr *expr)
96518518
PM
1782{
1783 if (expr->ops->destroy)
62472bce 1784 expr->ops->destroy(ctx, expr);
ef1f7df9 1785 module_put(expr->ops->type->owner);
96518518
PM
1786}
1787
0b2d8a7b
PM
1788struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
1789 const struct nlattr *nla)
1790{
1791 struct nft_expr_info info;
1792 struct nft_expr *expr;
1793 int err;
1794
1795 err = nf_tables_expr_parse(ctx, nla, &info);
1796 if (err < 0)
1797 goto err1;
1798
1799 err = -ENOMEM;
1800 expr = kzalloc(info.ops->size, GFP_KERNEL);
1801 if (expr == NULL)
1802 goto err2;
1803
1804 err = nf_tables_newexpr(ctx, &info, expr);
1805 if (err < 0)
6cafaf47 1806 goto err3;
0b2d8a7b
PM
1807
1808 return expr;
6cafaf47
LZ
1809err3:
1810 kfree(expr);
0b2d8a7b
PM
1811err2:
1812 module_put(info.ops->type->owner);
1813err1:
1814 return ERR_PTR(err);
1815}
1816
1817void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
1818{
1819 nf_tables_expr_destroy(ctx, expr);
1820 kfree(expr);
1821}
1822
96518518
PM
1823/*
1824 * Rules
1825 */
1826
1827static struct nft_rule *__nf_tables_rule_lookup(const struct nft_chain *chain,
1828 u64 handle)
1829{
1830 struct nft_rule *rule;
1831
1832 // FIXME: this sucks
1833 list_for_each_entry(rule, &chain->rules, list) {
1834 if (handle == rule->handle)
1835 return rule;
1836 }
1837
1838 return ERR_PTR(-ENOENT);
1839}
1840
1841static struct nft_rule *nf_tables_rule_lookup(const struct nft_chain *chain,
1842 const struct nlattr *nla)
1843{
1844 if (nla == NULL)
1845 return ERR_PTR(-EINVAL);
1846
1847 return __nf_tables_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
1848}
1849
1850static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
1851 [NFTA_RULE_TABLE] = { .type = NLA_STRING },
1852 [NFTA_RULE_CHAIN] = { .type = NLA_STRING,
1853 .len = NFT_CHAIN_MAXNAMELEN - 1 },
1854 [NFTA_RULE_HANDLE] = { .type = NLA_U64 },
1855 [NFTA_RULE_EXPRESSIONS] = { .type = NLA_NESTED },
0ca743a5 1856 [NFTA_RULE_COMPAT] = { .type = NLA_NESTED },
5e948466 1857 [NFTA_RULE_POSITION] = { .type = NLA_U64 },
0768b3b3
PNA
1858 [NFTA_RULE_USERDATA] = { .type = NLA_BINARY,
1859 .len = NFT_USERDATA_MAXLEN },
96518518
PM
1860};
1861
84d7fce6
PNA
1862static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
1863 u32 portid, u32 seq, int event,
1864 u32 flags, int family,
96518518
PM
1865 const struct nft_table *table,
1866 const struct nft_chain *chain,
1867 const struct nft_rule *rule)
1868{
1869 struct nlmsghdr *nlh;
1870 struct nfgenmsg *nfmsg;
1871 const struct nft_expr *expr, *next;
1872 struct nlattr *list;
5e948466
EL
1873 const struct nft_rule *prule;
1874 int type = event | NFNL_SUBSYS_NFTABLES << 8;
96518518 1875
5e948466 1876 nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg),
96518518
PM
1877 flags);
1878 if (nlh == NULL)
1879 goto nla_put_failure;
1880
1881 nfmsg = nlmsg_data(nlh);
1882 nfmsg->nfgen_family = family;
1883 nfmsg->version = NFNETLINK_V0;
84d7fce6 1884 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518
PM
1885
1886 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
1887 goto nla_put_failure;
1888 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
1889 goto nla_put_failure;
b46f6ded
ND
1890 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle),
1891 NFTA_RULE_PAD))
96518518
PM
1892 goto nla_put_failure;
1893
5e948466
EL
1894 if ((event != NFT_MSG_DELRULE) && (rule->list.prev != &chain->rules)) {
1895 prule = list_entry(rule->list.prev, struct nft_rule, list);
1896 if (nla_put_be64(skb, NFTA_RULE_POSITION,
b46f6ded
ND
1897 cpu_to_be64(prule->handle),
1898 NFTA_RULE_PAD))
5e948466
EL
1899 goto nla_put_failure;
1900 }
1901
96518518
PM
1902 list = nla_nest_start(skb, NFTA_RULE_EXPRESSIONS);
1903 if (list == NULL)
1904 goto nla_put_failure;
1905 nft_rule_for_each_expr(expr, next, rule) {
0b2d8a7b 1906 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
96518518 1907 goto nla_put_failure;
96518518
PM
1908 }
1909 nla_nest_end(skb, list);
1910
86f1ec32
PM
1911 if (rule->udata) {
1912 struct nft_userdata *udata = nft_userdata(rule);
1913 if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
1914 udata->data) < 0)
1915 goto nla_put_failure;
1916 }
0768b3b3 1917
053c095a
JB
1918 nlmsg_end(skb, nlh);
1919 return 0;
96518518
PM
1920
1921nla_put_failure:
1922 nlmsg_trim(skb, nlh);
1923 return -1;
1924}
1925
35151d84 1926static int nf_tables_rule_notify(const struct nft_ctx *ctx,
96518518 1927 const struct nft_rule *rule,
35151d84 1928 int event)
96518518
PM
1929{
1930 struct sk_buff *skb;
96518518
PM
1931 int err;
1932
128ad332
PNA
1933 if (!ctx->report &&
1934 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
96518518
PM
1935 return 0;
1936
1937 err = -ENOBUFS;
1938 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1939 if (skb == NULL)
1940 goto err;
1941
84d7fce6
PNA
1942 err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
1943 event, 0, ctx->afi->family, ctx->table,
35151d84 1944 ctx->chain, rule);
96518518
PM
1945 if (err < 0) {
1946 kfree_skb(skb);
1947 goto err;
1948 }
1949
128ad332
PNA
1950 err = nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1951 ctx->report, GFP_KERNEL);
96518518 1952err:
128ad332
PNA
1953 if (err < 0) {
1954 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1955 err);
1956 }
96518518
PM
1957 return err;
1958}
1959
6e1f760e
PNA
1960struct nft_rule_dump_ctx {
1961 char table[NFT_TABLE_MAXNAMELEN];
1962 char chain[NFT_CHAIN_MAXNAMELEN];
1963};
1964
96518518
PM
1965static int nf_tables_dump_rules(struct sk_buff *skb,
1966 struct netlink_callback *cb)
1967{
1968 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
6e1f760e 1969 const struct nft_rule_dump_ctx *ctx = cb->data;
96518518
PM
1970 const struct nft_af_info *afi;
1971 const struct nft_table *table;
1972 const struct nft_chain *chain;
1973 const struct nft_rule *rule;
1974 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 1975 struct net *net = sock_net(skb->sk);
96518518
PM
1976 int family = nfmsg->nfgen_family;
1977
e688a7f8 1978 rcu_read_lock();
38e029f1
PNA
1979 cb->seq = net->nft.base_seq;
1980
e688a7f8 1981 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
96518518
PM
1982 if (family != NFPROTO_UNSPEC && family != afi->family)
1983 continue;
1984
e688a7f8 1985 list_for_each_entry_rcu(table, &afi->tables, list) {
6e1f760e
PNA
1986 if (ctx && ctx->table[0] &&
1987 strcmp(ctx->table, table->name) != 0)
1988 continue;
1989
e688a7f8 1990 list_for_each_entry_rcu(chain, &table->chains, list) {
6e1f760e
PNA
1991 if (ctx && ctx->chain[0] &&
1992 strcmp(ctx->chain, chain->name) != 0)
1993 continue;
1994
e688a7f8 1995 list_for_each_entry_rcu(rule, &chain->rules, list) {
889f7ee7 1996 if (!nft_is_active(net, rule))
0628b123 1997 goto cont;
96518518
PM
1998 if (idx < s_idx)
1999 goto cont;
2000 if (idx > s_idx)
2001 memset(&cb->args[1], 0,
2002 sizeof(cb->args) - sizeof(cb->args[0]));
84d7fce6 2003 if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
96518518
PM
2004 cb->nlh->nlmsg_seq,
2005 NFT_MSG_NEWRULE,
2006 NLM_F_MULTI | NLM_F_APPEND,
2007 afi->family, table, chain, rule) < 0)
2008 goto done;
38e029f1
PNA
2009
2010 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518
PM
2011cont:
2012 idx++;
2013 }
2014 }
2015 }
2016 }
2017done:
e688a7f8
PNA
2018 rcu_read_unlock();
2019
96518518
PM
2020 cb->args[0] = idx;
2021 return skb->len;
2022}
2023
6e1f760e
PNA
2024static int nf_tables_dump_rules_done(struct netlink_callback *cb)
2025{
2026 kfree(cb->data);
2027 return 0;
2028}
2029
7b8002a1
PNA
2030static int nf_tables_getrule(struct net *net, struct sock *nlsk,
2031 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
2032 const struct nlattr * const nla[])
2033{
2034 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2035 u8 genmask = nft_genmask_cur(net);
96518518
PM
2036 const struct nft_af_info *afi;
2037 const struct nft_table *table;
2038 const struct nft_chain *chain;
2039 const struct nft_rule *rule;
2040 struct sk_buff *skb2;
2041 int family = nfmsg->nfgen_family;
2042 int err;
2043
2044 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2045 struct netlink_dump_control c = {
2046 .dump = nf_tables_dump_rules,
6e1f760e 2047 .done = nf_tables_dump_rules_done,
96518518 2048 };
6e1f760e
PNA
2049
2050 if (nla[NFTA_RULE_TABLE] || nla[NFTA_RULE_CHAIN]) {
2051 struct nft_rule_dump_ctx *ctx;
2052
2053 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2054 if (!ctx)
2055 return -ENOMEM;
2056
2057 if (nla[NFTA_RULE_TABLE])
2058 nla_strlcpy(ctx->table, nla[NFTA_RULE_TABLE],
2059 sizeof(ctx->table));
2060 if (nla[NFTA_RULE_CHAIN])
2061 nla_strlcpy(ctx->chain, nla[NFTA_RULE_CHAIN],
2062 sizeof(ctx->chain));
2063 c.data = ctx;
2064 }
2065
96518518
PM
2066 return netlink_dump_start(nlsk, skb, nlh, &c);
2067 }
2068
99633ab2 2069 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
2070 if (IS_ERR(afi))
2071 return PTR_ERR(afi);
2072
f2a6d766 2073 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
96518518
PM
2074 if (IS_ERR(table))
2075 return PTR_ERR(table);
2076
664b0f8c 2077 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
96518518
PM
2078 if (IS_ERR(chain))
2079 return PTR_ERR(chain);
2080
2081 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
2082 if (IS_ERR(rule))
2083 return PTR_ERR(rule);
2084
2085 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2086 if (!skb2)
2087 return -ENOMEM;
2088
84d7fce6 2089 err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
2090 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
2091 family, table, chain, rule);
2092 if (err < 0)
2093 goto err;
2094
2095 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2096
2097err:
2098 kfree_skb(skb2);
2099 return err;
2100}
2101
62472bce
PM
2102static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
2103 struct nft_rule *rule)
96518518 2104{
96518518
PM
2105 struct nft_expr *expr;
2106
2107 /*
2108 * Careful: some expressions might not be initialized in case this
2109 * is called on error from nf_tables_newrule().
2110 */
2111 expr = nft_expr_first(rule);
2112 while (expr->ops && expr != nft_expr_last(rule)) {
62472bce 2113 nf_tables_expr_destroy(ctx, expr);
96518518
PM
2114 expr = nft_expr_next(expr);
2115 }
2116 kfree(rule);
2117}
2118
1081d11b
PNA
2119#define NFT_RULE_MAXEXPRS 128
2120
2121static struct nft_expr_info *info;
2122
633c9a84
PNA
2123static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2124 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
2125 const struct nlattr * const nla[])
2126{
2127 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2128 u8 genmask = nft_genmask_next(net);
7c95f6d8 2129 struct nft_af_info *afi;
96518518
PM
2130 struct nft_table *table;
2131 struct nft_chain *chain;
2132 struct nft_rule *rule, *old_rule = NULL;
86f1ec32 2133 struct nft_userdata *udata;
1081d11b 2134 struct nft_trans *trans = NULL;
96518518
PM
2135 struct nft_expr *expr;
2136 struct nft_ctx ctx;
2137 struct nlattr *tmp;
86f1ec32 2138 unsigned int size, i, n, ulen = 0, usize = 0;
96518518
PM
2139 int err, rem;
2140 bool create;
5e948466 2141 u64 handle, pos_handle;
96518518
PM
2142
2143 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
2144
99633ab2 2145 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
96518518
PM
2146 if (IS_ERR(afi))
2147 return PTR_ERR(afi);
2148
f2a6d766 2149 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
96518518
PM
2150 if (IS_ERR(table))
2151 return PTR_ERR(table);
2152
664b0f8c 2153 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
96518518
PM
2154 if (IS_ERR(chain))
2155 return PTR_ERR(chain);
2156
2157 if (nla[NFTA_RULE_HANDLE]) {
2158 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
2159 rule = __nf_tables_rule_lookup(chain, handle);
2160 if (IS_ERR(rule))
2161 return PTR_ERR(rule);
2162
2163 if (nlh->nlmsg_flags & NLM_F_EXCL)
2164 return -EEXIST;
2165 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2166 old_rule = rule;
2167 else
2168 return -EOPNOTSUPP;
2169 } else {
2170 if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
2171 return -EINVAL;
2172 handle = nf_tables_alloc_handle(table);
a0a7379e
PNA
2173
2174 if (chain->use == UINT_MAX)
2175 return -EOVERFLOW;
96518518
PM
2176 }
2177
5e948466
EL
2178 if (nla[NFTA_RULE_POSITION]) {
2179 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
2180 return -EOPNOTSUPP;
2181
2182 pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
2183 old_rule = __nf_tables_rule_lookup(chain, pos_handle);
2184 if (IS_ERR(old_rule))
2185 return PTR_ERR(old_rule);
2186 }
2187
633c9a84 2188 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
0ca743a5 2189
96518518
PM
2190 n = 0;
2191 size = 0;
2192 if (nla[NFTA_RULE_EXPRESSIONS]) {
2193 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
2194 err = -EINVAL;
2195 if (nla_type(tmp) != NFTA_LIST_ELEM)
2196 goto err1;
2197 if (n == NFT_RULE_MAXEXPRS)
2198 goto err1;
0ca743a5 2199 err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
96518518
PM
2200 if (err < 0)
2201 goto err1;
2202 size += info[n].ops->size;
2203 n++;
2204 }
2205 }
9889840f
PM
2206 /* Check for overflow of dlen field */
2207 err = -EFBIG;
2208 if (size >= 1 << 12)
2209 goto err1;
96518518 2210
86f1ec32 2211 if (nla[NFTA_RULE_USERDATA]) {
0768b3b3 2212 ulen = nla_len(nla[NFTA_RULE_USERDATA]);
86f1ec32
PM
2213 if (ulen > 0)
2214 usize = sizeof(struct nft_userdata) + ulen;
2215 }
0768b3b3 2216
96518518 2217 err = -ENOMEM;
86f1ec32 2218 rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
96518518
PM
2219 if (rule == NULL)
2220 goto err1;
2221
889f7ee7 2222 nft_activate_next(net, rule);
0628b123 2223
96518518
PM
2224 rule->handle = handle;
2225 rule->dlen = size;
86f1ec32 2226 rule->udata = ulen ? 1 : 0;
0768b3b3 2227
86f1ec32
PM
2228 if (ulen) {
2229 udata = nft_userdata(rule);
2230 udata->len = ulen - 1;
2231 nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
2232 }
96518518 2233
96518518
PM
2234 expr = nft_expr_first(rule);
2235 for (i = 0; i < n; i++) {
2236 err = nf_tables_newexpr(&ctx, &info[i], expr);
2237 if (err < 0)
2238 goto err2;
ef1f7df9 2239 info[i].ops = NULL;
96518518
PM
2240 expr = nft_expr_next(expr);
2241 }
2242
96518518 2243 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
889f7ee7 2244 if (nft_is_active_next(net, old_rule)) {
ac904ac8 2245 trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
b380e5c7 2246 old_rule);
1081d11b 2247 if (trans == NULL) {
0628b123
PNA
2248 err = -ENOMEM;
2249 goto err2;
2250 }
889f7ee7 2251 nft_deactivate_next(net, old_rule);
ac34b861 2252 chain->use--;
5bc5c307 2253 list_add_tail_rcu(&rule->list, &old_rule->list);
0628b123
PNA
2254 } else {
2255 err = -ENOENT;
2256 goto err2;
2257 }
96518518 2258 } else if (nlh->nlmsg_flags & NLM_F_APPEND)
5e948466
EL
2259 if (old_rule)
2260 list_add_rcu(&rule->list, &old_rule->list);
2261 else
2262 list_add_tail_rcu(&rule->list, &chain->rules);
2263 else {
2264 if (old_rule)
2265 list_add_tail_rcu(&rule->list, &old_rule->list);
2266 else
2267 list_add_rcu(&rule->list, &chain->rules);
2268 }
96518518 2269
b380e5c7 2270 if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
0628b123
PNA
2271 err = -ENOMEM;
2272 goto err3;
2273 }
4fefee57 2274 chain->use++;
96518518
PM
2275 return 0;
2276
0628b123
PNA
2277err3:
2278 list_del_rcu(&rule->list);
96518518 2279err2:
62472bce 2280 nf_tables_rule_destroy(&ctx, rule);
96518518
PM
2281err1:
2282 for (i = 0; i < n; i++) {
2283 if (info[i].ops != NULL)
ef1f7df9 2284 module_put(info[i].ops->type->owner);
96518518
PM
2285 }
2286 return err;
2287}
2288
633c9a84
PNA
2289static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2290 struct sk_buff *skb, const struct nlmsghdr *nlh,
96518518
PM
2291 const struct nlattr * const nla[])
2292{
2293 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2294 u8 genmask = nft_genmask_next(net);
7c95f6d8 2295 struct nft_af_info *afi;
7c95f6d8 2296 struct nft_table *table;
cf9dc09d
PNA
2297 struct nft_chain *chain = NULL;
2298 struct nft_rule *rule;
0628b123
PNA
2299 int family = nfmsg->nfgen_family, err = 0;
2300 struct nft_ctx ctx;
96518518 2301
99633ab2 2302 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
2303 if (IS_ERR(afi))
2304 return PTR_ERR(afi);
2305
f2a6d766 2306 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
96518518
PM
2307 if (IS_ERR(table))
2308 return PTR_ERR(table);
2309
cf9dc09d 2310 if (nla[NFTA_RULE_CHAIN]) {
664b0f8c
PNA
2311 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN],
2312 genmask);
cf9dc09d
PNA
2313 if (IS_ERR(chain))
2314 return PTR_ERR(chain);
2315 }
96518518 2316
633c9a84 2317 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
0628b123 2318
cf9dc09d
PNA
2319 if (chain) {
2320 if (nla[NFTA_RULE_HANDLE]) {
2321 rule = nf_tables_rule_lookup(chain,
2322 nla[NFTA_RULE_HANDLE]);
2323 if (IS_ERR(rule))
2324 return PTR_ERR(rule);
96518518 2325
5e266fe7 2326 err = nft_delrule(&ctx, rule);
cf9dc09d 2327 } else {
ce24b721 2328 err = nft_delrule_by_chain(&ctx);
cf9dc09d
PNA
2329 }
2330 } else {
2331 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
2332 if (!nft_is_active_next(net, chain))
2333 continue;
2334
cf9dc09d 2335 ctx.chain = chain;
ce24b721 2336 err = nft_delrule_by_chain(&ctx);
0628b123
PNA
2337 if (err < 0)
2338 break;
2339 }
2340 }
2341
2342 return err;
2343}
2344
20a69341
PM
2345/*
2346 * Sets
2347 */
2348
2349static LIST_HEAD(nf_tables_set_ops);
2350
2351int nft_register_set(struct nft_set_ops *ops)
2352{
2353 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 2354 list_add_tail_rcu(&ops->list, &nf_tables_set_ops);
20a69341
PM
2355 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2356 return 0;
2357}
2358EXPORT_SYMBOL_GPL(nft_register_set);
2359
2360void nft_unregister_set(struct nft_set_ops *ops)
2361{
2362 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 2363 list_del_rcu(&ops->list);
20a69341
PM
2364 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2365}
2366EXPORT_SYMBOL_GPL(nft_unregister_set);
2367
c50b960c
PM
2368/*
2369 * Select a set implementation based on the data characteristics and the
2370 * given policy. The total memory use might not be known if no size is
2371 * given, in that case the amount of memory per element is used.
2372 */
2373static const struct nft_set_ops *
2374nft_select_set_ops(const struct nlattr * const nla[],
2375 const struct nft_set_desc *desc,
2376 enum nft_set_policies policy)
20a69341 2377{
c50b960c
PM
2378 const struct nft_set_ops *ops, *bops;
2379 struct nft_set_estimate est, best;
20a69341
PM
2380 u32 features;
2381
2382#ifdef CONFIG_MODULES
2383 if (list_empty(&nf_tables_set_ops)) {
2384 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2385 request_module("nft-set");
2386 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2387 if (!list_empty(&nf_tables_set_ops))
2388 return ERR_PTR(-EAGAIN);
2389 }
2390#endif
2391 features = 0;
2392 if (nla[NFTA_SET_FLAGS] != NULL) {
2393 features = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
4a8678ef 2394 features &= NFT_SET_INTERVAL | NFT_SET_MAP | NFT_SET_TIMEOUT;
20a69341
PM
2395 }
2396
c50b960c
PM
2397 bops = NULL;
2398 best.size = ~0;
2399 best.class = ~0;
2400
20a69341
PM
2401 list_for_each_entry(ops, &nf_tables_set_ops, list) {
2402 if ((ops->features & features) != features)
2403 continue;
c50b960c
PM
2404 if (!ops->estimate(desc, features, &est))
2405 continue;
2406
2407 switch (policy) {
2408 case NFT_SET_POL_PERFORMANCE:
2409 if (est.class < best.class)
2410 break;
2411 if (est.class == best.class && est.size < best.size)
2412 break;
2413 continue;
2414 case NFT_SET_POL_MEMORY:
2415 if (est.size < best.size)
2416 break;
2417 if (est.size == best.size && est.class < best.class)
2418 break;
2419 continue;
2420 default:
2421 break;
2422 }
2423
20a69341
PM
2424 if (!try_module_get(ops->owner))
2425 continue;
c50b960c
PM
2426 if (bops != NULL)
2427 module_put(bops->owner);
2428
2429 bops = ops;
2430 best = est;
20a69341
PM
2431 }
2432
c50b960c
PM
2433 if (bops != NULL)
2434 return bops;
2435
20a69341
PM
2436 return ERR_PTR(-EOPNOTSUPP);
2437}
2438
2439static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
2440 [NFTA_SET_TABLE] = { .type = NLA_STRING },
a9bdd836 2441 [NFTA_SET_NAME] = { .type = NLA_STRING,
cb39ad8b 2442 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341
PM
2443 [NFTA_SET_FLAGS] = { .type = NLA_U32 },
2444 [NFTA_SET_KEY_TYPE] = { .type = NLA_U32 },
2445 [NFTA_SET_KEY_LEN] = { .type = NLA_U32 },
2446 [NFTA_SET_DATA_TYPE] = { .type = NLA_U32 },
2447 [NFTA_SET_DATA_LEN] = { .type = NLA_U32 },
c50b960c
PM
2448 [NFTA_SET_POLICY] = { .type = NLA_U32 },
2449 [NFTA_SET_DESC] = { .type = NLA_NESTED },
958bee14 2450 [NFTA_SET_ID] = { .type = NLA_U32 },
761da293
PM
2451 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
2452 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
e6d8ecac
CFG
2453 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
2454 .len = NFT_USERDATA_MAXLEN },
8aeff920 2455 [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },
c50b960c
PM
2456};
2457
2458static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
2459 [NFTA_SET_DESC_SIZE] = { .type = NLA_U32 },
20a69341
PM
2460};
2461
633c9a84 2462static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
2463 const struct sk_buff *skb,
2464 const struct nlmsghdr *nlh,
f2a6d766
PNA
2465 const struct nlattr * const nla[],
2466 u8 genmask)
20a69341
PM
2467{
2468 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7c95f6d8
PNA
2469 struct nft_af_info *afi = NULL;
2470 struct nft_table *table = NULL;
20a69341 2471
c9c8e485
PNA
2472 if (nfmsg->nfgen_family != NFPROTO_UNSPEC) {
2473 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
2474 if (IS_ERR(afi))
2475 return PTR_ERR(afi);
2476 }
20a69341
PM
2477
2478 if (nla[NFTA_SET_TABLE] != NULL) {
ec2c9935
PM
2479 if (afi == NULL)
2480 return -EAFNOSUPPORT;
2481
f2a6d766
PNA
2482 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE],
2483 genmask);
20a69341
PM
2484 if (IS_ERR(table))
2485 return PTR_ERR(table);
2486 }
2487
633c9a84 2488 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
20a69341
PM
2489 return 0;
2490}
2491
2492struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
37a9cc52 2493 const struct nlattr *nla, u8 genmask)
20a69341
PM
2494{
2495 struct nft_set *set;
2496
2497 if (nla == NULL)
2498 return ERR_PTR(-EINVAL);
2499
2500 list_for_each_entry(set, &table->sets, list) {
37a9cc52
PNA
2501 if (!nla_strcmp(nla, set->name) &&
2502 nft_active_genmask(set, genmask))
20a69341
PM
2503 return set;
2504 }
2505 return ERR_PTR(-ENOENT);
2506}
63aea290 2507EXPORT_SYMBOL_GPL(nf_tables_set_lookup);
20a69341 2508
958bee14 2509struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
37a9cc52
PNA
2510 const struct nlattr *nla,
2511 u8 genmask)
958bee14
PNA
2512{
2513 struct nft_trans *trans;
2514 u32 id = ntohl(nla_get_be32(nla));
2515
2516 list_for_each_entry(trans, &net->nft.commit_list, list) {
37a9cc52
PNA
2517 struct nft_set *set = nft_trans_set(trans);
2518
958bee14 2519 if (trans->msg_type == NFT_MSG_NEWSET &&
37a9cc52
PNA
2520 id == nft_trans_set_id(trans) &&
2521 nft_active_genmask(set, genmask))
2522 return set;
958bee14
PNA
2523 }
2524 return ERR_PTR(-ENOENT);
2525}
63aea290 2526EXPORT_SYMBOL_GPL(nf_tables_set_lookup_byid);
958bee14 2527
20a69341
PM
2528static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
2529 const char *name)
2530{
2531 const struct nft_set *i;
2532 const char *p;
2533 unsigned long *inuse;
60eb1894 2534 unsigned int n = 0, min = 0;
20a69341 2535
cb39ad8b 2536 p = strnchr(name, NFT_SET_MAXNAMELEN, '%');
20a69341
PM
2537 if (p != NULL) {
2538 if (p[1] != 'd' || strchr(p + 2, '%'))
2539 return -EINVAL;
2540
2541 inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
2542 if (inuse == NULL)
2543 return -ENOMEM;
60eb1894 2544cont:
20a69341 2545 list_for_each_entry(i, &ctx->table->sets, list) {
14662917
DB
2546 int tmp;
2547
37a9cc52
PNA
2548 if (!nft_is_active_next(ctx->net, set))
2549 continue;
14662917 2550 if (!sscanf(i->name, name, &tmp))
20a69341 2551 continue;
60eb1894 2552 if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
20a69341 2553 continue;
14662917 2554
60eb1894 2555 set_bit(tmp - min, inuse);
20a69341
PM
2556 }
2557
53b70287 2558 n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
60eb1894
PM
2559 if (n >= BITS_PER_BYTE * PAGE_SIZE) {
2560 min += BITS_PER_BYTE * PAGE_SIZE;
2561 memset(inuse, 0, PAGE_SIZE);
2562 goto cont;
2563 }
20a69341
PM
2564 free_page((unsigned long)inuse);
2565 }
2566
60eb1894 2567 snprintf(set->name, sizeof(set->name), name, min + n);
20a69341 2568 list_for_each_entry(i, &ctx->table->sets, list) {
37a9cc52
PNA
2569 if (!nft_is_active_next(ctx->net, i))
2570 continue;
20a69341
PM
2571 if (!strcmp(set->name, i->name))
2572 return -ENFILE;
2573 }
2574 return 0;
2575}
2576
2577static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
2578 const struct nft_set *set, u16 event, u16 flags)
2579{
2580 struct nfgenmsg *nfmsg;
2581 struct nlmsghdr *nlh;
c50b960c 2582 struct nlattr *desc;
128ad332
PNA
2583 u32 portid = ctx->portid;
2584 u32 seq = ctx->seq;
20a69341
PM
2585
2586 event |= NFNL_SUBSYS_NFTABLES << 8;
2587 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
2588 flags);
2589 if (nlh == NULL)
2590 goto nla_put_failure;
2591
2592 nfmsg = nlmsg_data(nlh);
2593 nfmsg->nfgen_family = ctx->afi->family;
2594 nfmsg->version = NFNETLINK_V0;
84d7fce6 2595 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
20a69341
PM
2596
2597 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
2598 goto nla_put_failure;
2599 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
2600 goto nla_put_failure;
2601 if (set->flags != 0)
2602 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
2603 goto nla_put_failure;
2604
2605 if (nla_put_be32(skb, NFTA_SET_KEY_TYPE, htonl(set->ktype)))
2606 goto nla_put_failure;
2607 if (nla_put_be32(skb, NFTA_SET_KEY_LEN, htonl(set->klen)))
2608 goto nla_put_failure;
2609 if (set->flags & NFT_SET_MAP) {
2610 if (nla_put_be32(skb, NFTA_SET_DATA_TYPE, htonl(set->dtype)))
2611 goto nla_put_failure;
2612 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
2613 goto nla_put_failure;
2614 }
8aeff920
PNA
2615 if (set->flags & NFT_SET_OBJECT &&
2616 nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
2617 goto nla_put_failure;
20a69341 2618
761da293 2619 if (set->timeout &&
d3e2a111
AP
2620 nla_put_be64(skb, NFTA_SET_TIMEOUT,
2621 cpu_to_be64(jiffies_to_msecs(set->timeout)),
b46f6ded 2622 NFTA_SET_PAD))
761da293
PM
2623 goto nla_put_failure;
2624 if (set->gc_int &&
2625 nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
2626 goto nla_put_failure;
2627
9363dc4b
AB
2628 if (set->policy != NFT_SET_POL_PERFORMANCE) {
2629 if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
2630 goto nla_put_failure;
2631 }
2632
e6d8ecac
CFG
2633 if (nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata))
2634 goto nla_put_failure;
2635
c50b960c
PM
2636 desc = nla_nest_start(skb, NFTA_SET_DESC);
2637 if (desc == NULL)
2638 goto nla_put_failure;
2639 if (set->size &&
2640 nla_put_be32(skb, NFTA_SET_DESC_SIZE, htonl(set->size)))
2641 goto nla_put_failure;
2642 nla_nest_end(skb, desc);
2643
053c095a
JB
2644 nlmsg_end(skb, nlh);
2645 return 0;
20a69341
PM
2646
2647nla_put_failure:
2648 nlmsg_trim(skb, nlh);
2649 return -1;
2650}
2651
2652static int nf_tables_set_notify(const struct nft_ctx *ctx,
2653 const struct nft_set *set,
31f8441c 2654 int event, gfp_t gfp_flags)
20a69341
PM
2655{
2656 struct sk_buff *skb;
128ad332 2657 u32 portid = ctx->portid;
20a69341
PM
2658 int err;
2659
128ad332
PNA
2660 if (!ctx->report &&
2661 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
20a69341
PM
2662 return 0;
2663
2664 err = -ENOBUFS;
31f8441c 2665 skb = nlmsg_new(NLMSG_GOODSIZE, gfp_flags);
20a69341
PM
2666 if (skb == NULL)
2667 goto err;
2668
2669 err = nf_tables_fill_set(skb, ctx, set, event, 0);
2670 if (err < 0) {
2671 kfree_skb(skb);
2672 goto err;
2673 }
2674
128ad332 2675 err = nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES,
31f8441c 2676 ctx->report, gfp_flags);
20a69341
PM
2677err:
2678 if (err < 0)
99633ab2 2679 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, err);
20a69341
PM
2680 return err;
2681}
2682
5b96af77 2683static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
c9c8e485
PNA
2684{
2685 const struct nft_set *set;
2686 unsigned int idx, s_idx = cb->args[0];
7c95f6d8 2687 struct nft_af_info *afi;
c9c8e485
PNA
2688 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
2689 struct net *net = sock_net(skb->sk);
2690 int cur_family = cb->args[3];
5b96af77 2691 struct nft_ctx *ctx = cb->data, ctx_set;
c9c8e485
PNA
2692
2693 if (cb->args[1])
2694 return skb->len;
2695
e688a7f8 2696 rcu_read_lock();
38e029f1
PNA
2697 cb->seq = net->nft.base_seq;
2698
e688a7f8 2699 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
5b96af77
PNA
2700 if (ctx->afi && ctx->afi != afi)
2701 continue;
2702
c9c8e485
PNA
2703 if (cur_family) {
2704 if (afi->family != cur_family)
2705 continue;
2706
2707 cur_family = 0;
2708 }
e688a7f8 2709 list_for_each_entry_rcu(table, &afi->tables, list) {
5b96af77
PNA
2710 if (ctx->table && ctx->table != table)
2711 continue;
2712
c9c8e485
PNA
2713 if (cur_table) {
2714 if (cur_table != table)
2715 continue;
2716
2717 cur_table = NULL;
2718 }
c9c8e485 2719 idx = 0;
5b96af77 2720 list_for_each_entry_rcu(set, &table->sets, list) {
c9c8e485
PNA
2721 if (idx < s_idx)
2722 goto cont;
37a9cc52
PNA
2723 if (!nft_is_active(net, set))
2724 goto cont;
5b96af77
PNA
2725
2726 ctx_set = *ctx;
2727 ctx_set.table = table;
2728 ctx_set.afi = afi;
2729 if (nf_tables_fill_set(skb, &ctx_set, set,
c9c8e485
PNA
2730 NFT_MSG_NEWSET,
2731 NLM_F_MULTI) < 0) {
2732 cb->args[0] = idx;
2733 cb->args[2] = (unsigned long) table;
2734 cb->args[3] = afi->family;
2735 goto done;
2736 }
38e029f1 2737 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
c9c8e485
PNA
2738cont:
2739 idx++;
2740 }
2741 if (s_idx)
2742 s_idx = 0;
2743 }
2744 }
2745 cb->args[1] = 1;
2746done:
e688a7f8 2747 rcu_read_unlock();
c9c8e485
PNA
2748 return skb->len;
2749}
2750
5b96af77 2751static int nf_tables_dump_sets_done(struct netlink_callback *cb)
20a69341 2752{
5b96af77
PNA
2753 kfree(cb->data);
2754 return 0;
20a69341
PM
2755}
2756
7b8002a1
PNA
2757static int nf_tables_getset(struct net *net, struct sock *nlsk,
2758 struct sk_buff *skb, const struct nlmsghdr *nlh,
20a69341
PM
2759 const struct nlattr * const nla[])
2760{
f2a6d766 2761 u8 genmask = nft_genmask_cur(net);
20a69341
PM
2762 const struct nft_set *set;
2763 struct nft_ctx ctx;
2764 struct sk_buff *skb2;
c9c8e485 2765 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
20a69341
PM
2766 int err;
2767
01cfa0a4 2768 /* Verify existence before starting dump */
f2a6d766 2769 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
2770 if (err < 0)
2771 return err;
2772
2773 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2774 struct netlink_dump_control c = {
2775 .dump = nf_tables_dump_sets,
5b96af77 2776 .done = nf_tables_dump_sets_done,
20a69341 2777 };
5b96af77
PNA
2778 struct nft_ctx *ctx_dump;
2779
2780 ctx_dump = kmalloc(sizeof(*ctx_dump), GFP_KERNEL);
2781 if (ctx_dump == NULL)
2782 return -ENOMEM;
2783
2784 *ctx_dump = ctx;
2785 c.data = ctx_dump;
2786
20a69341
PM
2787 return netlink_dump_start(nlsk, skb, nlh, &c);
2788 }
2789
c9c8e485
PNA
2790 /* Only accept unspec with dump */
2791 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
2792 return -EAFNOSUPPORT;
eaa2bcd6
PT
2793 if (!nla[NFTA_SET_TABLE])
2794 return -EINVAL;
c9c8e485 2795
37a9cc52 2796 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
2797 if (IS_ERR(set))
2798 return PTR_ERR(set);
2799
2800 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2801 if (skb2 == NULL)
2802 return -ENOMEM;
2803
2804 err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
2805 if (err < 0)
2806 goto err;
2807
2808 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2809
2810err:
2811 kfree_skb(skb2);
2812 return err;
2813}
2814
c50b960c
PM
2815static int nf_tables_set_desc_parse(const struct nft_ctx *ctx,
2816 struct nft_set_desc *desc,
2817 const struct nlattr *nla)
2818{
2819 struct nlattr *da[NFTA_SET_DESC_MAX + 1];
2820 int err;
2821
2822 err = nla_parse_nested(da, NFTA_SET_DESC_MAX, nla, nft_set_desc_policy);
2823 if (err < 0)
2824 return err;
2825
2826 if (da[NFTA_SET_DESC_SIZE] != NULL)
2827 desc->size = ntohl(nla_get_be32(da[NFTA_SET_DESC_SIZE]));
2828
2829 return 0;
2830}
2831
633c9a84
PNA
2832static int nf_tables_newset(struct net *net, struct sock *nlsk,
2833 struct sk_buff *skb, const struct nlmsghdr *nlh,
20a69341
PM
2834 const struct nlattr * const nla[])
2835{
2836 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2837 u8 genmask = nft_genmask_next(net);
20a69341 2838 const struct nft_set_ops *ops;
7c95f6d8 2839 struct nft_af_info *afi;
20a69341
PM
2840 struct nft_table *table;
2841 struct nft_set *set;
2842 struct nft_ctx ctx;
cb39ad8b 2843 char name[NFT_SET_MAXNAMELEN];
20a69341
PM
2844 unsigned int size;
2845 bool create;
761da293 2846 u64 timeout;
8aeff920 2847 u32 ktype, dtype, flags, policy, gc_int, objtype;
c50b960c 2848 struct nft_set_desc desc;
e6d8ecac
CFG
2849 unsigned char *udata;
2850 u16 udlen;
20a69341
PM
2851 int err;
2852
2853 if (nla[NFTA_SET_TABLE] == NULL ||
2854 nla[NFTA_SET_NAME] == NULL ||
958bee14
PNA
2855 nla[NFTA_SET_KEY_LEN] == NULL ||
2856 nla[NFTA_SET_ID] == NULL)
20a69341
PM
2857 return -EINVAL;
2858
c50b960c
PM
2859 memset(&desc, 0, sizeof(desc));
2860
20a69341
PM
2861 ktype = NFT_DATA_VALUE;
2862 if (nla[NFTA_SET_KEY_TYPE] != NULL) {
2863 ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
2864 if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
2865 return -EINVAL;
2866 }
2867
c50b960c 2868 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
7d740264 2869 if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
2870 return -EINVAL;
2871
2872 flags = 0;
2873 if (nla[NFTA_SET_FLAGS] != NULL) {
2874 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2875 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
7c6c6e95 2876 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
8aeff920
PNA
2877 NFT_SET_MAP | NFT_SET_EVAL |
2878 NFT_SET_OBJECT))
20a69341 2879 return -EINVAL;
8aeff920
PNA
2880 /* Only one of these operations is supported */
2881 if ((flags & (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT)) ==
2882 (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT))
7c6c6e95 2883 return -EOPNOTSUPP;
20a69341
PM
2884 }
2885
2886 dtype = 0;
20a69341
PM
2887 if (nla[NFTA_SET_DATA_TYPE] != NULL) {
2888 if (!(flags & NFT_SET_MAP))
2889 return -EINVAL;
2890
2891 dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
2892 if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
2893 dtype != NFT_DATA_VERDICT)
2894 return -EINVAL;
2895
2896 if (dtype != NFT_DATA_VERDICT) {
2897 if (nla[NFTA_SET_DATA_LEN] == NULL)
2898 return -EINVAL;
c50b960c 2899 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
7d740264 2900 if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
2901 return -EINVAL;
2902 } else
7d740264 2903 desc.dlen = sizeof(struct nft_verdict);
20a69341
PM
2904 } else if (flags & NFT_SET_MAP)
2905 return -EINVAL;
2906
8aeff920
PNA
2907 if (nla[NFTA_SET_OBJ_TYPE] != NULL) {
2908 if (!(flags & NFT_SET_OBJECT))
2909 return -EINVAL;
2910
2911 objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
2912 if (objtype == NFT_OBJECT_UNSPEC ||
2913 objtype > NFT_OBJECT_MAX)
2914 return -EINVAL;
2915 } else if (flags & NFT_SET_OBJECT)
2916 return -EINVAL;
2917 else
2918 objtype = NFT_OBJECT_UNSPEC;
2919
761da293
PM
2920 timeout = 0;
2921 if (nla[NFTA_SET_TIMEOUT] != NULL) {
2922 if (!(flags & NFT_SET_TIMEOUT))
2923 return -EINVAL;
d3e2a111
AP
2924 timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
2925 nla[NFTA_SET_TIMEOUT])));
761da293
PM
2926 }
2927 gc_int = 0;
2928 if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
2929 if (!(flags & NFT_SET_TIMEOUT))
2930 return -EINVAL;
2931 gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
2932 }
2933
c50b960c
PM
2934 policy = NFT_SET_POL_PERFORMANCE;
2935 if (nla[NFTA_SET_POLICY] != NULL)
2936 policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
2937
2938 if (nla[NFTA_SET_DESC] != NULL) {
2939 err = nf_tables_set_desc_parse(&ctx, &desc, nla[NFTA_SET_DESC]);
2940 if (err < 0)
2941 return err;
2942 }
2943
20a69341
PM
2944 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
2945
99633ab2 2946 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
20a69341
PM
2947 if (IS_ERR(afi))
2948 return PTR_ERR(afi);
2949
f2a6d766 2950 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], genmask);
20a69341
PM
2951 if (IS_ERR(table))
2952 return PTR_ERR(table);
2953
633c9a84 2954 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
20a69341 2955
37a9cc52 2956 set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
2957 if (IS_ERR(set)) {
2958 if (PTR_ERR(set) != -ENOENT)
2959 return PTR_ERR(set);
2960 set = NULL;
2961 }
2962
2963 if (set != NULL) {
2964 if (nlh->nlmsg_flags & NLM_F_EXCL)
2965 return -EEXIST;
2966 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2967 return -EOPNOTSUPP;
2968 return 0;
2969 }
2970
2971 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
2972 return -ENOENT;
2973
c50b960c 2974 ops = nft_select_set_ops(nla, &desc, policy);
20a69341
PM
2975 if (IS_ERR(ops))
2976 return PTR_ERR(ops);
2977
e6d8ecac
CFG
2978 udlen = 0;
2979 if (nla[NFTA_SET_USERDATA])
2980 udlen = nla_len(nla[NFTA_SET_USERDATA]);
2981
20a69341
PM
2982 size = 0;
2983 if (ops->privsize != NULL)
2984 size = ops->privsize(nla);
2985
2986 err = -ENOMEM;
e6d8ecac 2987 set = kzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
20a69341
PM
2988 if (set == NULL)
2989 goto err1;
2990
2991 nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name));
2992 err = nf_tables_set_alloc_name(&ctx, set, name);
2993 if (err < 0)
2994 goto err2;
2995
e6d8ecac
CFG
2996 udata = NULL;
2997 if (udlen) {
2998 udata = set->data + size;
2999 nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
3000 }
3001
20a69341
PM
3002 INIT_LIST_HEAD(&set->bindings);
3003 set->ops = ops;
3004 set->ktype = ktype;
c50b960c 3005 set->klen = desc.klen;
20a69341 3006 set->dtype = dtype;
8aeff920 3007 set->objtype = objtype;
c50b960c 3008 set->dlen = desc.dlen;
20a69341 3009 set->flags = flags;
c50b960c 3010 set->size = desc.size;
9363dc4b 3011 set->policy = policy;
e6d8ecac
CFG
3012 set->udlen = udlen;
3013 set->udata = udata;
761da293
PM
3014 set->timeout = timeout;
3015 set->gc_int = gc_int;
20a69341 3016
c50b960c 3017 err = ops->init(set, &desc, nla);
20a69341
PM
3018 if (err < 0)
3019 goto err2;
3020
958bee14 3021 err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
20a69341 3022 if (err < 0)
c17c3cdf 3023 goto err3;
20a69341 3024
e688a7f8 3025 list_add_tail_rcu(&set->list, &table->sets);
4fefee57 3026 table->use++;
20a69341
PM
3027 return 0;
3028
c17c3cdf
LZ
3029err3:
3030 ops->destroy(set);
20a69341
PM
3031err2:
3032 kfree(set);
3033err1:
3034 module_put(ops->owner);
3035 return err;
3036}
3037
958bee14 3038static void nft_set_destroy(struct nft_set *set)
20a69341 3039{
20a69341
PM
3040 set->ops->destroy(set);
3041 module_put(set->ops->owner);
3042 kfree(set);
3043}
3044
958bee14
PNA
3045static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
3046{
e688a7f8 3047 list_del_rcu(&set->list);
31f8441c 3048 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC);
958bee14
PNA
3049 nft_set_destroy(set);
3050}
3051
633c9a84
PNA
3052static int nf_tables_delset(struct net *net, struct sock *nlsk,
3053 struct sk_buff *skb, const struct nlmsghdr *nlh,
20a69341
PM
3054 const struct nlattr * const nla[])
3055{
c9c8e485 3056 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3057 u8 genmask = nft_genmask_next(net);
20a69341
PM
3058 struct nft_set *set;
3059 struct nft_ctx ctx;
3060 int err;
3061
ec2c9935
PM
3062 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
3063 return -EAFNOSUPPORT;
20a69341
PM
3064 if (nla[NFTA_SET_TABLE] == NULL)
3065 return -EINVAL;
3066
f2a6d766 3067 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
3068 if (err < 0)
3069 return err;
3070
37a9cc52 3071 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
3072 if (IS_ERR(set))
3073 return PTR_ERR(set);
3074 if (!list_empty(&set->bindings))
3075 return -EBUSY;
3076
ee01d542 3077 return nft_delset(&ctx, set);
20a69341
PM
3078}
3079
3080static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
3081 const struct nft_set *set,
3082 const struct nft_set_iter *iter,
3083 const struct nft_set_elem *elem)
3084{
fe2811eb 3085 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3086 enum nft_registers dreg;
3087
3088 dreg = nft_type_to_reg(set->dtype);
1ec10212
PM
3089 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
3090 set->dtype == NFT_DATA_VERDICT ?
3091 NFT_DATA_VERDICT : NFT_DATA_VALUE,
3092 set->dlen);
20a69341
PM
3093}
3094
3095int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
3096 struct nft_set_binding *binding)
3097{
3098 struct nft_set_binding *i;
3099 struct nft_set_iter iter;
3100
3101 if (!list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
3102 return -EBUSY;
3103
11113e19 3104 if (binding->flags & NFT_SET_MAP) {
20a69341
PM
3105 /* If the set is already bound to the same chain all
3106 * jumps are already validated for that chain.
3107 */
3108 list_for_each_entry(i, &set->bindings, list) {
a4684402 3109 if (i->flags & NFT_SET_MAP &&
11113e19 3110 i->chain == binding->chain)
20a69341
PM
3111 goto bind;
3112 }
3113
8588ac09 3114 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
3115 iter.skip = 0;
3116 iter.count = 0;
3117 iter.err = 0;
3118 iter.fn = nf_tables_bind_check_setelem;
3119
3120 set->ops->walk(ctx, set, &iter);
a02f4248 3121 if (iter.err < 0)
20a69341 3122 return iter.err;
20a69341
PM
3123 }
3124bind:
3125 binding->chain = ctx->chain;
e688a7f8 3126 list_add_tail_rcu(&binding->list, &set->bindings);
20a69341
PM
3127 return 0;
3128}
63aea290 3129EXPORT_SYMBOL_GPL(nf_tables_bind_set);
20a69341
PM
3130
3131void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
3132 struct nft_set_binding *binding)
3133{
e688a7f8 3134 list_del_rcu(&binding->list);
20a69341 3135
958bee14 3136 if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS &&
37a9cc52 3137 nft_is_active(ctx->net, set))
20a69341
PM
3138 nf_tables_set_destroy(ctx, set);
3139}
63aea290 3140EXPORT_SYMBOL_GPL(nf_tables_unbind_set);
20a69341 3141
3ac4c07a
PM
3142const struct nft_set_ext_type nft_set_ext_types[] = {
3143 [NFT_SET_EXT_KEY] = {
7d740264 3144 .align = __alignof__(u32),
3ac4c07a
PM
3145 },
3146 [NFT_SET_EXT_DATA] = {
7d740264 3147 .align = __alignof__(u32),
3ac4c07a 3148 },
f25ad2e9
PM
3149 [NFT_SET_EXT_EXPR] = {
3150 .align = __alignof__(struct nft_expr),
3151 },
8aeff920
PNA
3152 [NFT_SET_EXT_OBJREF] = {
3153 .len = sizeof(struct nft_object *),
3154 .align = __alignof__(struct nft_object *),
3155 },
3ac4c07a
PM
3156 [NFT_SET_EXT_FLAGS] = {
3157 .len = sizeof(u8),
3158 .align = __alignof__(u8),
3159 },
c3e1b005
PM
3160 [NFT_SET_EXT_TIMEOUT] = {
3161 .len = sizeof(u64),
3162 .align = __alignof__(u64),
3163 },
3164 [NFT_SET_EXT_EXPIRATION] = {
3165 .len = sizeof(unsigned long),
3166 .align = __alignof__(unsigned long),
3167 },
68e942e8
PM
3168 [NFT_SET_EXT_USERDATA] = {
3169 .len = sizeof(struct nft_userdata),
3170 .align = __alignof__(struct nft_userdata),
3171 },
3ac4c07a
PM
3172};
3173EXPORT_SYMBOL_GPL(nft_set_ext_types);
3174
20a69341
PM
3175/*
3176 * Set elements
3177 */
3178
3179static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
3180 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
3181 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
3182 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
c3e1b005 3183 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
68e942e8
PM
3184 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY,
3185 .len = NFT_USERDATA_MAXLEN },
20a69341
PM
3186};
3187
3188static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
3189 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING },
3190 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING },
3191 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
958bee14 3192 [NFTA_SET_ELEM_LIST_SET_ID] = { .type = NLA_U32 },
20a69341
PM
3193};
3194
633c9a84 3195static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
3196 const struct sk_buff *skb,
3197 const struct nlmsghdr *nlh,
f2a6d766
PNA
3198 const struct nlattr * const nla[],
3199 u8 genmask)
20a69341
PM
3200{
3201 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7c95f6d8
PNA
3202 struct nft_af_info *afi;
3203 struct nft_table *table;
20a69341 3204
99633ab2 3205 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
20a69341
PM
3206 if (IS_ERR(afi))
3207 return PTR_ERR(afi);
3208
f2a6d766
PNA
3209 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE],
3210 genmask);
20a69341
PM
3211 if (IS_ERR(table))
3212 return PTR_ERR(table);
3213
633c9a84 3214 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
20a69341
PM
3215 return 0;
3216}
3217
3218static int nf_tables_fill_setelem(struct sk_buff *skb,
3219 const struct nft_set *set,
3220 const struct nft_set_elem *elem)
3221{
fe2811eb 3222 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3223 unsigned char *b = skb_tail_pointer(skb);
3224 struct nlattr *nest;
3225
3226 nest = nla_nest_start(skb, NFTA_LIST_ELEM);
3227 if (nest == NULL)
3228 goto nla_put_failure;
3229
fe2811eb
PM
3230 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, nft_set_ext_key(ext),
3231 NFT_DATA_VALUE, set->klen) < 0)
20a69341
PM
3232 goto nla_put_failure;
3233
fe2811eb
PM
3234 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3235 nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
20a69341
PM
3236 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
3237 set->dlen) < 0)
3238 goto nla_put_failure;
3239
f25ad2e9
PM
3240 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
3241 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
3242 goto nla_put_failure;
3243
8aeff920
PNA
3244 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3245 nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
3246 (*nft_set_ext_obj(ext))->name) < 0)
3247 goto nla_put_failure;
3248
fe2811eb
PM
3249 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
3250 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
3251 htonl(*nft_set_ext_flags(ext))))
3252 goto nla_put_failure;
20a69341 3253
c3e1b005
PM
3254 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
3255 nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
d3e2a111
AP
3256 cpu_to_be64(jiffies_to_msecs(
3257 *nft_set_ext_timeout(ext))),
b46f6ded 3258 NFTA_SET_ELEM_PAD))
c3e1b005
PM
3259 goto nla_put_failure;
3260
3261 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
3262 unsigned long expires, now = jiffies;
3263
3264 expires = *nft_set_ext_expiration(ext);
3265 if (time_before(now, expires))
3266 expires -= now;
3267 else
3268 expires = 0;
3269
3270 if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
b46f6ded
ND
3271 cpu_to_be64(jiffies_to_msecs(expires)),
3272 NFTA_SET_ELEM_PAD))
c3e1b005
PM
3273 goto nla_put_failure;
3274 }
3275
68e942e8
PM
3276 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
3277 struct nft_userdata *udata;
3278
3279 udata = nft_set_ext_userdata(ext);
3280 if (nla_put(skb, NFTA_SET_ELEM_USERDATA,
3281 udata->len + 1, udata->data))
3282 goto nla_put_failure;
3283 }
3284
20a69341
PM
3285 nla_nest_end(skb, nest);
3286 return 0;
3287
3288nla_put_failure:
3289 nlmsg_trim(skb, b);
3290 return -EMSGSIZE;
3291}
3292
3293struct nft_set_dump_args {
3294 const struct netlink_callback *cb;
3295 struct nft_set_iter iter;
3296 struct sk_buff *skb;
3297};
3298
3299static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
3300 const struct nft_set *set,
3301 const struct nft_set_iter *iter,
3302 const struct nft_set_elem *elem)
3303{
3304 struct nft_set_dump_args *args;
3305
3306 args = container_of(iter, struct nft_set_dump_args, iter);
3307 return nf_tables_fill_setelem(args->skb, set, elem);
3308}
3309
3310static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3311{
633c9a84 3312 struct net *net = sock_net(skb->sk);
f2a6d766 3313 u8 genmask = nft_genmask_cur(net);
20a69341
PM
3314 const struct nft_set *set;
3315 struct nft_set_dump_args args;
3316 struct nft_ctx ctx;
3317 struct nlattr *nla[NFTA_SET_ELEM_LIST_MAX + 1];
3318 struct nfgenmsg *nfmsg;
3319 struct nlmsghdr *nlh;
3320 struct nlattr *nest;
3321 u32 portid, seq;
3322 int event, err;
3323
720e0dfa
MN
3324 err = nlmsg_parse(cb->nlh, sizeof(struct nfgenmsg), nla,
3325 NFTA_SET_ELEM_LIST_MAX, nft_set_elem_list_policy);
20a69341
PM
3326 if (err < 0)
3327 return err;
3328
633c9a84 3329 err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
f2a6d766 3330 (void *)nla, genmask);
20a69341
PM
3331 if (err < 0)
3332 return err;
3333
37a9cc52
PNA
3334 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3335 genmask);
20a69341
PM
3336 if (IS_ERR(set))
3337 return PTR_ERR(set);
3338
3339 event = NFT_MSG_NEWSETELEM;
3340 event |= NFNL_SUBSYS_NFTABLES << 8;
3341 portid = NETLINK_CB(cb->skb).portid;
3342 seq = cb->nlh->nlmsg_seq;
3343
3344 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3345 NLM_F_MULTI);
3346 if (nlh == NULL)
3347 goto nla_put_failure;
3348
3349 nfmsg = nlmsg_data(nlh);
6403d962 3350 nfmsg->nfgen_family = ctx.afi->family;
20a69341 3351 nfmsg->version = NFNETLINK_V0;
84d7fce6 3352 nfmsg->res_id = htons(ctx.net->nft.base_seq & 0xffff);
20a69341
PM
3353
3354 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, ctx.table->name))
3355 goto nla_put_failure;
3356 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
3357 goto nla_put_failure;
3358
3359 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3360 if (nest == NULL)
3361 goto nla_put_failure;
3362
8588ac09
PNA
3363 args.cb = cb;
3364 args.skb = skb;
3365 args.iter.genmask = nft_genmask_cur(ctx.net);
3366 args.iter.skip = cb->args[0];
3367 args.iter.count = 0;
3368 args.iter.err = 0;
3369 args.iter.fn = nf_tables_dump_setelem;
20a69341
PM
3370 set->ops->walk(&ctx, set, &args.iter);
3371
3372 nla_nest_end(skb, nest);
3373 nlmsg_end(skb, nlh);
3374
3375 if (args.iter.err && args.iter.err != -EMSGSIZE)
3376 return args.iter.err;
3377 if (args.iter.count == cb->args[0])
3378 return 0;
3379
3380 cb->args[0] = args.iter.count;
3381 return skb->len;
3382
3383nla_put_failure:
3384 return -ENOSPC;
3385}
3386
7b8002a1
PNA
3387static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
3388 struct sk_buff *skb, const struct nlmsghdr *nlh,
20a69341
PM
3389 const struct nlattr * const nla[])
3390{
f2a6d766 3391 u8 genmask = nft_genmask_cur(net);
20a69341
PM
3392 const struct nft_set *set;
3393 struct nft_ctx ctx;
3394 int err;
3395
f2a6d766 3396 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
3397 if (err < 0)
3398 return err;
3399
37a9cc52
PNA
3400 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3401 genmask);
20a69341
PM
3402 if (IS_ERR(set))
3403 return PTR_ERR(set);
3404
3405 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3406 struct netlink_dump_control c = {
3407 .dump = nf_tables_dump_set,
3408 };
3409 return netlink_dump_start(nlsk, skb, nlh, &c);
3410 }
3411 return -EOPNOTSUPP;
3412}
3413
d60ce62f
AB
3414static int nf_tables_fill_setelem_info(struct sk_buff *skb,
3415 const struct nft_ctx *ctx, u32 seq,
3416 u32 portid, int event, u16 flags,
3417 const struct nft_set *set,
3418 const struct nft_set_elem *elem)
3419{
3420 struct nfgenmsg *nfmsg;
3421 struct nlmsghdr *nlh;
3422 struct nlattr *nest;
3423 int err;
3424
3425 event |= NFNL_SUBSYS_NFTABLES << 8;
3426 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3427 flags);
3428 if (nlh == NULL)
3429 goto nla_put_failure;
3430
3431 nfmsg = nlmsg_data(nlh);
3432 nfmsg->nfgen_family = ctx->afi->family;
3433 nfmsg->version = NFNETLINK_V0;
84d7fce6 3434 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
d60ce62f
AB
3435
3436 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
3437 goto nla_put_failure;
3438 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
3439 goto nla_put_failure;
3440
3441 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3442 if (nest == NULL)
3443 goto nla_put_failure;
3444
3445 err = nf_tables_fill_setelem(skb, set, elem);
3446 if (err < 0)
3447 goto nla_put_failure;
3448
3449 nla_nest_end(skb, nest);
3450
053c095a
JB
3451 nlmsg_end(skb, nlh);
3452 return 0;
d60ce62f
AB
3453
3454nla_put_failure:
3455 nlmsg_trim(skb, nlh);
3456 return -1;
3457}
3458
3459static int nf_tables_setelem_notify(const struct nft_ctx *ctx,
3460 const struct nft_set *set,
3461 const struct nft_set_elem *elem,
3462 int event, u16 flags)
3463{
128ad332
PNA
3464 struct net *net = ctx->net;
3465 u32 portid = ctx->portid;
d60ce62f
AB
3466 struct sk_buff *skb;
3467 int err;
3468
128ad332 3469 if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
d60ce62f
AB
3470 return 0;
3471
3472 err = -ENOBUFS;
3473 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3474 if (skb == NULL)
3475 goto err;
3476
3477 err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
3478 set, elem);
3479 if (err < 0) {
3480 kfree_skb(skb);
3481 goto err;
3482 }
3483
128ad332 3484 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
d60ce62f
AB
3485 GFP_KERNEL);
3486err:
3487 if (err < 0)
3488 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
3489 return err;
3490}
3491
60319eb1
PNA
3492static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3493 int msg_type,
3494 struct nft_set *set)
3495{
3496 struct nft_trans *trans;
3497
3498 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_elem));
3499 if (trans == NULL)
3500 return NULL;
3501
3502 nft_trans_elem_set(trans) = set;
3503 return trans;
3504}
3505
22fe54d5
PM
3506void *nft_set_elem_init(const struct nft_set *set,
3507 const struct nft_set_ext_tmpl *tmpl,
49499c3e 3508 const u32 *key, const u32 *data,
22fe54d5 3509 u64 timeout, gfp_t gfp)
fe2811eb
PM
3510{
3511 struct nft_set_ext *ext;
3512 void *elem;
3513
3514 elem = kzalloc(set->ops->elemsize + tmpl->len, gfp);
3515 if (elem == NULL)
3516 return NULL;
3517
3518 ext = nft_set_elem_ext(set, elem);
3519 nft_set_ext_init(ext, tmpl);
3520
3521 memcpy(nft_set_ext_key(ext), key, set->klen);
3522 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3523 memcpy(nft_set_ext_data(ext), data, set->dlen);
c3e1b005
PM
3524 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
3525 *nft_set_ext_expiration(ext) =
d3e2a111 3526 jiffies + timeout;
c3e1b005
PM
3527 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
3528 *nft_set_ext_timeout(ext) = timeout;
fe2811eb
PM
3529
3530 return elem;
3531}
3532
61f9e292
LZ
3533void nft_set_elem_destroy(const struct nft_set *set, void *elem,
3534 bool destroy_expr)
61edafbb
PM
3535{
3536 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3537
3538 nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
3539 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3540 nft_data_uninit(nft_set_ext_data(ext), set->dtype);
61f9e292 3541 if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
f25ad2e9 3542 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
8aeff920
PNA
3543 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
3544 (*nft_set_ext_obj(ext))->use--;
61edafbb
PM
3545 kfree(elem);
3546}
3547EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
3548
0e9091d6
PNA
3549static int nft_setelem_parse_flags(const struct nft_set *set,
3550 const struct nlattr *attr, u32 *flags)
3551{
3552 if (attr == NULL)
3553 return 0;
3554
3555 *flags = ntohl(nla_get_be32(attr));
3556 if (*flags & ~NFT_SET_ELEM_INTERVAL_END)
3557 return -EINVAL;
3558 if (!(set->flags & NFT_SET_INTERVAL) &&
3559 *flags & NFT_SET_ELEM_INTERVAL_END)
3560 return -EINVAL;
3561
3562 return 0;
3563}
3564
60319eb1 3565static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
c016c7e4 3566 const struct nlattr *attr, u32 nlmsg_flags)
20a69341
PM
3567{
3568 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
8aeff920 3569 u8 genmask = nft_genmask_next(ctx->net);
20a69341 3570 struct nft_data_desc d1, d2;
fe2811eb 3571 struct nft_set_ext_tmpl tmpl;
c016c7e4 3572 struct nft_set_ext *ext, *ext2;
20a69341
PM
3573 struct nft_set_elem elem;
3574 struct nft_set_binding *binding;
8aeff920 3575 struct nft_object *obj = NULL;
68e942e8 3576 struct nft_userdata *udata;
fe2811eb 3577 struct nft_data data;
20a69341 3578 enum nft_registers dreg;
60319eb1 3579 struct nft_trans *trans;
0e9091d6 3580 u32 flags = 0;
c3e1b005 3581 u64 timeout;
68e942e8 3582 u8 ulen;
20a69341
PM
3583 int err;
3584
3585 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
3586 nft_set_elem_policy);
3587 if (err < 0)
3588 return err;
3589
3590 if (nla[NFTA_SET_ELEM_KEY] == NULL)
3591 return -EINVAL;
3592
fe2811eb
PM
3593 nft_set_ext_prepare(&tmpl);
3594
0e9091d6
PNA
3595 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
3596 if (err < 0)
3597 return err;
3598 if (flags != 0)
3599 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
20a69341
PM
3600
3601 if (set->flags & NFT_SET_MAP) {
3602 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
fe2811eb 3603 !(flags & NFT_SET_ELEM_INTERVAL_END))
20a69341 3604 return -EINVAL;
bd7fc645 3605 if (nla[NFTA_SET_ELEM_DATA] != NULL &&
fe2811eb 3606 flags & NFT_SET_ELEM_INTERVAL_END)
bd7fc645 3607 return -EINVAL;
20a69341
PM
3608 } else {
3609 if (nla[NFTA_SET_ELEM_DATA] != NULL)
3610 return -EINVAL;
3611 }
3612
c3e1b005
PM
3613 timeout = 0;
3614 if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
3615 if (!(set->flags & NFT_SET_TIMEOUT))
3616 return -EINVAL;
d3e2a111
AP
3617 timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
3618 nla[NFTA_SET_ELEM_TIMEOUT])));
c3e1b005
PM
3619 } else if (set->flags & NFT_SET_TIMEOUT) {
3620 timeout = set->timeout;
3621 }
3622
7d740264 3623 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
d0a11fc3 3624 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
3625 if (err < 0)
3626 goto err1;
3627 err = -EINVAL;
3628 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
3629 goto err2;
3630
7d740264 3631 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
c3e1b005
PM
3632 if (timeout > 0) {
3633 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
3634 if (timeout != set->timeout)
3635 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
3636 }
fe2811eb 3637
8aeff920
PNA
3638 if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
3639 if (!(set->flags & NFT_SET_OBJECT)) {
3640 err = -EINVAL;
3641 goto err2;
3642 }
3643 obj = nf_tables_obj_lookup(ctx->table, nla[NFTA_SET_ELEM_OBJREF],
3644 set->objtype, genmask);
3645 if (IS_ERR(obj)) {
3646 err = PTR_ERR(obj);
3647 goto err2;
3648 }
3649 nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
3650 }
3651
20a69341 3652 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
d0a11fc3
PM
3653 err = nft_data_init(ctx, &data, sizeof(data), &d2,
3654 nla[NFTA_SET_ELEM_DATA]);
20a69341
PM
3655 if (err < 0)
3656 goto err2;
3657
3658 err = -EINVAL;
3659 if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
3660 goto err3;
3661
3662 dreg = nft_type_to_reg(set->dtype);
3663 list_for_each_entry(binding, &set->bindings, list) {
3664 struct nft_ctx bind_ctx = {
58c78e10 3665 .net = ctx->net,
20a69341
PM
3666 .afi = ctx->afi,
3667 .table = ctx->table,
7c95f6d8 3668 .chain = (struct nft_chain *)binding->chain,
20a69341
PM
3669 };
3670
11113e19
PM
3671 if (!(binding->flags & NFT_SET_MAP))
3672 continue;
3673
1ec10212
PM
3674 err = nft_validate_register_store(&bind_ctx, dreg,
3675 &data,
3676 d2.type, d2.len);
20a69341
PM
3677 if (err < 0)
3678 goto err3;
3679 }
fe2811eb 3680
7d740264 3681 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
20a69341
PM
3682 }
3683
68e942e8
PM
3684 /* The full maximum length of userdata can exceed the maximum
3685 * offset value (U8_MAX) for following extensions, therefor it
3686 * must be the last extension added.
3687 */
3688 ulen = 0;
3689 if (nla[NFTA_SET_ELEM_USERDATA] != NULL) {
3690 ulen = nla_len(nla[NFTA_SET_ELEM_USERDATA]);
3691 if (ulen > 0)
3692 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_USERDATA,
3693 ulen);
3694 }
3695
fe2811eb 3696 err = -ENOMEM;
7d740264 3697 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
c3e1b005 3698 timeout, GFP_KERNEL);
fe2811eb
PM
3699 if (elem.priv == NULL)
3700 goto err3;
3701
3702 ext = nft_set_elem_ext(set, elem.priv);
3703 if (flags)
3704 *nft_set_ext_flags(ext) = flags;
68e942e8
PM
3705 if (ulen > 0) {
3706 udata = nft_set_ext_userdata(ext);
3707 udata->len = ulen - 1;
3708 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
3709 }
8aeff920
PNA
3710 if (obj) {
3711 *nft_set_ext_obj(ext) = obj;
3712 obj->use++;
3713 }
fe2811eb 3714
60319eb1
PNA
3715 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
3716 if (trans == NULL)
fe2811eb 3717 goto err4;
60319eb1 3718
69086658 3719 ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
c016c7e4
PNA
3720 err = set->ops->insert(ctx->net, set, &elem, &ext2);
3721 if (err) {
3722 if (err == -EEXIST) {
8aeff920
PNA
3723 if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3724 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
3725 memcmp(nft_set_ext_data(ext),
3726 nft_set_ext_data(ext2), set->dlen) != 0) ||
3727 (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3728 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
3729 *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
c016c7e4
PNA
3730 err = -EBUSY;
3731 else if (!(nlmsg_flags & NLM_F_EXCL))
3732 err = 0;
3733 }
fe2811eb 3734 goto err5;
c016c7e4 3735 }
20a69341 3736
60319eb1 3737 nft_trans_elem(trans) = elem;
46bbafce 3738 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
20a69341
PM
3739 return 0;
3740
fe2811eb 3741err5:
60319eb1 3742 kfree(trans);
fe2811eb
PM
3743err4:
3744 kfree(elem.priv);
20a69341
PM
3745err3:
3746 if (nla[NFTA_SET_ELEM_DATA] != NULL)
fe2811eb 3747 nft_data_uninit(&data, d2.type);
20a69341 3748err2:
7d740264 3749 nft_data_uninit(&elem.key.val, d1.type);
20a69341
PM
3750err1:
3751 return err;
3752}
3753
633c9a84
PNA
3754static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
3755 struct sk_buff *skb, const struct nlmsghdr *nlh,
20a69341
PM
3756 const struct nlattr * const nla[])
3757{
f2a6d766 3758 u8 genmask = nft_genmask_next(net);
20a69341
PM
3759 const struct nlattr *attr;
3760 struct nft_set *set;
3761 struct nft_ctx ctx;
60319eb1 3762 int rem, err = 0;
20a69341 3763
7d5570ca
PNA
3764 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3765 return -EINVAL;
3766
f2a6d766 3767 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
3768 if (err < 0)
3769 return err;
3770
37a9cc52
PNA
3771 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3772 genmask);
958bee14
PNA
3773 if (IS_ERR(set)) {
3774 if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
3775 set = nf_tables_set_lookup_byid(net,
37a9cc52
PNA
3776 nla[NFTA_SET_ELEM_LIST_SET_ID],
3777 genmask);
958bee14
PNA
3778 }
3779 if (IS_ERR(set))
3780 return PTR_ERR(set);
3781 }
3782
20a69341
PM
3783 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
3784 return -EBUSY;
3785
3786 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3dd0673a
PM
3787 if (set->size &&
3788 !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact))
3789 return -ENFILE;
3790
c016c7e4 3791 err = nft_add_set_elem(&ctx, set, attr, nlh->nlmsg_flags);
3dd0673a
PM
3792 if (err < 0) {
3793 atomic_dec(&set->nelems);
60319eb1 3794 break;
3dd0673a 3795 }
20a69341 3796 }
60319eb1 3797 return err;
20a69341
PM
3798}
3799
60319eb1 3800static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
20a69341
PM
3801 const struct nlattr *attr)
3802{
3803 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3971ca14 3804 struct nft_set_ext_tmpl tmpl;
20a69341
PM
3805 struct nft_data_desc desc;
3806 struct nft_set_elem elem;
3971ca14 3807 struct nft_set_ext *ext;
60319eb1 3808 struct nft_trans *trans;
3971ca14
PNA
3809 u32 flags = 0;
3810 void *priv;
20a69341
PM
3811 int err;
3812
3813 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
3814 nft_set_elem_policy);
3815 if (err < 0)
3816 goto err1;
3817
3818 err = -EINVAL;
3819 if (nla[NFTA_SET_ELEM_KEY] == NULL)
3820 goto err1;
3821
3971ca14
PNA
3822 nft_set_ext_prepare(&tmpl);
3823
3824 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
3825 if (err < 0)
3826 return err;
3827 if (flags != 0)
3828 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
3829
7d740264 3830 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
d0a11fc3 3831 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
3832 if (err < 0)
3833 goto err1;
3834
3835 err = -EINVAL;
3836 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
3837 goto err2;
3838
3971ca14
PNA
3839 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
3840
3841 err = -ENOMEM;
3842 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
3843 GFP_KERNEL);
3844 if (elem.priv == NULL)
3845 goto err2;
3846
3847 ext = nft_set_elem_ext(set, elem.priv);
3848 if (flags)
3849 *nft_set_ext_flags(ext) = flags;
3850
60319eb1 3851 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
609ccf08
JL
3852 if (trans == NULL) {
3853 err = -ENOMEM;
3971ca14 3854 goto err3;
609ccf08 3855 }
20a69341 3856
42a55769 3857 priv = set->ops->deactivate(ctx->net, set, &elem);
3971ca14 3858 if (priv == NULL) {
cc02e457 3859 err = -ENOENT;
3971ca14 3860 goto err4;
cc02e457 3861 }
3971ca14
PNA
3862 kfree(elem.priv);
3863 elem.priv = priv;
cc02e457 3864
60319eb1 3865 nft_trans_elem(trans) = elem;
46bbafce 3866 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
0dc13625 3867 return 0;
cc02e457 3868
3971ca14 3869err4:
cc02e457 3870 kfree(trans);
3971ca14
PNA
3871err3:
3872 kfree(elem.priv);
20a69341 3873err2:
7d740264 3874 nft_data_uninit(&elem.key.val, desc.type);
20a69341
PM
3875err1:
3876 return err;
3877}
3878
633c9a84
PNA
3879static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
3880 struct sk_buff *skb, const struct nlmsghdr *nlh,
20a69341
PM
3881 const struct nlattr * const nla[])
3882{
f2a6d766 3883 u8 genmask = nft_genmask_next(net);
20a69341
PM
3884 const struct nlattr *attr;
3885 struct nft_set *set;
3886 struct nft_ctx ctx;
60319eb1 3887 int rem, err = 0;
20a69341 3888
7d5570ca
PNA
3889 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3890 return -EINVAL;
3891
f2a6d766 3892 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
3893 if (err < 0)
3894 return err;
3895
37a9cc52
PNA
3896 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3897 genmask);
20a69341
PM
3898 if (IS_ERR(set))
3899 return PTR_ERR(set);
3900 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
3901 return -EBUSY;
3902
3903 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3904 err = nft_del_setelem(&ctx, set, attr);
3905 if (err < 0)
60319eb1 3906 break;
4fefee57 3907
3dd0673a 3908 set->ndeact++;
20a69341 3909 }
60319eb1 3910 return err;
20a69341
PM
3911}
3912
cfed7e1b
PM
3913void nft_set_gc_batch_release(struct rcu_head *rcu)
3914{
3915 struct nft_set_gc_batch *gcb;
3916 unsigned int i;
3917
3918 gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
3919 for (i = 0; i < gcb->head.cnt; i++)
61f9e292 3920 nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
cfed7e1b
PM
3921 kfree(gcb);
3922}
3923EXPORT_SYMBOL_GPL(nft_set_gc_batch_release);
3924
3925struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
3926 gfp_t gfp)
3927{
3928 struct nft_set_gc_batch *gcb;
3929
3930 gcb = kzalloc(sizeof(*gcb), gfp);
3931 if (gcb == NULL)
3932 return gcb;
3933 gcb->head.set = set;
3934 return gcb;
3935}
3936EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
3937
e5009240
PNA
3938/*
3939 * Stateful objects
3940 */
3941
3942/**
3943 * nft_register_obj- register nf_tables stateful object type
3944 * @obj: object type
3945 *
3946 * Registers the object type for use with nf_tables. Returns zero on
3947 * success or a negative errno code otherwise.
3948 */
3949int nft_register_obj(struct nft_object_type *obj_type)
3950{
3951 if (obj_type->type == NFT_OBJECT_UNSPEC)
3952 return -EINVAL;
3953
3954 nfnl_lock(NFNL_SUBSYS_NFTABLES);
3955 list_add_rcu(&obj_type->list, &nf_tables_objects);
3956 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
3957 return 0;
3958}
3959EXPORT_SYMBOL_GPL(nft_register_obj);
3960
3961/**
3962 * nft_unregister_obj - unregister nf_tables object type
3963 * @obj: object type
3964 *
3965 * Unregisters the object type for use with nf_tables.
3966 */
3967void nft_unregister_obj(struct nft_object_type *obj_type)
3968{
3969 nfnl_lock(NFNL_SUBSYS_NFTABLES);
3970 list_del_rcu(&obj_type->list);
3971 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
3972}
3973EXPORT_SYMBOL_GPL(nft_unregister_obj);
3974
3975struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
3976 const struct nlattr *nla,
3977 u32 objtype, u8 genmask)
3978{
3979 struct nft_object *obj;
3980
3981 list_for_each_entry(obj, &table->objects, list) {
3982 if (!nla_strcmp(nla, obj->name) &&
3983 objtype == obj->type->type &&
3984 nft_active_genmask(obj, genmask))
3985 return obj;
3986 }
3987 return ERR_PTR(-ENOENT);
3988}
3989EXPORT_SYMBOL_GPL(nf_tables_obj_lookup);
3990
3991static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
3992 [NFTA_OBJ_TABLE] = { .type = NLA_STRING },
3993 [NFTA_OBJ_NAME] = { .type = NLA_STRING },
3994 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
3995 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
3996};
3997
3998static struct nft_object *nft_obj_init(const struct nft_object_type *type,
3999 const struct nlattr *attr)
4000{
4001 struct nlattr *tb[type->maxattr + 1];
4002 struct nft_object *obj;
4003 int err;
4004
4005 if (attr) {
4006 err = nla_parse_nested(tb, type->maxattr, attr, type->policy);
4007 if (err < 0)
4008 goto err1;
4009 } else {
4010 memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));
4011 }
4012
4013 err = -ENOMEM;
4014 obj = kzalloc(sizeof(struct nft_object) + type->size, GFP_KERNEL);
4015 if (obj == NULL)
4016 goto err1;
4017
4018 err = type->init((const struct nlattr * const *)tb, obj);
4019 if (err < 0)
4020 goto err2;
4021
4022 obj->type = type;
4023 return obj;
4024err2:
4025 kfree(obj);
4026err1:
4027 return ERR_PTR(err);
4028}
4029
4030static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
43da04a5 4031 struct nft_object *obj, bool reset)
e5009240
PNA
4032{
4033 struct nlattr *nest;
4034
4035 nest = nla_nest_start(skb, attr);
4036 if (!nest)
4037 goto nla_put_failure;
43da04a5 4038 if (obj->type->dump(skb, obj, reset) < 0)
e5009240
PNA
4039 goto nla_put_failure;
4040 nla_nest_end(skb, nest);
4041 return 0;
4042
4043nla_put_failure:
4044 return -1;
4045}
4046
4047static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
4048{
4049 const struct nft_object_type *type;
4050
4051 list_for_each_entry(type, &nf_tables_objects, list) {
4052 if (objtype == type->type)
4053 return type;
4054 }
4055 return NULL;
4056}
4057
4058static const struct nft_object_type *nft_obj_type_get(u32 objtype)
4059{
4060 const struct nft_object_type *type;
4061
4062 type = __nft_obj_type_get(objtype);
4063 if (type != NULL && try_module_get(type->owner))
4064 return type;
4065
4066#ifdef CONFIG_MODULES
4067 if (type == NULL) {
4068 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4069 request_module("nft-obj-%u", objtype);
4070 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4071 if (__nft_obj_type_get(objtype))
4072 return ERR_PTR(-EAGAIN);
4073 }
4074#endif
4075 return ERR_PTR(-ENOENT);
4076}
4077
4078static int nf_tables_newobj(struct net *net, struct sock *nlsk,
4079 struct sk_buff *skb, const struct nlmsghdr *nlh,
4080 const struct nlattr * const nla[])
4081{
4082 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4083 const struct nft_object_type *type;
4084 u8 genmask = nft_genmask_next(net);
4085 int family = nfmsg->nfgen_family;
4086 struct nft_af_info *afi;
4087 struct nft_table *table;
4088 struct nft_object *obj;
4089 struct nft_ctx ctx;
4090 u32 objtype;
4091 int err;
4092
4093 if (!nla[NFTA_OBJ_TYPE] ||
4094 !nla[NFTA_OBJ_NAME] ||
4095 !nla[NFTA_OBJ_DATA])
4096 return -EINVAL;
4097
4098 afi = nf_tables_afinfo_lookup(net, family, true);
4099 if (IS_ERR(afi))
4100 return PTR_ERR(afi);
4101
4102 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4103 if (IS_ERR(table))
4104 return PTR_ERR(table);
4105
4106 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4107 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4108 if (IS_ERR(obj)) {
4109 err = PTR_ERR(obj);
4110 if (err != -ENOENT)
4111 return err;
4112
4113 obj = NULL;
4114 }
4115
4116 if (obj != NULL) {
4117 if (nlh->nlmsg_flags & NLM_F_EXCL)
4118 return -EEXIST;
4119
4120 return 0;
4121 }
4122
4123 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4124
4125 type = nft_obj_type_get(objtype);
4126 if (IS_ERR(type))
4127 return PTR_ERR(type);
4128
4129 obj = nft_obj_init(type, nla[NFTA_OBJ_DATA]);
4130 if (IS_ERR(obj)) {
4131 err = PTR_ERR(obj);
4132 goto err1;
4133 }
18965317 4134 obj->table = table;
e5009240
PNA
4135 nla_strlcpy(obj->name, nla[NFTA_OBJ_NAME], NFT_OBJ_MAXNAMELEN);
4136
4137 err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj);
4138 if (err < 0)
4139 goto err2;
4140
4141 list_add_tail_rcu(&obj->list, &table->objects);
4142 table->use++;
4143 return 0;
4144err2:
4145 if (obj->type->destroy)
4146 obj->type->destroy(obj);
4147 kfree(obj);
4148err1:
4149 module_put(type->owner);
4150 return err;
4151}
4152
4153static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
4154 u32 portid, u32 seq, int event, u32 flags,
4155 int family, const struct nft_table *table,
43da04a5 4156 struct nft_object *obj, bool reset)
e5009240
PNA
4157{
4158 struct nfgenmsg *nfmsg;
4159 struct nlmsghdr *nlh;
4160
4161 event |= NFNL_SUBSYS_NFTABLES << 8;
4162 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
4163 if (nlh == NULL)
4164 goto nla_put_failure;
4165
4166 nfmsg = nlmsg_data(nlh);
4167 nfmsg->nfgen_family = family;
4168 nfmsg->version = NFNETLINK_V0;
4169 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4170
4171 if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
4172 nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
4173 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->type->type)) ||
4174 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
43da04a5 4175 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
e5009240
PNA
4176 goto nla_put_failure;
4177
4178 nlmsg_end(skb, nlh);
4179 return 0;
4180
4181nla_put_failure:
4182 nlmsg_trim(skb, nlh);
4183 return -1;
4184}
4185
4186static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
4187{
4188 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
4189 const struct nft_af_info *afi;
4190 const struct nft_table *table;
e5009240
PNA
4191 unsigned int idx = 0, s_idx = cb->args[0];
4192 struct net *net = sock_net(skb->sk);
4193 int family = nfmsg->nfgen_family;
43da04a5
PNA
4194 struct nft_object *obj;
4195 bool reset = false;
4196
4197 if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4198 reset = true;
e5009240
PNA
4199
4200 rcu_read_lock();
4201 cb->seq = net->nft.base_seq;
4202
4203 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
4204 if (family != NFPROTO_UNSPEC && family != afi->family)
4205 continue;
4206
4207 list_for_each_entry_rcu(table, &afi->tables, list) {
4208 list_for_each_entry_rcu(obj, &table->objects, list) {
4209 if (!nft_is_active(net, obj))
4210 goto cont;
4211 if (idx < s_idx)
4212 goto cont;
4213 if (idx > s_idx)
4214 memset(&cb->args[1], 0,
4215 sizeof(cb->args) - sizeof(cb->args[0]));
4216 if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
4217 cb->nlh->nlmsg_seq,
4218 NFT_MSG_NEWOBJ,
4219 NLM_F_MULTI | NLM_F_APPEND,
43da04a5 4220 afi->family, table, obj, reset) < 0)
e5009240
PNA
4221 goto done;
4222
4223 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4224cont:
4225 idx++;
4226 }
4227 }
4228 }
4229done:
4230 rcu_read_unlock();
4231
4232 cb->args[0] = idx;
4233 return skb->len;
4234}
4235
4236static int nf_tables_getobj(struct net *net, struct sock *nlsk,
4237 struct sk_buff *skb, const struct nlmsghdr *nlh,
4238 const struct nlattr * const nla[])
4239{
4240 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4241 u8 genmask = nft_genmask_cur(net);
4242 int family = nfmsg->nfgen_family;
4243 const struct nft_af_info *afi;
4244 const struct nft_table *table;
4245 struct nft_object *obj;
4246 struct sk_buff *skb2;
43da04a5 4247 bool reset = false;
e5009240
PNA
4248 u32 objtype;
4249 int err;
4250
4251 if (nlh->nlmsg_flags & NLM_F_DUMP) {
4252 struct netlink_dump_control c = {
4253 .dump = nf_tables_dump_obj,
4254 };
4255 return netlink_dump_start(nlsk, skb, nlh, &c);
4256 }
4257
4258 if (!nla[NFTA_OBJ_NAME] ||
4259 !nla[NFTA_OBJ_TYPE])
4260 return -EINVAL;
4261
4262 afi = nf_tables_afinfo_lookup(net, family, false);
4263 if (IS_ERR(afi))
4264 return PTR_ERR(afi);
4265
4266 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4267 if (IS_ERR(table))
4268 return PTR_ERR(table);
4269
4270 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4271 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4272 if (IS_ERR(obj))
4273 return PTR_ERR(obj);
4274
4275 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
4276 if (!skb2)
4277 return -ENOMEM;
4278
43da04a5
PNA
4279 if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4280 reset = true;
4281
e5009240
PNA
4282 err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
4283 nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
43da04a5 4284 family, table, obj, reset);
e5009240
PNA
4285 if (err < 0)
4286 goto err;
4287
4288 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4289err:
4290 kfree_skb(skb2);
4291 return err;
4292
4293 return 0;
4294}
4295
4296static void nft_obj_destroy(struct nft_object *obj)
4297{
4298 if (obj->type->destroy)
4299 obj->type->destroy(obj);
4300
4301 module_put(obj->type->owner);
4302 kfree(obj);
4303}
4304
4305static int nf_tables_delobj(struct net *net, struct sock *nlsk,
4306 struct sk_buff *skb, const struct nlmsghdr *nlh,
4307 const struct nlattr * const nla[])
4308{
4309 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4310 u8 genmask = nft_genmask_next(net);
4311 int family = nfmsg->nfgen_family;
4312 struct nft_af_info *afi;
4313 struct nft_table *table;
4314 struct nft_object *obj;
4315 struct nft_ctx ctx;
4316 u32 objtype;
4317
4318 if (!nla[NFTA_OBJ_TYPE] ||
4319 !nla[NFTA_OBJ_NAME])
4320 return -EINVAL;
4321
4322 afi = nf_tables_afinfo_lookup(net, family, true);
4323 if (IS_ERR(afi))
4324 return PTR_ERR(afi);
4325
4326 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4327 if (IS_ERR(table))
4328 return PTR_ERR(table);
4329
4330 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4331 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4332 if (IS_ERR(obj))
4333 return PTR_ERR(obj);
4334 if (obj->use > 0)
4335 return -EBUSY;
4336
4337 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4338
4339 return nft_delobj(&ctx, obj);
4340}
4341
2599e989
PNA
4342int nft_obj_notify(struct net *net, struct nft_table *table,
4343 struct nft_object *obj, u32 portid, u32 seq, int event,
4344 int family, int report, gfp_t gfp)
e5009240
PNA
4345{
4346 struct sk_buff *skb;
4347 int err;
4348
2599e989
PNA
4349 if (!report &&
4350 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
e5009240
PNA
4351 return 0;
4352
4353 err = -ENOBUFS;
2599e989 4354 skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
e5009240
PNA
4355 if (skb == NULL)
4356 goto err;
4357
2599e989
PNA
4358 err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
4359 table, obj, false);
e5009240
PNA
4360 if (err < 0) {
4361 kfree_skb(skb);
4362 goto err;
4363 }
4364
2599e989 4365 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
e5009240
PNA
4366err:
4367 if (err < 0) {
2599e989 4368 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
e5009240
PNA
4369 }
4370 return err;
4371}
2599e989
PNA
4372EXPORT_SYMBOL_GPL(nft_obj_notify);
4373
4374static int nf_tables_obj_notify(const struct nft_ctx *ctx,
4375 struct nft_object *obj, int event)
4376{
4377 return nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid,
4378 ctx->seq, event, ctx->afi->family, ctx->report,
4379 GFP_KERNEL);
4380}
e5009240 4381
84d7fce6
PNA
4382static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
4383 u32 portid, u32 seq)
4384{
4385 struct nlmsghdr *nlh;
4386 struct nfgenmsg *nfmsg;
4387 int event = (NFNL_SUBSYS_NFTABLES << 8) | NFT_MSG_NEWGEN;
4388
4389 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0);
4390 if (nlh == NULL)
4391 goto nla_put_failure;
4392
4393 nfmsg = nlmsg_data(nlh);
4394 nfmsg->nfgen_family = AF_UNSPEC;
4395 nfmsg->version = NFNETLINK_V0;
4396 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4397
4398 if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)))
4399 goto nla_put_failure;
4400
053c095a
JB
4401 nlmsg_end(skb, nlh);
4402 return 0;
84d7fce6
PNA
4403
4404nla_put_failure:
4405 nlmsg_trim(skb, nlh);
4406 return -EMSGSIZE;
4407}
4408
4409static int nf_tables_gen_notify(struct net *net, struct sk_buff *skb, int event)
4410{
4411 struct nlmsghdr *nlh = nlmsg_hdr(skb);
4412 struct sk_buff *skb2;
4413 int err;
4414
4415 if (nlmsg_report(nlh) &&
4416 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
4417 return 0;
4418
4419 err = -ENOBUFS;
4420 skb2 = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
4421 if (skb2 == NULL)
4422 goto err;
4423
4424 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
4425 nlh->nlmsg_seq);
4426 if (err < 0) {
4427 kfree_skb(skb2);
4428 goto err;
4429 }
4430
4431 err = nfnetlink_send(skb2, net, NETLINK_CB(skb).portid,
4432 NFNLGRP_NFTABLES, nlmsg_report(nlh), GFP_KERNEL);
4433err:
4434 if (err < 0) {
4435 nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4436 err);
4437 }
4438 return err;
4439}
4440
7b8002a1
PNA
4441static int nf_tables_getgen(struct net *net, struct sock *nlsk,
4442 struct sk_buff *skb, const struct nlmsghdr *nlh,
84d7fce6
PNA
4443 const struct nlattr * const nla[])
4444{
84d7fce6
PNA
4445 struct sk_buff *skb2;
4446 int err;
4447
4448 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
4449 if (skb2 == NULL)
4450 return -ENOMEM;
4451
4452 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
4453 nlh->nlmsg_seq);
4454 if (err < 0)
4455 goto err;
4456
4457 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4458err:
4459 kfree_skb(skb2);
4460 return err;
4461}
4462
96518518
PM
4463static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
4464 [NFT_MSG_NEWTABLE] = {
55dd6f93 4465 .call_batch = nf_tables_newtable,
96518518
PM
4466 .attr_count = NFTA_TABLE_MAX,
4467 .policy = nft_table_policy,
4468 },
4469 [NFT_MSG_GETTABLE] = {
4470 .call = nf_tables_gettable,
4471 .attr_count = NFTA_TABLE_MAX,
4472 .policy = nft_table_policy,
4473 },
4474 [NFT_MSG_DELTABLE] = {
55dd6f93 4475 .call_batch = nf_tables_deltable,
96518518
PM
4476 .attr_count = NFTA_TABLE_MAX,
4477 .policy = nft_table_policy,
4478 },
4479 [NFT_MSG_NEWCHAIN] = {
91c7b38d 4480 .call_batch = nf_tables_newchain,
96518518
PM
4481 .attr_count = NFTA_CHAIN_MAX,
4482 .policy = nft_chain_policy,
4483 },
4484 [NFT_MSG_GETCHAIN] = {
4485 .call = nf_tables_getchain,
4486 .attr_count = NFTA_CHAIN_MAX,
4487 .policy = nft_chain_policy,
4488 },
4489 [NFT_MSG_DELCHAIN] = {
91c7b38d 4490 .call_batch = nf_tables_delchain,
96518518
PM
4491 .attr_count = NFTA_CHAIN_MAX,
4492 .policy = nft_chain_policy,
4493 },
4494 [NFT_MSG_NEWRULE] = {
0628b123 4495 .call_batch = nf_tables_newrule,
96518518
PM
4496 .attr_count = NFTA_RULE_MAX,
4497 .policy = nft_rule_policy,
4498 },
4499 [NFT_MSG_GETRULE] = {
4500 .call = nf_tables_getrule,
4501 .attr_count = NFTA_RULE_MAX,
4502 .policy = nft_rule_policy,
4503 },
4504 [NFT_MSG_DELRULE] = {
0628b123 4505 .call_batch = nf_tables_delrule,
96518518
PM
4506 .attr_count = NFTA_RULE_MAX,
4507 .policy = nft_rule_policy,
4508 },
20a69341 4509 [NFT_MSG_NEWSET] = {
958bee14 4510 .call_batch = nf_tables_newset,
20a69341
PM
4511 .attr_count = NFTA_SET_MAX,
4512 .policy = nft_set_policy,
4513 },
4514 [NFT_MSG_GETSET] = {
4515 .call = nf_tables_getset,
4516 .attr_count = NFTA_SET_MAX,
4517 .policy = nft_set_policy,
4518 },
4519 [NFT_MSG_DELSET] = {
958bee14 4520 .call_batch = nf_tables_delset,
20a69341
PM
4521 .attr_count = NFTA_SET_MAX,
4522 .policy = nft_set_policy,
4523 },
4524 [NFT_MSG_NEWSETELEM] = {
958bee14 4525 .call_batch = nf_tables_newsetelem,
20a69341
PM
4526 .attr_count = NFTA_SET_ELEM_LIST_MAX,
4527 .policy = nft_set_elem_list_policy,
4528 },
4529 [NFT_MSG_GETSETELEM] = {
4530 .call = nf_tables_getsetelem,
4531 .attr_count = NFTA_SET_ELEM_LIST_MAX,
4532 .policy = nft_set_elem_list_policy,
4533 },
4534 [NFT_MSG_DELSETELEM] = {
958bee14 4535 .call_batch = nf_tables_delsetelem,
20a69341
PM
4536 .attr_count = NFTA_SET_ELEM_LIST_MAX,
4537 .policy = nft_set_elem_list_policy,
4538 },
84d7fce6
PNA
4539 [NFT_MSG_GETGEN] = {
4540 .call = nf_tables_getgen,
4541 },
e5009240
PNA
4542 [NFT_MSG_NEWOBJ] = {
4543 .call_batch = nf_tables_newobj,
4544 .attr_count = NFTA_OBJ_MAX,
4545 .policy = nft_obj_policy,
4546 },
4547 [NFT_MSG_GETOBJ] = {
4548 .call = nf_tables_getobj,
4549 .attr_count = NFTA_OBJ_MAX,
4550 .policy = nft_obj_policy,
4551 },
4552 [NFT_MSG_DELOBJ] = {
4553 .call_batch = nf_tables_delobj,
4554 .attr_count = NFTA_OBJ_MAX,
4555 .policy = nft_obj_policy,
4556 },
43da04a5
PNA
4557 [NFT_MSG_GETOBJ_RESET] = {
4558 .call = nf_tables_getobj,
4559 .attr_count = NFTA_OBJ_MAX,
4560 .policy = nft_obj_policy,
4561 },
96518518
PM
4562};
4563
91c7b38d
PNA
4564static void nft_chain_commit_update(struct nft_trans *trans)
4565{
4566 struct nft_base_chain *basechain;
4567
4568 if (nft_trans_chain_name(trans)[0])
4569 strcpy(trans->ctx.chain->name, nft_trans_chain_name(trans));
4570
4571 if (!(trans->ctx.chain->flags & NFT_BASE_CHAIN))
4572 return;
4573
4574 basechain = nft_base_chain(trans->ctx.chain);
4575 nft_chain_stats_replace(basechain, nft_trans_chain_stats(trans));
4576
4577 switch (nft_trans_chain_policy(trans)) {
4578 case NF_DROP:
4579 case NF_ACCEPT:
4580 basechain->policy = nft_trans_chain_policy(trans);
4581 break;
4582 }
4583}
4584
b326dd37 4585static void nf_tables_commit_release(struct nft_trans *trans)
c7c32e72 4586{
c7c32e72
PNA
4587 switch (trans->msg_type) {
4588 case NFT_MSG_DELTABLE:
4589 nf_tables_table_destroy(&trans->ctx);
4590 break;
4591 case NFT_MSG_DELCHAIN:
4592 nf_tables_chain_destroy(trans->ctx.chain);
4593 break;
4594 case NFT_MSG_DELRULE:
4595 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
4596 break;
4597 case NFT_MSG_DELSET:
4598 nft_set_destroy(nft_trans_set(trans));
4599 break;
61edafbb
PM
4600 case NFT_MSG_DELSETELEM:
4601 nft_set_elem_destroy(nft_trans_elem_set(trans),
61f9e292 4602 nft_trans_elem(trans).priv, true);
61edafbb 4603 break;
e5009240
PNA
4604 case NFT_MSG_DELOBJ:
4605 nft_obj_destroy(nft_trans_obj(trans));
4606 break;
c7c32e72
PNA
4607 }
4608 kfree(trans);
4609}
4610
5913beaf 4611static int nf_tables_commit(struct net *net, struct sk_buff *skb)
37082f93 4612{
37082f93 4613 struct nft_trans *trans, *next;
a3716e70 4614 struct nft_trans_elem *te;
37082f93
PNA
4615
4616 /* Bump generation counter, invalidate any dump in progress */
38e029f1 4617 while (++net->nft.base_seq == 0);
37082f93
PNA
4618
4619 /* A new generation has just started */
ea4bd995 4620 net->nft.gencursor = nft_gencursor_next(net);
37082f93
PNA
4621
4622 /* Make sure all packets have left the previous generation before
4623 * purging old rules.
4624 */
4625 synchronize_rcu();
4626
4627 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
b380e5c7 4628 switch (trans->msg_type) {
55dd6f93
PNA
4629 case NFT_MSG_NEWTABLE:
4630 if (nft_trans_table_update(trans)) {
4631 if (!nft_trans_table_enable(trans)) {
664b0f8c
PNA
4632 nf_tables_table_disable(net,
4633 trans->ctx.afi,
55dd6f93
PNA
4634 trans->ctx.table);
4635 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
4636 }
4637 } else {
f2a6d766 4638 nft_clear(net, trans->ctx.table);
55dd6f93 4639 }
35151d84 4640 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
55dd6f93
PNA
4641 nft_trans_destroy(trans);
4642 break;
4643 case NFT_MSG_DELTABLE:
f2a6d766 4644 list_del_rcu(&trans->ctx.table->list);
35151d84 4645 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
55dd6f93 4646 break;
91c7b38d
PNA
4647 case NFT_MSG_NEWCHAIN:
4648 if (nft_trans_chain_update(trans))
4649 nft_chain_commit_update(trans);
4fefee57 4650 else
664b0f8c 4651 nft_clear(net, trans->ctx.chain);
4fefee57 4652
35151d84 4653 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
91c7b38d
PNA
4654 nft_trans_destroy(trans);
4655 break;
4656 case NFT_MSG_DELCHAIN:
664b0f8c 4657 list_del_rcu(&trans->ctx.chain->list);
35151d84 4658 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
82bec71d
PNA
4659 nf_tables_unregister_hooks(trans->ctx.net,
4660 trans->ctx.table,
c5598794
AB
4661 trans->ctx.chain,
4662 trans->ctx.afi->nops);
91c7b38d 4663 break;
b380e5c7 4664 case NFT_MSG_NEWRULE:
889f7ee7 4665 nft_clear(trans->ctx.net, nft_trans_rule(trans));
35151d84 4666 nf_tables_rule_notify(&trans->ctx,
37082f93 4667 nft_trans_rule(trans),
35151d84 4668 NFT_MSG_NEWRULE);
37082f93 4669 nft_trans_destroy(trans);
b380e5c7
PNA
4670 break;
4671 case NFT_MSG_DELRULE:
4672 list_del_rcu(&nft_trans_rule(trans)->list);
35151d84
PNA
4673 nf_tables_rule_notify(&trans->ctx,
4674 nft_trans_rule(trans),
4675 NFT_MSG_DELRULE);
b380e5c7 4676 break;
958bee14 4677 case NFT_MSG_NEWSET:
37a9cc52 4678 nft_clear(net, nft_trans_set(trans));
4fefee57
PNA
4679 /* This avoids hitting -EBUSY when deleting the table
4680 * from the transaction.
4681 */
4682 if (nft_trans_set(trans)->flags & NFT_SET_ANONYMOUS &&
4683 !list_empty(&nft_trans_set(trans)->bindings))
4684 trans->ctx.table->use--;
4685
958bee14 4686 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 4687 NFT_MSG_NEWSET, GFP_KERNEL);
958bee14
PNA
4688 nft_trans_destroy(trans);
4689 break;
4690 case NFT_MSG_DELSET:
37a9cc52 4691 list_del_rcu(&nft_trans_set(trans)->list);
958bee14 4692 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 4693 NFT_MSG_DELSET, GFP_KERNEL);
958bee14 4694 break;
60319eb1 4695 case NFT_MSG_NEWSETELEM:
cc02e457
PM
4696 te = (struct nft_trans_elem *)trans->data;
4697
42a55769 4698 te->set->ops->activate(net, te->set, &te->elem);
cc02e457
PM
4699 nf_tables_setelem_notify(&trans->ctx, te->set,
4700 &te->elem,
60319eb1
PNA
4701 NFT_MSG_NEWSETELEM, 0);
4702 nft_trans_destroy(trans);
4703 break;
4704 case NFT_MSG_DELSETELEM:
a3716e70 4705 te = (struct nft_trans_elem *)trans->data;
fe2811eb 4706
a3716e70
PNA
4707 nf_tables_setelem_notify(&trans->ctx, te->set,
4708 &te->elem,
60319eb1 4709 NFT_MSG_DELSETELEM, 0);
02263db0 4710 te->set->ops->remove(te->set, &te->elem);
3dd0673a
PM
4711 atomic_dec(&te->set->nelems);
4712 te->set->ndeact--;
60319eb1 4713 break;
e5009240
PNA
4714 case NFT_MSG_NEWOBJ:
4715 nft_clear(net, nft_trans_obj(trans));
4716 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
4717 NFT_MSG_NEWOBJ);
4718 nft_trans_destroy(trans);
4719 break;
4720 case NFT_MSG_DELOBJ:
4721 list_del_rcu(&nft_trans_obj(trans)->list);
4722 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
4723 NFT_MSG_DELOBJ);
4724 break;
37082f93 4725 }
37082f93
PNA
4726 }
4727
b326dd37
PNA
4728 synchronize_rcu();
4729
37082f93 4730 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
c7c32e72 4731 list_del(&trans->list);
b326dd37 4732 nf_tables_commit_release(trans);
37082f93 4733 }
84d7fce6
PNA
4734
4735 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
37082f93
PNA
4736
4737 return 0;
4738}
4739
b326dd37 4740static void nf_tables_abort_release(struct nft_trans *trans)
c7c32e72 4741{
c7c32e72
PNA
4742 switch (trans->msg_type) {
4743 case NFT_MSG_NEWTABLE:
4744 nf_tables_table_destroy(&trans->ctx);
4745 break;
4746 case NFT_MSG_NEWCHAIN:
4747 nf_tables_chain_destroy(trans->ctx.chain);
4748 break;
4749 case NFT_MSG_NEWRULE:
4750 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
4751 break;
4752 case NFT_MSG_NEWSET:
4753 nft_set_destroy(nft_trans_set(trans));
4754 break;
61edafbb
PM
4755 case NFT_MSG_NEWSETELEM:
4756 nft_set_elem_destroy(nft_trans_elem_set(trans),
61f9e292 4757 nft_trans_elem(trans).priv, true);
61edafbb 4758 break;
e5009240
PNA
4759 case NFT_MSG_NEWOBJ:
4760 nft_obj_destroy(nft_trans_obj(trans));
4761 break;
c7c32e72
PNA
4762 }
4763 kfree(trans);
4764}
4765
5913beaf 4766static int nf_tables_abort(struct net *net, struct sk_buff *skb)
37082f93 4767{
37082f93 4768 struct nft_trans *trans, *next;
02263db0 4769 struct nft_trans_elem *te;
37082f93 4770
a907e36d
XL
4771 list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
4772 list) {
b380e5c7 4773 switch (trans->msg_type) {
55dd6f93
PNA
4774 case NFT_MSG_NEWTABLE:
4775 if (nft_trans_table_update(trans)) {
4776 if (nft_trans_table_enable(trans)) {
664b0f8c
PNA
4777 nf_tables_table_disable(net,
4778 trans->ctx.afi,
55dd6f93
PNA
4779 trans->ctx.table);
4780 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
4781 }
4782 nft_trans_destroy(trans);
4783 } else {
e688a7f8 4784 list_del_rcu(&trans->ctx.table->list);
55dd6f93
PNA
4785 }
4786 break;
4787 case NFT_MSG_DELTABLE:
f2a6d766 4788 nft_clear(trans->ctx.net, trans->ctx.table);
55dd6f93
PNA
4789 nft_trans_destroy(trans);
4790 break;
91c7b38d
PNA
4791 case NFT_MSG_NEWCHAIN:
4792 if (nft_trans_chain_update(trans)) {
982f4051 4793 free_percpu(nft_trans_chain_stats(trans));
91c7b38d
PNA
4794
4795 nft_trans_destroy(trans);
4796 } else {
4fefee57 4797 trans->ctx.table->use--;
e688a7f8 4798 list_del_rcu(&trans->ctx.chain->list);
82bec71d
PNA
4799 nf_tables_unregister_hooks(trans->ctx.net,
4800 trans->ctx.table,
c5598794
AB
4801 trans->ctx.chain,
4802 trans->ctx.afi->nops);
91c7b38d
PNA
4803 }
4804 break;
4805 case NFT_MSG_DELCHAIN:
4fefee57 4806 trans->ctx.table->use++;
664b0f8c 4807 nft_clear(trans->ctx.net, trans->ctx.chain);
91c7b38d
PNA
4808 nft_trans_destroy(trans);
4809 break;
b380e5c7 4810 case NFT_MSG_NEWRULE:
4fefee57 4811 trans->ctx.chain->use--;
b380e5c7
PNA
4812 list_del_rcu(&nft_trans_rule(trans)->list);
4813 break;
4814 case NFT_MSG_DELRULE:
4fefee57 4815 trans->ctx.chain->use++;
889f7ee7 4816 nft_clear(trans->ctx.net, nft_trans_rule(trans));
37082f93 4817 nft_trans_destroy(trans);
b380e5c7 4818 break;
958bee14 4819 case NFT_MSG_NEWSET:
4fefee57 4820 trans->ctx.table->use--;
e688a7f8 4821 list_del_rcu(&nft_trans_set(trans)->list);
958bee14
PNA
4822 break;
4823 case NFT_MSG_DELSET:
4fefee57 4824 trans->ctx.table->use++;
37a9cc52 4825 nft_clear(trans->ctx.net, nft_trans_set(trans));
958bee14
PNA
4826 nft_trans_destroy(trans);
4827 break;
60319eb1 4828 case NFT_MSG_NEWSETELEM:
02263db0 4829 te = (struct nft_trans_elem *)trans->data;
fe2811eb 4830
02263db0 4831 te->set->ops->remove(te->set, &te->elem);
3dd0673a 4832 atomic_dec(&te->set->nelems);
60319eb1
PNA
4833 break;
4834 case NFT_MSG_DELSETELEM:
cc02e457
PM
4835 te = (struct nft_trans_elem *)trans->data;
4836
42a55769 4837 te->set->ops->activate(net, te->set, &te->elem);
3dd0673a 4838 te->set->ndeact--;
cc02e457 4839
e5009240
PNA
4840 nft_trans_destroy(trans);
4841 break;
4842 case NFT_MSG_NEWOBJ:
4843 trans->ctx.table->use--;
4844 list_del_rcu(&nft_trans_obj(trans)->list);
4845 break;
4846 case NFT_MSG_DELOBJ:
4847 trans->ctx.table->use++;
4848 nft_clear(trans->ctx.net, nft_trans_obj(trans));
60319eb1
PNA
4849 nft_trans_destroy(trans);
4850 break;
37082f93 4851 }
37082f93
PNA
4852 }
4853
b326dd37
PNA
4854 synchronize_rcu();
4855
a1cee076
PNA
4856 list_for_each_entry_safe_reverse(trans, next,
4857 &net->nft.commit_list, list) {
c7c32e72 4858 list_del(&trans->list);
b326dd37 4859 nf_tables_abort_release(trans);
37082f93
PNA
4860 }
4861
4862 return 0;
4863}
4864
96518518
PM
4865static const struct nfnetlink_subsystem nf_tables_subsys = {
4866 .name = "nf_tables",
4867 .subsys_id = NFNL_SUBSYS_NFTABLES,
4868 .cb_count = NFT_MSG_MAX,
4869 .cb = nf_tables_cb,
0628b123
PNA
4870 .commit = nf_tables_commit,
4871 .abort = nf_tables_abort,
96518518
PM
4872};
4873
7210e4e3
PNA
4874int nft_chain_validate_dependency(const struct nft_chain *chain,
4875 enum nft_chain_type type)
4876{
4877 const struct nft_base_chain *basechain;
4878
4879 if (chain->flags & NFT_BASE_CHAIN) {
4880 basechain = nft_base_chain(chain);
4881 if (basechain->type->type != type)
4882 return -EOPNOTSUPP;
4883 }
4884 return 0;
4885}
4886EXPORT_SYMBOL_GPL(nft_chain_validate_dependency);
4887
75e8d06d
PNA
4888int nft_chain_validate_hooks(const struct nft_chain *chain,
4889 unsigned int hook_flags)
4890{
4891 struct nft_base_chain *basechain;
4892
4893 if (chain->flags & NFT_BASE_CHAIN) {
4894 basechain = nft_base_chain(chain);
4895
4896 if ((1 << basechain->ops[0].hooknum) & hook_flags)
4897 return 0;
4898
4899 return -EOPNOTSUPP;
4900 }
4901
4902 return 0;
4903}
4904EXPORT_SYMBOL_GPL(nft_chain_validate_hooks);
4905
20a69341
PM
4906/*
4907 * Loop detection - walk through the ruleset beginning at the destination chain
4908 * of a new jump until either the source chain is reached (loop) or all
4909 * reachable chains have been traversed.
4910 *
4911 * The loop check is performed whenever a new jump verdict is added to an
4912 * expression or verdict map or a verdict map is bound to a new chain.
4913 */
4914
4915static int nf_tables_check_loops(const struct nft_ctx *ctx,
4916 const struct nft_chain *chain);
4917
4918static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
4919 const struct nft_set *set,
4920 const struct nft_set_iter *iter,
4921 const struct nft_set_elem *elem)
4922{
fe2811eb
PM
4923 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4924 const struct nft_data *data;
4925
4926 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
4927 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
62f9c8b4
PNA
4928 return 0;
4929
fe2811eb 4930 data = nft_set_ext_data(ext);
1ca2e170 4931 switch (data->verdict.code) {
20a69341
PM
4932 case NFT_JUMP:
4933 case NFT_GOTO:
1ca2e170 4934 return nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
4935 default:
4936 return 0;
4937 }
4938}
4939
4940static int nf_tables_check_loops(const struct nft_ctx *ctx,
4941 const struct nft_chain *chain)
4942{
4943 const struct nft_rule *rule;
4944 const struct nft_expr *expr, *last;
20a69341
PM
4945 const struct nft_set *set;
4946 struct nft_set_binding *binding;
4947 struct nft_set_iter iter;
20a69341
PM
4948
4949 if (ctx->chain == chain)
4950 return -ELOOP;
4951
4952 list_for_each_entry(rule, &chain->rules, list) {
4953 nft_rule_for_each_expr(expr, last, rule) {
0ca743a5
PNA
4954 const struct nft_data *data = NULL;
4955 int err;
4956
4957 if (!expr->ops->validate)
20a69341
PM
4958 continue;
4959
0ca743a5
PNA
4960 err = expr->ops->validate(ctx, expr, &data);
4961 if (err < 0)
4962 return err;
4963
20a69341 4964 if (data == NULL)
0ca743a5 4965 continue;
20a69341 4966
1ca2e170 4967 switch (data->verdict.code) {
20a69341
PM
4968 case NFT_JUMP:
4969 case NFT_GOTO:
1ca2e170
PM
4970 err = nf_tables_check_loops(ctx,
4971 data->verdict.chain);
20a69341
PM
4972 if (err < 0)
4973 return err;
4974 default:
4975 break;
4976 }
4977 }
4978 }
4979
4980 list_for_each_entry(set, &ctx->table->sets, list) {
37a9cc52
PNA
4981 if (!nft_is_active_next(ctx->net, set))
4982 continue;
20a69341
PM
4983 if (!(set->flags & NFT_SET_MAP) ||
4984 set->dtype != NFT_DATA_VERDICT)
4985 continue;
4986
4987 list_for_each_entry(binding, &set->bindings, list) {
11113e19
PM
4988 if (!(binding->flags & NFT_SET_MAP) ||
4989 binding->chain != chain)
20a69341
PM
4990 continue;
4991
8588ac09 4992 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
4993 iter.skip = 0;
4994 iter.count = 0;
4995 iter.err = 0;
4996 iter.fn = nf_tables_loop_check_setelem;
4997
4998 set->ops->walk(ctx, set, &iter);
4999 if (iter.err < 0)
5000 return iter.err;
5001 }
5002 }
5003
5004 return 0;
5005}
5006
36b701fa
LGL
5007/**
5008 * nft_parse_u32_check - fetch u32 attribute and check for maximum value
5009 *
5010 * @attr: netlink attribute to fetch value from
5011 * @max: maximum value to be stored in dest
5012 * @dest: pointer to the variable
5013 *
5014 * Parse, check and store a given u32 netlink attribute into variable.
5015 * This function returns -ERANGE if the value goes over maximum value.
5016 * Otherwise a 0 is returned and the attribute value is stored in the
5017 * destination variable.
5018 */
f1d505bb 5019int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
36b701fa 5020{
09525a09 5021 u32 val;
36b701fa
LGL
5022
5023 val = ntohl(nla_get_be32(attr));
5024 if (val > max)
5025 return -ERANGE;
5026
5027 *dest = val;
5028 return 0;
5029}
5030EXPORT_SYMBOL_GPL(nft_parse_u32_check);
5031
49499c3e
PM
5032/**
5033 * nft_parse_register - parse a register value from a netlink attribute
5034 *
5035 * @attr: netlink attribute
5036 *
5037 * Parse and translate a register value from a netlink attribute.
5038 * Registers used to be 128 bit wide, these register numbers will be
5039 * mapped to the corresponding 32 bit register numbers.
5040 */
b1c96ed3
PM
5041unsigned int nft_parse_register(const struct nlattr *attr)
5042{
49499c3e
PM
5043 unsigned int reg;
5044
5045 reg = ntohl(nla_get_be32(attr));
5046 switch (reg) {
5047 case NFT_REG_VERDICT...NFT_REG_4:
5048 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
5049 default:
5050 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
5051 }
b1c96ed3
PM
5052}
5053EXPORT_SYMBOL_GPL(nft_parse_register);
5054
49499c3e
PM
5055/**
5056 * nft_dump_register - dump a register value to a netlink attribute
5057 *
5058 * @skb: socket buffer
5059 * @attr: attribute number
5060 * @reg: register number
5061 *
5062 * Construct a netlink attribute containing the register number. For
5063 * compatibility reasons, register numbers being a multiple of 4 are
5064 * translated to the corresponding 128 bit register numbers.
5065 */
b1c96ed3
PM
5066int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
5067{
49499c3e
PM
5068 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
5069 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
5070 else
5071 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
5072
b1c96ed3
PM
5073 return nla_put_be32(skb, attr, htonl(reg));
5074}
5075EXPORT_SYMBOL_GPL(nft_dump_register);
5076
96518518 5077/**
d07db988 5078 * nft_validate_register_load - validate a load from a register
96518518
PM
5079 *
5080 * @reg: the register number
d07db988 5081 * @len: the length of the data
96518518
PM
5082 *
5083 * Validate that the input register is one of the general purpose
d07db988 5084 * registers and that the length of the load is within the bounds.
96518518 5085 */
d07db988 5086int nft_validate_register_load(enum nft_registers reg, unsigned int len)
96518518 5087{
49499c3e 5088 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
96518518 5089 return -EINVAL;
d07db988
PM
5090 if (len == 0)
5091 return -EINVAL;
49499c3e 5092 if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
d07db988 5093 return -ERANGE;
49499c3e 5094
96518518
PM
5095 return 0;
5096}
d07db988 5097EXPORT_SYMBOL_GPL(nft_validate_register_load);
96518518 5098
96518518 5099/**
1ec10212 5100 * nft_validate_register_store - validate an expressions' register store
96518518
PM
5101 *
5102 * @ctx: context of the expression performing the load
5103 * @reg: the destination register number
5104 * @data: the data to load
5105 * @type: the data type
45d9bcda 5106 * @len: the length of the data
96518518
PM
5107 *
5108 * Validate that a data load uses the appropriate data type for
45d9bcda
PM
5109 * the destination register and the length is within the bounds.
5110 * A value of NULL for the data means that its runtime gathered
58f40ab6 5111 * data.
96518518 5112 */
1ec10212
PM
5113int nft_validate_register_store(const struct nft_ctx *ctx,
5114 enum nft_registers reg,
5115 const struct nft_data *data,
5116 enum nft_data_types type, unsigned int len)
96518518 5117{
20a69341
PM
5118 int err;
5119
96518518
PM
5120 switch (reg) {
5121 case NFT_REG_VERDICT:
58f40ab6 5122 if (type != NFT_DATA_VERDICT)
96518518 5123 return -EINVAL;
20a69341 5124
58f40ab6 5125 if (data != NULL &&
1ca2e170
PM
5126 (data->verdict.code == NFT_GOTO ||
5127 data->verdict.code == NFT_JUMP)) {
5128 err = nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
5129 if (err < 0)
5130 return err;
5131
1ca2e170
PM
5132 if (ctx->chain->level + 1 >
5133 data->verdict.chain->level) {
20a69341
PM
5134 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
5135 return -EMLINK;
1ca2e170 5136 data->verdict.chain->level = ctx->chain->level + 1;
20a69341
PM
5137 }
5138 }
5139
96518518
PM
5140 return 0;
5141 default:
49499c3e 5142 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
27e6d201 5143 return -EINVAL;
45d9bcda
PM
5144 if (len == 0)
5145 return -EINVAL;
49499c3e
PM
5146 if (reg * NFT_REG32_SIZE + len >
5147 FIELD_SIZEOF(struct nft_regs, data))
45d9bcda 5148 return -ERANGE;
27e6d201 5149
96518518
PM
5150 if (data != NULL && type != NFT_DATA_VALUE)
5151 return -EINVAL;
5152 return 0;
5153 }
5154}
1ec10212 5155EXPORT_SYMBOL_GPL(nft_validate_register_store);
96518518
PM
5156
5157static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
5158 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
5159 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
5160 .len = NFT_CHAIN_MAXNAMELEN - 1 },
5161};
5162
5163static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
5164 struct nft_data_desc *desc, const struct nlattr *nla)
5165{
664b0f8c 5166 u8 genmask = nft_genmask_next(ctx->net);
96518518
PM
5167 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
5168 struct nft_chain *chain;
5169 int err;
5170
5171 err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy);
5172 if (err < 0)
5173 return err;
5174
5175 if (!tb[NFTA_VERDICT_CODE])
5176 return -EINVAL;
1ca2e170 5177 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
96518518 5178
1ca2e170 5179 switch (data->verdict.code) {
e0abdadc 5180 default:
1ca2e170 5181 switch (data->verdict.code & NF_VERDICT_MASK) {
e0abdadc
PM
5182 case NF_ACCEPT:
5183 case NF_DROP:
5184 case NF_QUEUE:
5185 break;
5186 default:
5187 return -EINVAL;
5188 }
5189 /* fall through */
96518518
PM
5190 case NFT_CONTINUE:
5191 case NFT_BREAK:
5192 case NFT_RETURN:
96518518
PM
5193 break;
5194 case NFT_JUMP:
5195 case NFT_GOTO:
5196 if (!tb[NFTA_VERDICT_CHAIN])
5197 return -EINVAL;
5198 chain = nf_tables_chain_lookup(ctx->table,
664b0f8c 5199 tb[NFTA_VERDICT_CHAIN], genmask);
96518518
PM
5200 if (IS_ERR(chain))
5201 return PTR_ERR(chain);
5202 if (chain->flags & NFT_BASE_CHAIN)
5203 return -EOPNOTSUPP;
5204
96518518 5205 chain->use++;
1ca2e170 5206 data->verdict.chain = chain;
96518518 5207 break;
96518518
PM
5208 }
5209
4c4ed074 5210 desc->len = sizeof(data->verdict);
96518518
PM
5211 desc->type = NFT_DATA_VERDICT;
5212 return 0;
5213}
5214
5215static void nft_verdict_uninit(const struct nft_data *data)
5216{
1ca2e170 5217 switch (data->verdict.code) {
96518518
PM
5218 case NFT_JUMP:
5219 case NFT_GOTO:
1ca2e170 5220 data->verdict.chain->use--;
96518518
PM
5221 break;
5222 }
5223}
5224
33d5a7b1 5225int nft_verdict_dump(struct sk_buff *skb, int type, const struct nft_verdict *v)
96518518
PM
5226{
5227 struct nlattr *nest;
5228
33d5a7b1 5229 nest = nla_nest_start(skb, type);
96518518
PM
5230 if (!nest)
5231 goto nla_put_failure;
5232
33d5a7b1 5233 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(v->code)))
96518518
PM
5234 goto nla_put_failure;
5235
33d5a7b1 5236 switch (v->code) {
96518518
PM
5237 case NFT_JUMP:
5238 case NFT_GOTO:
1ca2e170 5239 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
33d5a7b1 5240 v->chain->name))
96518518
PM
5241 goto nla_put_failure;
5242 }
5243 nla_nest_end(skb, nest);
5244 return 0;
5245
5246nla_put_failure:
5247 return -1;
5248}
5249
d0a11fc3
PM
5250static int nft_value_init(const struct nft_ctx *ctx,
5251 struct nft_data *data, unsigned int size,
96518518
PM
5252 struct nft_data_desc *desc, const struct nlattr *nla)
5253{
5254 unsigned int len;
5255
5256 len = nla_len(nla);
5257 if (len == 0)
5258 return -EINVAL;
d0a11fc3 5259 if (len > size)
96518518
PM
5260 return -EOVERFLOW;
5261
d0a11fc3 5262 nla_memcpy(data->data, nla, len);
96518518
PM
5263 desc->type = NFT_DATA_VALUE;
5264 desc->len = len;
5265 return 0;
5266}
5267
5268static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
5269 unsigned int len)
5270{
5271 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
5272}
5273
5274static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
d0a11fc3 5275 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
96518518
PM
5276 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
5277};
5278
5279/**
5280 * nft_data_init - parse nf_tables data netlink attributes
5281 *
5282 * @ctx: context of the expression using the data
5283 * @data: destination struct nft_data
d0a11fc3 5284 * @size: maximum data length
96518518
PM
5285 * @desc: data description
5286 * @nla: netlink attribute containing data
5287 *
5288 * Parse the netlink data attributes and initialize a struct nft_data.
5289 * The type and length of data are returned in the data description.
5290 *
5291 * The caller can indicate that it only wants to accept data of type
5292 * NFT_DATA_VALUE by passing NULL for the ctx argument.
5293 */
d0a11fc3
PM
5294int nft_data_init(const struct nft_ctx *ctx,
5295 struct nft_data *data, unsigned int size,
96518518
PM
5296 struct nft_data_desc *desc, const struct nlattr *nla)
5297{
5298 struct nlattr *tb[NFTA_DATA_MAX + 1];
5299 int err;
5300
5301 err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy);
5302 if (err < 0)
5303 return err;
5304
5305 if (tb[NFTA_DATA_VALUE])
d0a11fc3
PM
5306 return nft_value_init(ctx, data, size, desc,
5307 tb[NFTA_DATA_VALUE]);
96518518
PM
5308 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
5309 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
5310 return -EINVAL;
5311}
5312EXPORT_SYMBOL_GPL(nft_data_init);
5313
5314/**
5315 * nft_data_uninit - release a nft_data item
5316 *
5317 * @data: struct nft_data to release
5318 * @type: type of data
5319 *
5320 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
5321 * all others need to be released by calling this function.
5322 */
5323void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
5324{
960bd2c2 5325 if (type < NFT_DATA_VERDICT)
96518518 5326 return;
960bd2c2 5327 switch (type) {
96518518
PM
5328 case NFT_DATA_VERDICT:
5329 return nft_verdict_uninit(data);
5330 default:
5331 WARN_ON(1);
5332 }
5333}
5334EXPORT_SYMBOL_GPL(nft_data_uninit);
5335
5336int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
5337 enum nft_data_types type, unsigned int len)
5338{
5339 struct nlattr *nest;
5340 int err;
5341
5342 nest = nla_nest_start(skb, attr);
5343 if (nest == NULL)
5344 return -1;
5345
5346 switch (type) {
5347 case NFT_DATA_VALUE:
5348 err = nft_value_dump(skb, data, len);
5349 break;
5350 case NFT_DATA_VERDICT:
33d5a7b1 5351 err = nft_verdict_dump(skb, NFTA_DATA_VERDICT, &data->verdict);
96518518
PM
5352 break;
5353 default:
5354 err = -EINVAL;
5355 WARN_ON(1);
5356 }
5357
5358 nla_nest_end(skb, nest);
5359 return err;
5360}
5361EXPORT_SYMBOL_GPL(nft_data_dump);
5362
df05ef87 5363static int __net_init nf_tables_init_net(struct net *net)
99633ab2
PNA
5364{
5365 INIT_LIST_HEAD(&net->nft.af_info);
0628b123 5366 INIT_LIST_HEAD(&net->nft.commit_list);
38e029f1 5367 net->nft.base_seq = 1;
99633ab2
PNA
5368 return 0;
5369}
5370
5ebe0b0e
PNA
5371int __nft_release_basechain(struct nft_ctx *ctx)
5372{
5373 struct nft_rule *rule, *nr;
5374
5375 BUG_ON(!(ctx->chain->flags & NFT_BASE_CHAIN));
5376
82bec71d 5377 nf_tables_unregister_hooks(ctx->net, ctx->chain->table, ctx->chain,
5ebe0b0e
PNA
5378 ctx->afi->nops);
5379 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
5380 list_del(&rule->list);
5381 ctx->chain->use--;
5382 nf_tables_rule_destroy(ctx, rule);
5383 }
5384 list_del(&ctx->chain->list);
5385 ctx->table->use--;
5386 nf_tables_chain_destroy(ctx->chain);
5387
5388 return 0;
5389}
5390EXPORT_SYMBOL_GPL(__nft_release_basechain);
5391
df05ef87
PNA
5392/* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */
5393static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
5394{
5395 struct nft_table *table, *nt;
5396 struct nft_chain *chain, *nc;
e5009240 5397 struct nft_object *obj, *ne;
df05ef87
PNA
5398 struct nft_rule *rule, *nr;
5399 struct nft_set *set, *ns;
5400 struct nft_ctx ctx = {
5401 .net = net,
5402 .afi = afi,
5403 };
5404
5405 list_for_each_entry_safe(table, nt, &afi->tables, list) {
5406 list_for_each_entry(chain, &table->chains, list)
82bec71d
PNA
5407 nf_tables_unregister_hooks(net, table, chain,
5408 afi->nops);
df05ef87
PNA
5409 /* No packets are walking on these chains anymore. */
5410 ctx.table = table;
5411 list_for_each_entry(chain, &table->chains, list) {
5412 ctx.chain = chain;
5413 list_for_each_entry_safe(rule, nr, &chain->rules, list) {
5414 list_del(&rule->list);
5415 chain->use--;
5416 nf_tables_rule_destroy(&ctx, rule);
5417 }
5418 }
5419 list_for_each_entry_safe(set, ns, &table->sets, list) {
5420 list_del(&set->list);
5421 table->use--;
5422 nft_set_destroy(set);
5423 }
e5009240
PNA
5424 list_for_each_entry_safe(obj, ne, &table->objects, list) {
5425 list_del(&obj->list);
5426 table->use--;
5427 nft_obj_destroy(obj);
5428 }
df05ef87
PNA
5429 list_for_each_entry_safe(chain, nc, &table->chains, list) {
5430 list_del(&chain->list);
5431 table->use--;
5432 nf_tables_chain_destroy(chain);
5433 }
5434 list_del(&table->list);
5435 nf_tables_table_destroy(&ctx);
5436 }
5437}
5438
99633ab2
PNA
5439static struct pernet_operations nf_tables_net_ops = {
5440 .init = nf_tables_init_net,
5441};
5442
96518518
PM
5443static int __init nf_tables_module_init(void)
5444{
5445 int err;
5446
5447 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
5448 GFP_KERNEL);
5449 if (info == NULL) {
5450 err = -ENOMEM;
5451 goto err1;
5452 }
5453
5454 err = nf_tables_core_module_init();
5455 if (err < 0)
5456 goto err2;
5457
5458 err = nfnetlink_subsys_register(&nf_tables_subsys);
5459 if (err < 0)
5460 goto err3;
5461
5462 pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
99633ab2 5463 return register_pernet_subsys(&nf_tables_net_ops);
96518518
PM
5464err3:
5465 nf_tables_core_module_exit();
5466err2:
5467 kfree(info);
5468err1:
5469 return err;
5470}
5471
5472static void __exit nf_tables_module_exit(void)
5473{
99633ab2 5474 unregister_pernet_subsys(&nf_tables_net_ops);
96518518 5475 nfnetlink_subsys_unregister(&nf_tables_subsys);
1b1bc49c 5476 rcu_barrier();
96518518
PM
5477 nf_tables_core_module_exit();
5478 kfree(info);
5479}
5480
5481module_init(nf_tables_module_init);
5482module_exit(nf_tables_module_exit);
5483
5484MODULE_LICENSE("GPL");
5485MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
5486MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);