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