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