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