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