]> git.karo-electronics.de Git - karo-tx-linux.git/blob - net/netfilter/nf_tables_api.c
7d59c89c6c754a6be422a469479b7ad4a6c967d8
[karo-tx-linux.git] / net / netfilter / nf_tables_api.c
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
23 static LIST_HEAD(nf_tables_afinfo);
24 static 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  */
34 int 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 }
42 EXPORT_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  */
51 void 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 }
57 EXPORT_SYMBOL_GPL(nft_unregister_afinfo);
58
59 static 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
70 static 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
94 static 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
106 static 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
132 static inline u64 nf_tables_alloc_handle(struct nft_table *table)
133 {
134         return ++table->hgenerator;
135 }
136
137 static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
138         [NFTA_TABLE_NAME]       = { .type = NLA_STRING },
139 };
140
141 static 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
163 nla_put_failure:
164         nlmsg_trim(skb, nlh);
165         return -1;
166 }
167
168 static 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);
198 err:
199         if (err < 0)
200                 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
201         return err;
202 }
203
204 static 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;
230 cont:
231                         idx++;
232                 }
233         }
234 done:
235         cb->args[0] = idx;
236         return skb->len;
237 }
238
239 static 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
277 err:
278         kfree_skb(skb2);
279         return err;
280 }
281
282 static 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
324 static 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
353 static 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
366 static 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  */
381 int 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);
389 again:
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;
418 err:
419         nfnl_unlock(NFNL_SUBSYS_NFTABLES);
420         return err;
421 }
422 EXPORT_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  */
432 void 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 }
444 EXPORT_SYMBOL_GPL(nft_unregister_table);
445
446 /*
447  * Chains
448  */
449
450 static struct nft_chain *
451 nf_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
463 static 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
479 static 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
487 static 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
492 static 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
531 nla_put_failure:
532         nlmsg_trim(skb, nlh);
533         return -1;
534 }
535
536 static 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);
567 err:
568         if (err < 0)
569                 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
570         return err;
571 }
572
573 static 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;
600 cont:
601                                 idx++;
602                         }
603                 }
604         }
605 done:
606         cb->args[0] = idx;
607         return skb->len;
608 }
609
610
611 static 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
654 err:
655         kfree_skb(skb2);
656         return err;
657 }
658
659 static 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++;
762 notify:
763         nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_NEWCHAIN,
764                                family);
765         return 0;
766 }
767
768 static 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
780 static 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
822 static 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  */
843 int 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 }
850 EXPORT_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  */
858 void 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 }
864 EXPORT_SYMBOL_GPL(nft_unregister_expr);
865
866 static 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
877 static 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
901 static 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
906 static 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
923 nla_put_failure:
924         return -1;
925 };
926
927 struct nft_expr_info {
928         const struct nft_expr_ops       *ops;
929         struct nlattr                   *tb[NFTA_EXPR_MAX + 1];
930 };
931
932 static 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
949 static 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
977 err1:
978         expr->ops = NULL;
979         return err;
980 }
981
982 static 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
993 static 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
1007 static 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
1016 static 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
1024 static 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
1068 nla_put_failure:
1069         nlmsg_trim(skb, nlh);
1070         return -1;
1071 }
1072
1073 static 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);
1105 err:
1106         if (err < 0)
1107                 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
1108         return err;
1109 }
1110
1111 static 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;
1140 cont:
1141                                         idx++;
1142                                 }
1143                         }
1144                 }
1145         }
1146 done:
1147         cb->args[0] = idx;
1148         return skb->len;
1149 }
1150
1151 static 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
1199 err:
1200         kfree_skb(skb2);
1201         return err;
1202 }
1203
1204 static 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
1221 static 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
1228 static struct nft_expr_info *info;
1229
1230 static 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
1333 err2:
1334         nf_tables_rule_destroy(rule);
1335 err1:
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
1343 static 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
1395 static 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
1443 static 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  */
1458 int 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 }
1466 EXPORT_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  */
1476 int 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 }
1484 EXPORT_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  */
1499 int 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 }
1515 EXPORT_SYMBOL_GPL(nft_validate_data_load);
1516
1517 static 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
1523 static 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
1575 static 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
1585 static 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
1605 nla_put_failure:
1606         return -1;
1607 }
1608
1609 static 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
1626 static 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
1632 static 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  */
1652 int 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 }
1668 EXPORT_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  */
1679 void 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 }
1690 EXPORT_SYMBOL_GPL(nft_data_uninit);
1691
1692 int 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 }
1717 EXPORT_SYMBOL_GPL(nft_data_dump);
1718
1719 static 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;
1740 err3:
1741         nf_tables_core_module_exit();
1742 err2:
1743         kfree(info);
1744 err1:
1745         return err;
1746 }
1747
1748 static 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
1755 module_init(nf_tables_module_init);
1756 module_exit(nf_tables_module_exit);
1757
1758 MODULE_LICENSE("GPL");
1759 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
1760 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);