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