]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - net/netfilter/nf_tables_api.c
netfilter: add nftables
[mirror_ubuntu-hirsute-kernel.git] / net / netfilter / nf_tables_api.c
CommitLineData
96518518
PM
1/*
2 * Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
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,
107 const struct nlattr *nla,
108 bool autoload)
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
119#ifdef CONFIG_MODULES
120 if (autoload) {
121 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
122 request_module("nft-table-%u-%*.s", afi->family,
123 nla_len(nla)-1, (const char *)nla_data(nla));
124 nfnl_lock(NFNL_SUBSYS_NFTABLES);
125 if (nft_table_lookup(afi, nla))
126 return ERR_PTR(-EAGAIN);
127 }
128#endif
129 return ERR_PTR(-ENOENT);
130}
131
132static inline u64 nf_tables_alloc_handle(struct nft_table *table)
133{
134 return ++table->hgenerator;
135}
136
137static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
138 [NFTA_TABLE_NAME] = { .type = NLA_STRING },
139};
140
141static int nf_tables_fill_table_info(struct sk_buff *skb, u32 portid, u32 seq,
142 int event, u32 flags, int family,
143 const struct nft_table *table)
144{
145 struct nlmsghdr *nlh;
146 struct nfgenmsg *nfmsg;
147
148 event |= NFNL_SUBSYS_NFTABLES << 8;
149 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
150 if (nlh == NULL)
151 goto nla_put_failure;
152
153 nfmsg = nlmsg_data(nlh);
154 nfmsg->nfgen_family = family;
155 nfmsg->version = NFNETLINK_V0;
156 nfmsg->res_id = 0;
157
158 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name))
159 goto nla_put_failure;
160
161 return nlmsg_end(skb, nlh);
162
163nla_put_failure:
164 nlmsg_trim(skb, nlh);
165 return -1;
166}
167
168static int nf_tables_table_notify(const struct sk_buff *oskb,
169 const struct nlmsghdr *nlh,
170 const struct nft_table *table,
171 int event, int family)
172{
173 struct sk_buff *skb;
174 u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
175 u32 seq = nlh ? nlh->nlmsg_seq : 0;
176 struct net *net = oskb ? sock_net(oskb->sk) : &init_net;
177 bool report;
178 int err;
179
180 report = nlh ? nlmsg_report(nlh) : false;
181 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
182 return 0;
183
184 err = -ENOBUFS;
185 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
186 if (skb == NULL)
187 goto err;
188
189 err = nf_tables_fill_table_info(skb, portid, seq, event, 0,
190 family, table);
191 if (err < 0) {
192 kfree_skb(skb);
193 goto err;
194 }
195
196 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
197 GFP_KERNEL);
198err:
199 if (err < 0)
200 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
201 return err;
202}
203
204static int nf_tables_dump_tables(struct sk_buff *skb,
205 struct netlink_callback *cb)
206{
207 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
208 const struct nft_af_info *afi;
209 const struct nft_table *table;
210 unsigned int idx = 0, s_idx = cb->args[0];
211 int family = nfmsg->nfgen_family;
212
213 list_for_each_entry(afi, &nf_tables_afinfo, list) {
214 if (family != NFPROTO_UNSPEC && family != afi->family)
215 continue;
216
217 list_for_each_entry(table, &afi->tables, list) {
218 if (idx < s_idx)
219 goto cont;
220 if (idx > s_idx)
221 memset(&cb->args[1], 0,
222 sizeof(cb->args) - sizeof(cb->args[0]));
223 if (nf_tables_fill_table_info(skb,
224 NETLINK_CB(cb->skb).portid,
225 cb->nlh->nlmsg_seq,
226 NFT_MSG_NEWTABLE,
227 NLM_F_MULTI,
228 afi->family, table) < 0)
229 goto done;
230cont:
231 idx++;
232 }
233 }
234done:
235 cb->args[0] = idx;
236 return skb->len;
237}
238
239static int nf_tables_gettable(struct sock *nlsk, struct sk_buff *skb,
240 const struct nlmsghdr *nlh,
241 const struct nlattr * const nla[])
242{
243 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
244 const struct nft_af_info *afi;
245 const struct nft_table *table;
246 struct sk_buff *skb2;
247 int family = nfmsg->nfgen_family;
248 int err;
249
250 if (nlh->nlmsg_flags & NLM_F_DUMP) {
251 struct netlink_dump_control c = {
252 .dump = nf_tables_dump_tables,
253 };
254 return netlink_dump_start(nlsk, skb, nlh, &c);
255 }
256
257 afi = nf_tables_afinfo_lookup(family, false);
258 if (IS_ERR(afi))
259 return PTR_ERR(afi);
260
261 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], false);
262 if (IS_ERR(table))
263 return PTR_ERR(table);
264
265 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
266 if (!skb2)
267 return -ENOMEM;
268
269 err = nf_tables_fill_table_info(skb2, NETLINK_CB(skb).portid,
270 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
271 family, table);
272 if (err < 0)
273 goto err;
274
275 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
276
277err:
278 kfree_skb(skb2);
279 return err;
280}
281
282static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
283 const struct nlmsghdr *nlh,
284 const struct nlattr * const nla[])
285{
286 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
287 const struct nlattr *name;
288 struct nft_af_info *afi;
289 struct nft_table *table;
290 int family = nfmsg->nfgen_family;
291
292 afi = nf_tables_afinfo_lookup(family, true);
293 if (IS_ERR(afi))
294 return PTR_ERR(afi);
295
296 name = nla[NFTA_TABLE_NAME];
297 table = nf_tables_table_lookup(afi, name, false);
298 if (IS_ERR(table)) {
299 if (PTR_ERR(table) != -ENOENT)
300 return PTR_ERR(table);
301 table = NULL;
302 }
303
304 if (table != NULL) {
305 if (nlh->nlmsg_flags & NLM_F_EXCL)
306 return -EEXIST;
307 if (nlh->nlmsg_flags & NLM_F_REPLACE)
308 return -EOPNOTSUPP;
309 return 0;
310 }
311
312 table = kzalloc(sizeof(*table) + nla_len(name), GFP_KERNEL);
313 if (table == NULL)
314 return -ENOMEM;
315
316 nla_strlcpy(table->name, name, nla_len(name));
317 INIT_LIST_HEAD(&table->chains);
318
319 list_add_tail(&table->list, &afi->tables);
320 nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
321 return 0;
322}
323
324static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
325 const struct nlmsghdr *nlh,
326 const struct nlattr * const nla[])
327{
328 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
329 struct nft_af_info *afi;
330 struct nft_table *table;
331 int family = nfmsg->nfgen_family;
332
333 afi = nf_tables_afinfo_lookup(family, false);
334 if (IS_ERR(afi))
335 return PTR_ERR(afi);
336
337 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], false);
338 if (IS_ERR(table))
339 return PTR_ERR(table);
340
341 if (table->flags & NFT_TABLE_BUILTIN)
342 return -EOPNOTSUPP;
343
344 if (table->use)
345 return -EBUSY;
346
347 list_del(&table->list);
348 nf_tables_table_notify(skb, nlh, table, NFT_MSG_DELTABLE, family);
349 kfree(table);
350 return 0;
351}
352
353static struct nft_table *__nf_tables_table_lookup(const struct nft_af_info *afi,
354 const char *name)
355{
356 struct nft_table *table;
357
358 list_for_each_entry(table, &afi->tables, list) {
359 if (!strcmp(name, table->name))
360 return table;
361 }
362
363 return ERR_PTR(-ENOENT);
364}
365
366static int nf_tables_chain_notify(const struct sk_buff *oskb,
367 const struct nlmsghdr *nlh,
368 const struct nft_table *table,
369 const struct nft_chain *chain,
370 int event, int family);
371
372/**
373 * nft_register_table - register a built-in table
374 *
375 * @table: the table to register
376 * @family: protocol family to register table with
377 *
378 * Register a built-in table for use with nf_tables. Returns zero on
379 * success or a negative errno code otherwise.
380 */
381int nft_register_table(struct nft_table *table, int family)
382{
383 struct nft_af_info *afi;
384 struct nft_table *t;
385 struct nft_chain *chain;
386 int err;
387
388 nfnl_lock(NFNL_SUBSYS_NFTABLES);
389again:
390 afi = nf_tables_afinfo_lookup(family, true);
391 if (IS_ERR(afi)) {
392 err = PTR_ERR(afi);
393 if (err == -EAGAIN)
394 goto again;
395 goto err;
396 }
397
398 t = __nf_tables_table_lookup(afi, table->name);
399 if (IS_ERR(t)) {
400 err = PTR_ERR(t);
401 if (err != -ENOENT)
402 goto err;
403 t = NULL;
404 }
405
406 if (t != NULL) {
407 err = -EEXIST;
408 goto err;
409 }
410
411 table->flags |= NFT_TABLE_BUILTIN;
412 list_add_tail(&table->list, &afi->tables);
413 nf_tables_table_notify(NULL, NULL, table, NFT_MSG_NEWTABLE, family);
414 list_for_each_entry(chain, &table->chains, list)
415 nf_tables_chain_notify(NULL, NULL, table, chain,
416 NFT_MSG_NEWCHAIN, family);
417 err = 0;
418err:
419 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
420 return err;
421}
422EXPORT_SYMBOL_GPL(nft_register_table);
423
424/**
425 * nft_unregister_table - unregister a built-in table
426 *
427 * @table: the table to unregister
428 * @family: protocol family to unregister table with
429 *
430 * Unregister a built-in table for use with nf_tables.
431 */
432void nft_unregister_table(struct nft_table *table, int family)
433{
434 struct nft_chain *chain;
435
436 nfnl_lock(NFNL_SUBSYS_NFTABLES);
437 list_del(&table->list);
438 list_for_each_entry(chain, &table->chains, list)
439 nf_tables_chain_notify(NULL, NULL, table, chain,
440 NFT_MSG_DELCHAIN, family);
441 nf_tables_table_notify(NULL, NULL, table, NFT_MSG_DELTABLE, family);
442 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
443}
444EXPORT_SYMBOL_GPL(nft_unregister_table);
445
446/*
447 * Chains
448 */
449
450static struct nft_chain *
451nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle)
452{
453 struct nft_chain *chain;
454
455 list_for_each_entry(chain, &table->chains, list) {
456 if (chain->handle == handle)
457 return chain;
458 }
459
460 return ERR_PTR(-ENOENT);
461}
462
463static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
464 const struct nlattr *nla)
465{
466 struct nft_chain *chain;
467
468 if (nla == NULL)
469 return ERR_PTR(-EINVAL);
470
471 list_for_each_entry(chain, &table->chains, list) {
472 if (!nla_strcmp(nla, chain->name))
473 return chain;
474 }
475
476 return ERR_PTR(-ENOENT);
477}
478
479static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
480 [NFTA_CHAIN_TABLE] = { .type = NLA_STRING },
481 [NFTA_CHAIN_HANDLE] = { .type = NLA_U64 },
482 [NFTA_CHAIN_NAME] = { .type = NLA_STRING,
483 .len = NFT_CHAIN_MAXNAMELEN - 1 },
484 [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED },
485};
486
487static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
488 [NFTA_HOOK_HOOKNUM] = { .type = NLA_U32 },
489 [NFTA_HOOK_PRIORITY] = { .type = NLA_U32 },
490};
491
492static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq,
493 int event, u32 flags, int family,
494 const struct nft_table *table,
495 const struct nft_chain *chain)
496{
497 struct nlmsghdr *nlh;
498 struct nfgenmsg *nfmsg;
499
500 event |= NFNL_SUBSYS_NFTABLES << 8;
501 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
502 if (nlh == NULL)
503 goto nla_put_failure;
504
505 nfmsg = nlmsg_data(nlh);
506 nfmsg->nfgen_family = family;
507 nfmsg->version = NFNETLINK_V0;
508 nfmsg->res_id = 0;
509
510 if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
511 goto nla_put_failure;
512 if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle)))
513 goto nla_put_failure;
514 if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
515 goto nla_put_failure;
516
517 if (chain->flags & NFT_BASE_CHAIN) {
518 const struct nf_hook_ops *ops = &nft_base_chain(chain)->ops;
519 struct nlattr *nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
520 if (nest == NULL)
521 goto nla_put_failure;
522 if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum)))
523 goto nla_put_failure;
524 if (nla_put_be32(skb, NFTA_HOOK_PRIORITY, htonl(ops->priority)))
525 goto nla_put_failure;
526 nla_nest_end(skb, nest);
527 }
528
529 return nlmsg_end(skb, nlh);
530
531nla_put_failure:
532 nlmsg_trim(skb, nlh);
533 return -1;
534}
535
536static int nf_tables_chain_notify(const struct sk_buff *oskb,
537 const struct nlmsghdr *nlh,
538 const struct nft_table *table,
539 const struct nft_chain *chain,
540 int event, int family)
541{
542 struct sk_buff *skb;
543 u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
544 struct net *net = oskb ? sock_net(oskb->sk) : &init_net;
545 u32 seq = nlh ? nlh->nlmsg_seq : 0;
546 bool report;
547 int err;
548
549 report = nlh ? nlmsg_report(nlh) : false;
550 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
551 return 0;
552
553 err = -ENOBUFS;
554 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
555 if (skb == NULL)
556 goto err;
557
558 err = nf_tables_fill_chain_info(skb, portid, seq, event, 0, family,
559 table, chain);
560 if (err < 0) {
561 kfree_skb(skb);
562 goto err;
563 }
564
565 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
566 GFP_KERNEL);
567err:
568 if (err < 0)
569 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
570 return err;
571}
572
573static int nf_tables_dump_chains(struct sk_buff *skb,
574 struct netlink_callback *cb)
575{
576 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
577 const struct nft_af_info *afi;
578 const struct nft_table *table;
579 const struct nft_chain *chain;
580 unsigned int idx = 0, s_idx = cb->args[0];
581 int family = nfmsg->nfgen_family;
582
583 list_for_each_entry(afi, &nf_tables_afinfo, list) {
584 if (family != NFPROTO_UNSPEC && family != afi->family)
585 continue;
586
587 list_for_each_entry(table, &afi->tables, list) {
588 list_for_each_entry(chain, &table->chains, list) {
589 if (idx < s_idx)
590 goto cont;
591 if (idx > s_idx)
592 memset(&cb->args[1], 0,
593 sizeof(cb->args) - sizeof(cb->args[0]));
594 if (nf_tables_fill_chain_info(skb, NETLINK_CB(cb->skb).portid,
595 cb->nlh->nlmsg_seq,
596 NFT_MSG_NEWCHAIN,
597 NLM_F_MULTI,
598 afi->family, table, chain) < 0)
599 goto done;
600cont:
601 idx++;
602 }
603 }
604 }
605done:
606 cb->args[0] = idx;
607 return skb->len;
608}
609
610
611static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb,
612 const struct nlmsghdr *nlh,
613 const struct nlattr * const nla[])
614{
615 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
616 const struct nft_af_info *afi;
617 const struct nft_table *table;
618 const struct nft_chain *chain;
619 struct sk_buff *skb2;
620 int family = nfmsg->nfgen_family;
621 int err;
622
623 if (nlh->nlmsg_flags & NLM_F_DUMP) {
624 struct netlink_dump_control c = {
625 .dump = nf_tables_dump_chains,
626 };
627 return netlink_dump_start(nlsk, skb, nlh, &c);
628 }
629
630 afi = nf_tables_afinfo_lookup(family, false);
631 if (IS_ERR(afi))
632 return PTR_ERR(afi);
633
634 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], false);
635 if (IS_ERR(table))
636 return PTR_ERR(table);
637
638 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
639 if (IS_ERR(chain))
640 return PTR_ERR(chain);
641
642 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
643 if (!skb2)
644 return -ENOMEM;
645
646 err = nf_tables_fill_chain_info(skb2, NETLINK_CB(skb).portid,
647 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
648 family, table, chain);
649 if (err < 0)
650 goto err;
651
652 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
653
654err:
655 kfree_skb(skb2);
656 return err;
657}
658
659static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
660 const struct nlmsghdr *nlh,
661 const struct nlattr * const nla[])
662{
663 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
664 const struct nlattr * uninitialized_var(name);
665 const struct nft_af_info *afi;
666 struct nft_table *table;
667 struct nft_chain *chain;
668 struct nft_base_chain *basechain;
669 struct nlattr *ha[NFTA_HOOK_MAX + 1];
670 int family = nfmsg->nfgen_family;
671 u64 handle = 0;
672 int err;
673 bool create;
674
675 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
676
677 afi = nf_tables_afinfo_lookup(family, true);
678 if (IS_ERR(afi))
679 return PTR_ERR(afi);
680
681 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], create);
682 if (IS_ERR(table))
683 return PTR_ERR(table);
684
685 if (table->use == UINT_MAX)
686 return -EOVERFLOW;
687
688 chain = NULL;
689 name = nla[NFTA_CHAIN_NAME];
690
691 if (nla[NFTA_CHAIN_HANDLE]) {
692 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
693 chain = nf_tables_chain_lookup_byhandle(table, handle);
694 if (IS_ERR(chain))
695 return PTR_ERR(chain);
696 } else {
697 chain = nf_tables_chain_lookup(table, name);
698 if (IS_ERR(chain)) {
699 if (PTR_ERR(chain) != -ENOENT)
700 return PTR_ERR(chain);
701 chain = NULL;
702 }
703 }
704
705 if (chain != NULL) {
706 if (nlh->nlmsg_flags & NLM_F_EXCL)
707 return -EEXIST;
708 if (nlh->nlmsg_flags & NLM_F_REPLACE)
709 return -EOPNOTSUPP;
710
711 if (nla[NFTA_CHAIN_HANDLE] && name &&
712 !IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME])))
713 return -EEXIST;
714
715 if (nla[NFTA_CHAIN_HANDLE] && name)
716 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
717
718 goto notify;
719 }
720
721 if (nla[NFTA_CHAIN_HOOK]) {
722 struct nf_hook_ops *ops;
723
724 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
725 nft_hook_policy);
726 if (err < 0)
727 return err;
728 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
729 ha[NFTA_HOOK_PRIORITY] == NULL)
730 return -EINVAL;
731 if (ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM])) >= afi->nhooks)
732 return -EINVAL;
733
734 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
735 if (basechain == NULL)
736 return -ENOMEM;
737 chain = &basechain->chain;
738
739 ops = &basechain->ops;
740 ops->pf = family;
741 ops->owner = afi->owner;
742 ops->hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
743 ops->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
744 ops->priv = chain;
745 ops->hook = nft_do_chain;
746 if (afi->hooks[ops->hooknum])
747 ops->hook = afi->hooks[ops->hooknum];
748
749 chain->flags |= NFT_BASE_CHAIN;
750 } else {
751 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
752 if (chain == NULL)
753 return -ENOMEM;
754 }
755
756 INIT_LIST_HEAD(&chain->rules);
757 chain->handle = nf_tables_alloc_handle(table);
758 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
759
760 list_add_tail(&chain->list, &table->chains);
761 table->use++;
762notify:
763 nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_NEWCHAIN,
764 family);
765 return 0;
766}
767
768static void nf_tables_rcu_chain_destroy(struct rcu_head *head)
769{
770 struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
771
772 BUG_ON(chain->use > 0);
773
774 if (chain->flags & NFT_BASE_CHAIN)
775 kfree(nft_base_chain(chain));
776 else
777 kfree(chain);
778}
779
780static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
781 const struct nlmsghdr *nlh,
782 const struct nlattr * const nla[])
783{
784 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
785 const struct nft_af_info *afi;
786 struct nft_table *table;
787 struct nft_chain *chain;
788 int family = nfmsg->nfgen_family;
789
790 afi = nf_tables_afinfo_lookup(family, false);
791 if (IS_ERR(afi))
792 return PTR_ERR(afi);
793
794 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], false);
795 if (IS_ERR(table))
796 return PTR_ERR(table);
797
798 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
799 if (IS_ERR(chain))
800 return PTR_ERR(chain);
801
802 if (chain->flags & NFT_CHAIN_BUILTIN)
803 return -EOPNOTSUPP;
804
805 if (!list_empty(&chain->rules))
806 return -EBUSY;
807
808 list_del(&chain->list);
809 table->use--;
810
811 if (chain->flags & NFT_BASE_CHAIN)
812 nf_unregister_hook(&nft_base_chain(chain)->ops);
813
814 nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_DELCHAIN,
815 family);
816
817 /* Make sure all rule references are gone before this is released */
818 call_rcu(&chain->rcu_head, nf_tables_rcu_chain_destroy);
819 return 0;
820}
821
822static void nft_ctx_init(struct nft_ctx *ctx,
823 const struct nft_af_info *afi,
824 const struct nft_table *table,
825 const struct nft_chain *chain)
826{
827 ctx->afi = afi;
828 ctx->table = table;
829 ctx->chain = chain;
830}
831
832/*
833 * Expressions
834 */
835
836/**
837 * nft_register_expr - register nf_tables expr operations
838 * @ops: expr operations
839 *
840 * Registers the expr operations for use with nf_tables. Returns zero on
841 * success or a negative errno code otherwise.
842 */
843int nft_register_expr(struct nft_expr_ops *ops)
844{
845 nfnl_lock(NFNL_SUBSYS_NFTABLES);
846 list_add_tail(&ops->list, &nf_tables_expressions);
847 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
848 return 0;
849}
850EXPORT_SYMBOL_GPL(nft_register_expr);
851
852/**
853 * nft_unregister_expr - unregister nf_tables expr operations
854 * @ops: expr operations
855 *
856 * Unregisters the expr operations for use with nf_tables.
857 */
858void nft_unregister_expr(struct nft_expr_ops *ops)
859{
860 nfnl_lock(NFNL_SUBSYS_NFTABLES);
861 list_del(&ops->list);
862 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
863}
864EXPORT_SYMBOL_GPL(nft_unregister_expr);
865
866static const struct nft_expr_ops *__nft_expr_ops_get(struct nlattr *nla)
867{
868 const struct nft_expr_ops *ops;
869
870 list_for_each_entry(ops, &nf_tables_expressions, list) {
871 if (!nla_strcmp(nla, ops->name))
872 return ops;
873 }
874 return NULL;
875}
876
877static const struct nft_expr_ops *nft_expr_ops_get(struct nlattr *nla)
878{
879 const struct nft_expr_ops *ops;
880
881 if (nla == NULL)
882 return ERR_PTR(-EINVAL);
883
884 ops = __nft_expr_ops_get(nla);
885 if (ops != NULL && try_module_get(ops->owner))
886 return ops;
887
888#ifdef CONFIG_MODULES
889 if (ops == NULL) {
890 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
891 request_module("nft-expr-%.*s",
892 nla_len(nla), (char *)nla_data(nla));
893 nfnl_lock(NFNL_SUBSYS_NFTABLES);
894 if (__nft_expr_ops_get(nla))
895 return ERR_PTR(-EAGAIN);
896 }
897#endif
898 return ERR_PTR(-ENOENT);
899}
900
901static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
902 [NFTA_EXPR_NAME] = { .type = NLA_STRING },
903 [NFTA_EXPR_DATA] = { .type = NLA_NESTED },
904};
905
906static int nf_tables_fill_expr_info(struct sk_buff *skb,
907 const struct nft_expr *expr)
908{
909 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->name))
910 goto nla_put_failure;
911
912 if (expr->ops->dump) {
913 struct nlattr *data = nla_nest_start(skb, NFTA_EXPR_DATA);
914 if (data == NULL)
915 goto nla_put_failure;
916 if (expr->ops->dump(skb, expr) < 0)
917 goto nla_put_failure;
918 nla_nest_end(skb, data);
919 }
920
921 return skb->len;
922
923nla_put_failure:
924 return -1;
925};
926
927struct nft_expr_info {
928 const struct nft_expr_ops *ops;
929 struct nlattr *tb[NFTA_EXPR_MAX + 1];
930};
931
932static int nf_tables_expr_parse(const struct nlattr *nla,
933 struct nft_expr_info *info)
934{
935 const struct nft_expr_ops *ops;
936 int err;
937
938 err = nla_parse_nested(info->tb, NFTA_EXPR_MAX, nla, nft_expr_policy);
939 if (err < 0)
940 return err;
941
942 ops = nft_expr_ops_get(info->tb[NFTA_EXPR_NAME]);
943 if (IS_ERR(ops))
944 return PTR_ERR(ops);
945 info->ops = ops;
946 return 0;
947}
948
949static int nf_tables_newexpr(const struct nft_ctx *ctx,
950 struct nft_expr_info *info,
951 struct nft_expr *expr)
952{
953 const struct nft_expr_ops *ops = info->ops;
954 int err;
955
956 expr->ops = ops;
957 if (ops->init) {
958 struct nlattr *ma[ops->maxattr + 1];
959
960 if (info->tb[NFTA_EXPR_DATA]) {
961 err = nla_parse_nested(ma, ops->maxattr,
962 info->tb[NFTA_EXPR_DATA],
963 ops->policy);
964 if (err < 0)
965 goto err1;
966 } else
967 memset(ma, 0, sizeof(ma[0]) * (ops->maxattr + 1));
968
969 err = ops->init(ctx, expr, (const struct nlattr **)ma);
970 if (err < 0)
971 goto err1;
972 }
973
974 info->ops = NULL;
975 return 0;
976
977err1:
978 expr->ops = NULL;
979 return err;
980}
981
982static void nf_tables_expr_destroy(struct nft_expr *expr)
983{
984 if (expr->ops->destroy)
985 expr->ops->destroy(expr);
986 module_put(expr->ops->owner);
987}
988
989/*
990 * Rules
991 */
992
993static struct nft_rule *__nf_tables_rule_lookup(const struct nft_chain *chain,
994 u64 handle)
995{
996 struct nft_rule *rule;
997
998 // FIXME: this sucks
999 list_for_each_entry(rule, &chain->rules, list) {
1000 if (handle == rule->handle)
1001 return rule;
1002 }
1003
1004 return ERR_PTR(-ENOENT);
1005}
1006
1007static struct nft_rule *nf_tables_rule_lookup(const struct nft_chain *chain,
1008 const struct nlattr *nla)
1009{
1010 if (nla == NULL)
1011 return ERR_PTR(-EINVAL);
1012
1013 return __nf_tables_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
1014}
1015
1016static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
1017 [NFTA_RULE_TABLE] = { .type = NLA_STRING },
1018 [NFTA_RULE_CHAIN] = { .type = NLA_STRING,
1019 .len = NFT_CHAIN_MAXNAMELEN - 1 },
1020 [NFTA_RULE_HANDLE] = { .type = NLA_U64 },
1021 [NFTA_RULE_EXPRESSIONS] = { .type = NLA_NESTED },
1022};
1023
1024static int nf_tables_fill_rule_info(struct sk_buff *skb, u32 portid, u32 seq,
1025 int event, u32 flags, int family,
1026 const struct nft_table *table,
1027 const struct nft_chain *chain,
1028 const struct nft_rule *rule)
1029{
1030 struct nlmsghdr *nlh;
1031 struct nfgenmsg *nfmsg;
1032 const struct nft_expr *expr, *next;
1033 struct nlattr *list;
1034
1035 event |= NFNL_SUBSYS_NFTABLES << 8;
1036 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
1037 flags);
1038 if (nlh == NULL)
1039 goto nla_put_failure;
1040
1041 nfmsg = nlmsg_data(nlh);
1042 nfmsg->nfgen_family = family;
1043 nfmsg->version = NFNETLINK_V0;
1044 nfmsg->res_id = 0;
1045
1046 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
1047 goto nla_put_failure;
1048 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
1049 goto nla_put_failure;
1050 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle)))
1051 goto nla_put_failure;
1052
1053 list = nla_nest_start(skb, NFTA_RULE_EXPRESSIONS);
1054 if (list == NULL)
1055 goto nla_put_failure;
1056 nft_rule_for_each_expr(expr, next, rule) {
1057 struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM);
1058 if (elem == NULL)
1059 goto nla_put_failure;
1060 if (nf_tables_fill_expr_info(skb, expr) < 0)
1061 goto nla_put_failure;
1062 nla_nest_end(skb, elem);
1063 }
1064 nla_nest_end(skb, list);
1065
1066 return nlmsg_end(skb, nlh);
1067
1068nla_put_failure:
1069 nlmsg_trim(skb, nlh);
1070 return -1;
1071}
1072
1073static int nf_tables_rule_notify(const struct sk_buff *oskb,
1074 const struct nlmsghdr *nlh,
1075 const struct nft_table *table,
1076 const struct nft_chain *chain,
1077 const struct nft_rule *rule,
1078 int event, u32 flags, int family)
1079{
1080 struct sk_buff *skb;
1081 u32 portid = NETLINK_CB(oskb).portid;
1082 struct net *net = oskb ? sock_net(oskb->sk) : &init_net;
1083 u32 seq = nlh->nlmsg_seq;
1084 bool report;
1085 int err;
1086
1087 report = nlmsg_report(nlh);
1088 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
1089 return 0;
1090
1091 err = -ENOBUFS;
1092 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1093 if (skb == NULL)
1094 goto err;
1095
1096 err = nf_tables_fill_rule_info(skb, portid, seq, event, flags,
1097 family, table, chain, rule);
1098 if (err < 0) {
1099 kfree_skb(skb);
1100 goto err;
1101 }
1102
1103 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
1104 GFP_KERNEL);
1105err:
1106 if (err < 0)
1107 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
1108 return err;
1109}
1110
1111static int nf_tables_dump_rules(struct sk_buff *skb,
1112 struct netlink_callback *cb)
1113{
1114 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1115 const struct nft_af_info *afi;
1116 const struct nft_table *table;
1117 const struct nft_chain *chain;
1118 const struct nft_rule *rule;
1119 unsigned int idx = 0, s_idx = cb->args[0];
1120 int family = nfmsg->nfgen_family;
1121
1122 list_for_each_entry(afi, &nf_tables_afinfo, list) {
1123 if (family != NFPROTO_UNSPEC && family != afi->family)
1124 continue;
1125
1126 list_for_each_entry(table, &afi->tables, list) {
1127 list_for_each_entry(chain, &table->chains, list) {
1128 list_for_each_entry(rule, &chain->rules, list) {
1129 if (idx < s_idx)
1130 goto cont;
1131 if (idx > s_idx)
1132 memset(&cb->args[1], 0,
1133 sizeof(cb->args) - sizeof(cb->args[0]));
1134 if (nf_tables_fill_rule_info(skb, NETLINK_CB(cb->skb).portid,
1135 cb->nlh->nlmsg_seq,
1136 NFT_MSG_NEWRULE,
1137 NLM_F_MULTI | NLM_F_APPEND,
1138 afi->family, table, chain, rule) < 0)
1139 goto done;
1140cont:
1141 idx++;
1142 }
1143 }
1144 }
1145 }
1146done:
1147 cb->args[0] = idx;
1148 return skb->len;
1149}
1150
1151static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb,
1152 const struct nlmsghdr *nlh,
1153 const struct nlattr * const nla[])
1154{
1155 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1156 const struct nft_af_info *afi;
1157 const struct nft_table *table;
1158 const struct nft_chain *chain;
1159 const struct nft_rule *rule;
1160 struct sk_buff *skb2;
1161 int family = nfmsg->nfgen_family;
1162 int err;
1163
1164 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1165 struct netlink_dump_control c = {
1166 .dump = nf_tables_dump_rules,
1167 };
1168 return netlink_dump_start(nlsk, skb, nlh, &c);
1169 }
1170
1171 afi = nf_tables_afinfo_lookup(family, false);
1172 if (IS_ERR(afi))
1173 return PTR_ERR(afi);
1174
1175 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], false);
1176 if (IS_ERR(table))
1177 return PTR_ERR(table);
1178
1179 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1180 if (IS_ERR(chain))
1181 return PTR_ERR(chain);
1182
1183 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
1184 if (IS_ERR(rule))
1185 return PTR_ERR(rule);
1186
1187 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1188 if (!skb2)
1189 return -ENOMEM;
1190
1191 err = nf_tables_fill_rule_info(skb2, NETLINK_CB(skb).portid,
1192 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
1193 family, table, chain, rule);
1194 if (err < 0)
1195 goto err;
1196
1197 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1198
1199err:
1200 kfree_skb(skb2);
1201 return err;
1202}
1203
1204static void nf_tables_rcu_rule_destroy(struct rcu_head *head)
1205{
1206 struct nft_rule *rule = container_of(head, struct nft_rule, rcu_head);
1207 struct nft_expr *expr;
1208
1209 /*
1210 * Careful: some expressions might not be initialized in case this
1211 * is called on error from nf_tables_newrule().
1212 */
1213 expr = nft_expr_first(rule);
1214 while (expr->ops && expr != nft_expr_last(rule)) {
1215 nf_tables_expr_destroy(expr);
1216 expr = nft_expr_next(expr);
1217 }
1218 kfree(rule);
1219}
1220
1221static void nf_tables_rule_destroy(struct nft_rule *rule)
1222{
1223 call_rcu(&rule->rcu_head, nf_tables_rcu_rule_destroy);
1224}
1225
1226#define NFT_RULE_MAXEXPRS 128
1227
1228static struct nft_expr_info *info;
1229
1230static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1231 const struct nlmsghdr *nlh,
1232 const struct nlattr * const nla[])
1233{
1234 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1235 const struct nft_af_info *afi;
1236 struct nft_table *table;
1237 struct nft_chain *chain;
1238 struct nft_rule *rule, *old_rule = NULL;
1239 struct nft_expr *expr;
1240 struct nft_ctx ctx;
1241 struct nlattr *tmp;
1242 unsigned int size, i, n;
1243 int err, rem;
1244 bool create;
1245 u64 handle;
1246
1247 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
1248
1249 afi = nf_tables_afinfo_lookup(nfmsg->nfgen_family, create);
1250 if (IS_ERR(afi))
1251 return PTR_ERR(afi);
1252
1253 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], create);
1254 if (IS_ERR(table))
1255 return PTR_ERR(table);
1256
1257 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1258 if (IS_ERR(chain))
1259 return PTR_ERR(chain);
1260
1261 if (nla[NFTA_RULE_HANDLE]) {
1262 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
1263 rule = __nf_tables_rule_lookup(chain, handle);
1264 if (IS_ERR(rule))
1265 return PTR_ERR(rule);
1266
1267 if (nlh->nlmsg_flags & NLM_F_EXCL)
1268 return -EEXIST;
1269 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1270 old_rule = rule;
1271 else
1272 return -EOPNOTSUPP;
1273 } else {
1274 if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
1275 return -EINVAL;
1276 handle = nf_tables_alloc_handle(table);
1277 }
1278
1279 n = 0;
1280 size = 0;
1281 if (nla[NFTA_RULE_EXPRESSIONS]) {
1282 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
1283 err = -EINVAL;
1284 if (nla_type(tmp) != NFTA_LIST_ELEM)
1285 goto err1;
1286 if (n == NFT_RULE_MAXEXPRS)
1287 goto err1;
1288 err = nf_tables_expr_parse(tmp, &info[n]);
1289 if (err < 0)
1290 goto err1;
1291 size += info[n].ops->size;
1292 n++;
1293 }
1294 }
1295
1296 err = -ENOMEM;
1297 rule = kzalloc(sizeof(*rule) + size, GFP_KERNEL);
1298 if (rule == NULL)
1299 goto err1;
1300
1301 rule->handle = handle;
1302 rule->dlen = size;
1303
1304 nft_ctx_init(&ctx, afi, table, chain);
1305 expr = nft_expr_first(rule);
1306 for (i = 0; i < n; i++) {
1307 err = nf_tables_newexpr(&ctx, &info[i], expr);
1308 if (err < 0)
1309 goto err2;
1310 expr = nft_expr_next(expr);
1311 }
1312
1313 /* Register hook when first rule is inserted into a base chain */
1314 if (list_empty(&chain->rules) && chain->flags & NFT_BASE_CHAIN) {
1315 err = nf_register_hook(&nft_base_chain(chain)->ops);
1316 if (err < 0)
1317 goto err2;
1318 }
1319
1320 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
1321 list_replace_rcu(&old_rule->list, &rule->list);
1322 nf_tables_rule_destroy(old_rule);
1323 } else if (nlh->nlmsg_flags & NLM_F_APPEND)
1324 list_add_tail_rcu(&rule->list, &chain->rules);
1325 else
1326 list_add_rcu(&rule->list, &chain->rules);
1327
1328 nf_tables_rule_notify(skb, nlh, table, chain, rule, NFT_MSG_NEWRULE,
1329 nlh->nlmsg_flags & (NLM_F_APPEND | NLM_F_REPLACE),
1330 nfmsg->nfgen_family);
1331 return 0;
1332
1333err2:
1334 nf_tables_rule_destroy(rule);
1335err1:
1336 for (i = 0; i < n; i++) {
1337 if (info[i].ops != NULL)
1338 module_put(info[i].ops->owner);
1339 }
1340 return err;
1341}
1342
1343static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
1344 const struct nlmsghdr *nlh,
1345 const struct nlattr * const nla[])
1346{
1347 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1348 const struct nft_af_info *afi;
1349 const struct nft_table *table;
1350 struct nft_chain *chain;
1351 struct nft_rule *rule, *tmp;
1352 int family = nfmsg->nfgen_family;
1353
1354 afi = nf_tables_afinfo_lookup(family, false);
1355 if (IS_ERR(afi))
1356 return PTR_ERR(afi);
1357
1358 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], false);
1359 if (IS_ERR(table))
1360 return PTR_ERR(table);
1361
1362 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1363 if (IS_ERR(chain))
1364 return PTR_ERR(chain);
1365
1366 if (nla[NFTA_RULE_HANDLE]) {
1367 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
1368 if (IS_ERR(rule))
1369 return PTR_ERR(rule);
1370
1371 /* List removal must be visible before destroying expressions */
1372 list_del_rcu(&rule->list);
1373
1374 nf_tables_rule_notify(skb, nlh, table, chain, rule,
1375 NFT_MSG_DELRULE, 0, family);
1376 nf_tables_rule_destroy(rule);
1377 } else {
1378 /* Remove all rules in this chain */
1379 list_for_each_entry_safe(rule, tmp, &chain->rules, list) {
1380 list_del_rcu(&rule->list);
1381
1382 nf_tables_rule_notify(skb, nlh, table, chain, rule,
1383 NFT_MSG_DELRULE, 0, family);
1384 nf_tables_rule_destroy(rule);
1385 }
1386 }
1387
1388 /* Unregister hook when last rule from base chain is deleted */
1389 if (list_empty(&chain->rules) && chain->flags & NFT_BASE_CHAIN)
1390 nf_unregister_hook(&nft_base_chain(chain)->ops);
1391
1392 return 0;
1393}
1394
1395static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
1396 [NFT_MSG_NEWTABLE] = {
1397 .call = nf_tables_newtable,
1398 .attr_count = NFTA_TABLE_MAX,
1399 .policy = nft_table_policy,
1400 },
1401 [NFT_MSG_GETTABLE] = {
1402 .call = nf_tables_gettable,
1403 .attr_count = NFTA_TABLE_MAX,
1404 .policy = nft_table_policy,
1405 },
1406 [NFT_MSG_DELTABLE] = {
1407 .call = nf_tables_deltable,
1408 .attr_count = NFTA_TABLE_MAX,
1409 .policy = nft_table_policy,
1410 },
1411 [NFT_MSG_NEWCHAIN] = {
1412 .call = nf_tables_newchain,
1413 .attr_count = NFTA_CHAIN_MAX,
1414 .policy = nft_chain_policy,
1415 },
1416 [NFT_MSG_GETCHAIN] = {
1417 .call = nf_tables_getchain,
1418 .attr_count = NFTA_CHAIN_MAX,
1419 .policy = nft_chain_policy,
1420 },
1421 [NFT_MSG_DELCHAIN] = {
1422 .call = nf_tables_delchain,
1423 .attr_count = NFTA_CHAIN_MAX,
1424 .policy = nft_chain_policy,
1425 },
1426 [NFT_MSG_NEWRULE] = {
1427 .call = nf_tables_newrule,
1428 .attr_count = NFTA_RULE_MAX,
1429 .policy = nft_rule_policy,
1430 },
1431 [NFT_MSG_GETRULE] = {
1432 .call = nf_tables_getrule,
1433 .attr_count = NFTA_RULE_MAX,
1434 .policy = nft_rule_policy,
1435 },
1436 [NFT_MSG_DELRULE] = {
1437 .call = nf_tables_delrule,
1438 .attr_count = NFTA_RULE_MAX,
1439 .policy = nft_rule_policy,
1440 },
1441};
1442
1443static const struct nfnetlink_subsystem nf_tables_subsys = {
1444 .name = "nf_tables",
1445 .subsys_id = NFNL_SUBSYS_NFTABLES,
1446 .cb_count = NFT_MSG_MAX,
1447 .cb = nf_tables_cb,
1448};
1449
1450/**
1451 * nft_validate_input_register - validate an expressions' input register
1452 *
1453 * @reg: the register number
1454 *
1455 * Validate that the input register is one of the general purpose
1456 * registers.
1457 */
1458int nft_validate_input_register(enum nft_registers reg)
1459{
1460 if (reg <= NFT_REG_VERDICT)
1461 return -EINVAL;
1462 if (reg > NFT_REG_MAX)
1463 return -ERANGE;
1464 return 0;
1465}
1466EXPORT_SYMBOL_GPL(nft_validate_input_register);
1467
1468/**
1469 * nft_validate_output_register - validate an expressions' output register
1470 *
1471 * @reg: the register number
1472 *
1473 * Validate that the output register is one of the general purpose
1474 * registers or the verdict register.
1475 */
1476int nft_validate_output_register(enum nft_registers reg)
1477{
1478 if (reg < NFT_REG_VERDICT)
1479 return -EINVAL;
1480 if (reg > NFT_REG_MAX)
1481 return -ERANGE;
1482 return 0;
1483}
1484EXPORT_SYMBOL_GPL(nft_validate_output_register);
1485
1486/**
1487 * nft_validate_data_load - validate an expressions' data load
1488 *
1489 * @ctx: context of the expression performing the load
1490 * @reg: the destination register number
1491 * @data: the data to load
1492 * @type: the data type
1493 *
1494 * Validate that a data load uses the appropriate data type for
1495 * the destination register. A value of NULL for the data means
1496 * that its runtime gathered data, which is always of type
1497 * NFT_DATA_VALUE.
1498 */
1499int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
1500 const struct nft_data *data,
1501 enum nft_data_types type)
1502{
1503 switch (reg) {
1504 case NFT_REG_VERDICT:
1505 if (data == NULL || type != NFT_DATA_VERDICT)
1506 return -EINVAL;
1507 // FIXME: do loop detection
1508 return 0;
1509 default:
1510 if (data != NULL && type != NFT_DATA_VALUE)
1511 return -EINVAL;
1512 return 0;
1513 }
1514}
1515EXPORT_SYMBOL_GPL(nft_validate_data_load);
1516
1517static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
1518 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
1519 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
1520 .len = NFT_CHAIN_MAXNAMELEN - 1 },
1521};
1522
1523static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
1524 struct nft_data_desc *desc, const struct nlattr *nla)
1525{
1526 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
1527 struct nft_chain *chain;
1528 int err;
1529
1530 err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy);
1531 if (err < 0)
1532 return err;
1533
1534 if (!tb[NFTA_VERDICT_CODE])
1535 return -EINVAL;
1536 data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
1537
1538 switch (data->verdict) {
1539 case NF_ACCEPT:
1540 case NF_DROP:
1541 case NF_QUEUE:
1542 case NFT_CONTINUE:
1543 case NFT_BREAK:
1544 case NFT_RETURN:
1545 desc->len = sizeof(data->verdict);
1546 break;
1547 case NFT_JUMP:
1548 case NFT_GOTO:
1549 if (!tb[NFTA_VERDICT_CHAIN])
1550 return -EINVAL;
1551 chain = nf_tables_chain_lookup(ctx->table,
1552 tb[NFTA_VERDICT_CHAIN]);
1553 if (IS_ERR(chain))
1554 return PTR_ERR(chain);
1555 if (chain->flags & NFT_BASE_CHAIN)
1556 return -EOPNOTSUPP;
1557
1558 if (ctx->chain->level + 1 > chain->level) {
1559 if (ctx->chain->level + 1 == 16)
1560 return -EMLINK;
1561 chain->level = ctx->chain->level + 1;
1562 }
1563 chain->use++;
1564 data->chain = chain;
1565 desc->len = sizeof(data);
1566 break;
1567 default:
1568 return -EINVAL;
1569 }
1570
1571 desc->type = NFT_DATA_VERDICT;
1572 return 0;
1573}
1574
1575static void nft_verdict_uninit(const struct nft_data *data)
1576{
1577 switch (data->verdict) {
1578 case NFT_JUMP:
1579 case NFT_GOTO:
1580 data->chain->use--;
1581 break;
1582 }
1583}
1584
1585static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data)
1586{
1587 struct nlattr *nest;
1588
1589 nest = nla_nest_start(skb, NFTA_DATA_VERDICT);
1590 if (!nest)
1591 goto nla_put_failure;
1592
1593 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict)))
1594 goto nla_put_failure;
1595
1596 switch (data->verdict) {
1597 case NFT_JUMP:
1598 case NFT_GOTO:
1599 if (nla_put_string(skb, NFTA_VERDICT_CHAIN, data->chain->name))
1600 goto nla_put_failure;
1601 }
1602 nla_nest_end(skb, nest);
1603 return 0;
1604
1605nla_put_failure:
1606 return -1;
1607}
1608
1609static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
1610 struct nft_data_desc *desc, const struct nlattr *nla)
1611{
1612 unsigned int len;
1613
1614 len = nla_len(nla);
1615 if (len == 0)
1616 return -EINVAL;
1617 if (len > sizeof(data->data))
1618 return -EOVERFLOW;
1619
1620 nla_memcpy(data->data, nla, sizeof(data->data));
1621 desc->type = NFT_DATA_VALUE;
1622 desc->len = len;
1623 return 0;
1624}
1625
1626static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
1627 unsigned int len)
1628{
1629 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
1630}
1631
1632static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
1633 [NFTA_DATA_VALUE] = { .type = NLA_BINARY,
1634 .len = FIELD_SIZEOF(struct nft_data, data) },
1635 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
1636};
1637
1638/**
1639 * nft_data_init - parse nf_tables data netlink attributes
1640 *
1641 * @ctx: context of the expression using the data
1642 * @data: destination struct nft_data
1643 * @desc: data description
1644 * @nla: netlink attribute containing data
1645 *
1646 * Parse the netlink data attributes and initialize a struct nft_data.
1647 * The type and length of data are returned in the data description.
1648 *
1649 * The caller can indicate that it only wants to accept data of type
1650 * NFT_DATA_VALUE by passing NULL for the ctx argument.
1651 */
1652int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
1653 struct nft_data_desc *desc, const struct nlattr *nla)
1654{
1655 struct nlattr *tb[NFTA_DATA_MAX + 1];
1656 int err;
1657
1658 err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy);
1659 if (err < 0)
1660 return err;
1661
1662 if (tb[NFTA_DATA_VALUE])
1663 return nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]);
1664 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
1665 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
1666 return -EINVAL;
1667}
1668EXPORT_SYMBOL_GPL(nft_data_init);
1669
1670/**
1671 * nft_data_uninit - release a nft_data item
1672 *
1673 * @data: struct nft_data to release
1674 * @type: type of data
1675 *
1676 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
1677 * all others need to be released by calling this function.
1678 */
1679void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
1680{
1681 switch (type) {
1682 case NFT_DATA_VALUE:
1683 return;
1684 case NFT_DATA_VERDICT:
1685 return nft_verdict_uninit(data);
1686 default:
1687 WARN_ON(1);
1688 }
1689}
1690EXPORT_SYMBOL_GPL(nft_data_uninit);
1691
1692int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
1693 enum nft_data_types type, unsigned int len)
1694{
1695 struct nlattr *nest;
1696 int err;
1697
1698 nest = nla_nest_start(skb, attr);
1699 if (nest == NULL)
1700 return -1;
1701
1702 switch (type) {
1703 case NFT_DATA_VALUE:
1704 err = nft_value_dump(skb, data, len);
1705 break;
1706 case NFT_DATA_VERDICT:
1707 err = nft_verdict_dump(skb, data);
1708 break;
1709 default:
1710 err = -EINVAL;
1711 WARN_ON(1);
1712 }
1713
1714 nla_nest_end(skb, nest);
1715 return err;
1716}
1717EXPORT_SYMBOL_GPL(nft_data_dump);
1718
1719static int __init nf_tables_module_init(void)
1720{
1721 int err;
1722
1723 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
1724 GFP_KERNEL);
1725 if (info == NULL) {
1726 err = -ENOMEM;
1727 goto err1;
1728 }
1729
1730 err = nf_tables_core_module_init();
1731 if (err < 0)
1732 goto err2;
1733
1734 err = nfnetlink_subsys_register(&nf_tables_subsys);
1735 if (err < 0)
1736 goto err3;
1737
1738 pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
1739 return 0;
1740err3:
1741 nf_tables_core_module_exit();
1742err2:
1743 kfree(info);
1744err1:
1745 return err;
1746}
1747
1748static void __exit nf_tables_module_exit(void)
1749{
1750 nfnetlink_subsys_unregister(&nf_tables_subsys);
1751 nf_tables_core_module_exit();
1752 kfree(info);
1753}
1754
1755module_init(nf_tables_module_init);
1756module_exit(nf_tables_module_exit);
1757
1758MODULE_LICENSE("GPL");
1759MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
1760MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);