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