x86/smpboot: Init apic mapping before usage
[cascardo/linux.git] / net / netfilter / nft_compat.c
1 /*
2  * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
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  * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/netlink.h>
15 #include <linux/netfilter.h>
16 #include <linux/netfilter/nfnetlink.h>
17 #include <linux/netfilter/nf_tables.h>
18 #include <linux/netfilter/nf_tables_compat.h>
19 #include <linux/netfilter/x_tables.h>
20 #include <linux/netfilter_ipv4/ip_tables.h>
21 #include <linux/netfilter_ipv6/ip6_tables.h>
22 #include <linux/netfilter_bridge/ebtables.h>
23 #include <linux/netfilter_arp/arp_tables.h>
24 #include <net/netfilter/nf_tables.h>
25
26 struct nft_xt {
27         struct list_head        head;
28         struct nft_expr_ops     ops;
29         unsigned int            refcnt;
30 };
31
32 static void nft_xt_put(struct nft_xt *xt)
33 {
34         if (--xt->refcnt == 0) {
35                 list_del(&xt->head);
36                 kfree(xt);
37         }
38 }
39
40 static int nft_compat_chain_validate_dependency(const char *tablename,
41                                                 const struct nft_chain *chain)
42 {
43         const struct nft_base_chain *basechain;
44
45         if (!tablename || !(chain->flags & NFT_BASE_CHAIN))
46                 return 0;
47
48         basechain = nft_base_chain(chain);
49         if (strcmp(tablename, "nat") == 0 &&
50             basechain->type->type != NFT_CHAIN_T_NAT)
51                 return -EINVAL;
52
53         return 0;
54 }
55
56 union nft_entry {
57         struct ipt_entry e4;
58         struct ip6t_entry e6;
59         struct ebt_entry ebt;
60         struct arpt_entry arp;
61 };
62
63 static inline void
64 nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
65 {
66         par->target     = xt;
67         par->targinfo   = xt_info;
68         par->hotdrop    = false;
69 }
70
71 static void nft_target_eval_xt(const struct nft_expr *expr,
72                                struct nft_regs *regs,
73                                const struct nft_pktinfo *pkt)
74 {
75         void *info = nft_expr_priv(expr);
76         struct xt_target *target = expr->ops->data;
77         struct sk_buff *skb = pkt->skb;
78         int ret;
79
80         nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info);
81
82         ret = target->target(skb, &pkt->xt);
83
84         if (pkt->xt.hotdrop)
85                 ret = NF_DROP;
86
87         switch (ret) {
88         case XT_CONTINUE:
89                 regs->verdict.code = NFT_CONTINUE;
90                 break;
91         default:
92                 regs->verdict.code = ret;
93                 break;
94         }
95 }
96
97 static void nft_target_eval_bridge(const struct nft_expr *expr,
98                                    struct nft_regs *regs,
99                                    const struct nft_pktinfo *pkt)
100 {
101         void *info = nft_expr_priv(expr);
102         struct xt_target *target = expr->ops->data;
103         struct sk_buff *skb = pkt->skb;
104         int ret;
105
106         nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info);
107
108         ret = target->target(skb, &pkt->xt);
109
110         if (pkt->xt.hotdrop)
111                 ret = NF_DROP;
112
113         switch (ret) {
114         case EBT_ACCEPT:
115                 regs->verdict.code = NF_ACCEPT;
116                 break;
117         case EBT_DROP:
118                 regs->verdict.code = NF_DROP;
119                 break;
120         case EBT_CONTINUE:
121                 regs->verdict.code = NFT_CONTINUE;
122                 break;
123         case EBT_RETURN:
124                 regs->verdict.code = NFT_RETURN;
125                 break;
126         default:
127                 regs->verdict.code = ret;
128                 break;
129         }
130 }
131
132 static const struct nla_policy nft_target_policy[NFTA_TARGET_MAX + 1] = {
133         [NFTA_TARGET_NAME]      = { .type = NLA_NUL_STRING },
134         [NFTA_TARGET_REV]       = { .type = NLA_U32 },
135         [NFTA_TARGET_INFO]      = { .type = NLA_BINARY },
136 };
137
138 static void
139 nft_target_set_tgchk_param(struct xt_tgchk_param *par,
140                            const struct nft_ctx *ctx,
141                            struct xt_target *target, void *info,
142                            union nft_entry *entry, u16 proto, bool inv)
143 {
144         par->net        = ctx->net;
145         par->table      = ctx->table->name;
146         switch (ctx->afi->family) {
147         case AF_INET:
148                 entry->e4.ip.proto = proto;
149                 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
150                 break;
151         case AF_INET6:
152                 if (proto)
153                         entry->e6.ipv6.flags |= IP6T_F_PROTO;
154
155                 entry->e6.ipv6.proto = proto;
156                 entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
157                 break;
158         case NFPROTO_BRIDGE:
159                 entry->ebt.ethproto = (__force __be16)proto;
160                 entry->ebt.invflags = inv ? EBT_IPROTO : 0;
161                 break;
162         case NFPROTO_ARP:
163                 break;
164         }
165         par->entryinfo  = entry;
166         par->target     = target;
167         par->targinfo   = info;
168         if (ctx->chain->flags & NFT_BASE_CHAIN) {
169                 const struct nft_base_chain *basechain =
170                                                 nft_base_chain(ctx->chain);
171                 const struct nf_hook_ops *ops = &basechain->ops[0];
172
173                 par->hook_mask = 1 << ops->hooknum;
174         } else {
175                 par->hook_mask = 0;
176         }
177         par->family     = ctx->afi->family;
178         par->nft_compat = true;
179 }
180
181 static void target_compat_from_user(struct xt_target *t, void *in, void *out)
182 {
183         int pad;
184
185         memcpy(out, in, t->targetsize);
186         pad = XT_ALIGN(t->targetsize) - t->targetsize;
187         if (pad > 0)
188                 memset(out + t->targetsize, 0, pad);
189 }
190
191 static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] = {
192         [NFTA_RULE_COMPAT_PROTO]        = { .type = NLA_U32 },
193         [NFTA_RULE_COMPAT_FLAGS]        = { .type = NLA_U32 },
194 };
195
196 static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
197 {
198         struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
199         u32 flags;
200         int err;
201
202         err = nla_parse_nested(tb, NFTA_RULE_COMPAT_MAX, attr,
203                                nft_rule_compat_policy);
204         if (err < 0)
205                 return err;
206
207         if (!tb[NFTA_RULE_COMPAT_PROTO] || !tb[NFTA_RULE_COMPAT_FLAGS])
208                 return -EINVAL;
209
210         flags = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_FLAGS]));
211         if (flags & ~NFT_RULE_COMPAT_F_MASK)
212                 return -EINVAL;
213         if (flags & NFT_RULE_COMPAT_F_INV)
214                 *inv = true;
215
216         *proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO]));
217         return 0;
218 }
219
220 static int
221 nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
222                 const struct nlattr * const tb[])
223 {
224         void *info = nft_expr_priv(expr);
225         struct xt_target *target = expr->ops->data;
226         struct xt_tgchk_param par;
227         size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO]));
228         u16 proto = 0;
229         bool inv = false;
230         union nft_entry e = {};
231         int ret;
232
233         ret = nft_compat_chain_validate_dependency(target->table, ctx->chain);
234         if (ret < 0)
235                 goto err;
236
237         target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
238
239         if (ctx->nla[NFTA_RULE_COMPAT]) {
240                 ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
241                 if (ret < 0)
242                         goto err;
243         }
244
245         nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv);
246
247         ret = xt_check_target(&par, size, proto, inv);
248         if (ret < 0)
249                 goto err;
250
251         /* The standard target cannot be used */
252         if (target->target == NULL) {
253                 ret = -EINVAL;
254                 goto err;
255         }
256
257         return 0;
258 err:
259         module_put(target->me);
260         return ret;
261 }
262
263 static void
264 nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
265 {
266         struct xt_target *target = expr->ops->data;
267         void *info = nft_expr_priv(expr);
268         struct xt_tgdtor_param par;
269
270         par.net = ctx->net;
271         par.target = target;
272         par.targinfo = info;
273         par.family = ctx->afi->family;
274         if (par.target->destroy != NULL)
275                 par.target->destroy(&par);
276
277         nft_xt_put(container_of(expr->ops, struct nft_xt, ops));
278         module_put(target->me);
279 }
280
281 static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr)
282 {
283         const struct xt_target *target = expr->ops->data;
284         void *info = nft_expr_priv(expr);
285
286         if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) ||
287             nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) ||
288             nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(target->targetsize), info))
289                 goto nla_put_failure;
290
291         return 0;
292
293 nla_put_failure:
294         return -1;
295 }
296
297 static int nft_target_validate(const struct nft_ctx *ctx,
298                                const struct nft_expr *expr,
299                                const struct nft_data **data)
300 {
301         struct xt_target *target = expr->ops->data;
302         unsigned int hook_mask = 0;
303         int ret;
304
305         if (ctx->chain->flags & NFT_BASE_CHAIN) {
306                 const struct nft_base_chain *basechain =
307                                                 nft_base_chain(ctx->chain);
308                 const struct nf_hook_ops *ops = &basechain->ops[0];
309
310                 hook_mask = 1 << ops->hooknum;
311                 if (!(hook_mask & target->hooks))
312                         return -EINVAL;
313
314                 ret = nft_compat_chain_validate_dependency(target->table,
315                                                            ctx->chain);
316                 if (ret < 0)
317                         return ret;
318         }
319         return 0;
320 }
321
322 static void nft_match_eval(const struct nft_expr *expr,
323                            struct nft_regs *regs,
324                            const struct nft_pktinfo *pkt)
325 {
326         void *info = nft_expr_priv(expr);
327         struct xt_match *match = expr->ops->data;
328         struct sk_buff *skb = pkt->skb;
329         bool ret;
330
331         nft_compat_set_par((struct xt_action_param *)&pkt->xt, match, info);
332
333         ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
334
335         if (pkt->xt.hotdrop) {
336                 regs->verdict.code = NF_DROP;
337                 return;
338         }
339
340         switch (ret ? 1 : 0) {
341         case 1:
342                 regs->verdict.code = NFT_CONTINUE;
343                 break;
344         case 0:
345                 regs->verdict.code = NFT_BREAK;
346                 break;
347         }
348 }
349
350 static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = {
351         [NFTA_MATCH_NAME]       = { .type = NLA_NUL_STRING },
352         [NFTA_MATCH_REV]        = { .type = NLA_U32 },
353         [NFTA_MATCH_INFO]       = { .type = NLA_BINARY },
354 };
355
356 /* struct xt_mtchk_param and xt_tgchk_param look very similar */
357 static void
358 nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
359                           struct xt_match *match, void *info,
360                           union nft_entry *entry, u16 proto, bool inv)
361 {
362         par->net        = ctx->net;
363         par->table      = ctx->table->name;
364         switch (ctx->afi->family) {
365         case AF_INET:
366                 entry->e4.ip.proto = proto;
367                 entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
368                 break;
369         case AF_INET6:
370                 if (proto)
371                         entry->e6.ipv6.flags |= IP6T_F_PROTO;
372
373                 entry->e6.ipv6.proto = proto;
374                 entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
375                 break;
376         case NFPROTO_BRIDGE:
377                 entry->ebt.ethproto = (__force __be16)proto;
378                 entry->ebt.invflags = inv ? EBT_IPROTO : 0;
379                 break;
380         case NFPROTO_ARP:
381                 break;
382         }
383         par->entryinfo  = entry;
384         par->match      = match;
385         par->matchinfo  = info;
386         if (ctx->chain->flags & NFT_BASE_CHAIN) {
387                 const struct nft_base_chain *basechain =
388                                                 nft_base_chain(ctx->chain);
389                 const struct nf_hook_ops *ops = &basechain->ops[0];
390
391                 par->hook_mask = 1 << ops->hooknum;
392         } else {
393                 par->hook_mask = 0;
394         }
395         par->family     = ctx->afi->family;
396         par->nft_compat = true;
397 }
398
399 static void match_compat_from_user(struct xt_match *m, void *in, void *out)
400 {
401         int pad;
402
403         memcpy(out, in, m->matchsize);
404         pad = XT_ALIGN(m->matchsize) - m->matchsize;
405         if (pad > 0)
406                 memset(out + m->matchsize, 0, pad);
407 }
408
409 static int
410 nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
411                 const struct nlattr * const tb[])
412 {
413         void *info = nft_expr_priv(expr);
414         struct xt_match *match = expr->ops->data;
415         struct xt_mtchk_param par;
416         size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO]));
417         u16 proto = 0;
418         bool inv = false;
419         union nft_entry e = {};
420         int ret;
421
422         ret = nft_compat_chain_validate_dependency(match->table, ctx->chain);
423         if (ret < 0)
424                 goto err;
425
426         match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
427
428         if (ctx->nla[NFTA_RULE_COMPAT]) {
429                 ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
430                 if (ret < 0)
431                         goto err;
432         }
433
434         nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv);
435
436         ret = xt_check_match(&par, size, proto, inv);
437         if (ret < 0)
438                 goto err;
439
440         return 0;
441 err:
442         module_put(match->me);
443         return ret;
444 }
445
446 static void
447 nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
448 {
449         struct xt_match *match = expr->ops->data;
450         void *info = nft_expr_priv(expr);
451         struct xt_mtdtor_param par;
452
453         par.net = ctx->net;
454         par.match = match;
455         par.matchinfo = info;
456         par.family = ctx->afi->family;
457         if (par.match->destroy != NULL)
458                 par.match->destroy(&par);
459
460         nft_xt_put(container_of(expr->ops, struct nft_xt, ops));
461         module_put(match->me);
462 }
463
464 static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr)
465 {
466         void *info = nft_expr_priv(expr);
467         struct xt_match *match = expr->ops->data;
468
469         if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) ||
470             nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) ||
471             nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(match->matchsize), info))
472                 goto nla_put_failure;
473
474         return 0;
475
476 nla_put_failure:
477         return -1;
478 }
479
480 static int nft_match_validate(const struct nft_ctx *ctx,
481                               const struct nft_expr *expr,
482                               const struct nft_data **data)
483 {
484         struct xt_match *match = expr->ops->data;
485         unsigned int hook_mask = 0;
486         int ret;
487
488         if (ctx->chain->flags & NFT_BASE_CHAIN) {
489                 const struct nft_base_chain *basechain =
490                                                 nft_base_chain(ctx->chain);
491                 const struct nf_hook_ops *ops = &basechain->ops[0];
492
493                 hook_mask = 1 << ops->hooknum;
494                 if (!(hook_mask & match->hooks))
495                         return -EINVAL;
496
497                 ret = nft_compat_chain_validate_dependency(match->table,
498                                                            ctx->chain);
499                 if (ret < 0)
500                         return ret;
501         }
502         return 0;
503 }
504
505 static int
506 nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
507                       int event, u16 family, const char *name,
508                       int rev, int target)
509 {
510         struct nlmsghdr *nlh;
511         struct nfgenmsg *nfmsg;
512         unsigned int flags = portid ? NLM_F_MULTI : 0;
513
514         event |= NFNL_SUBSYS_NFT_COMPAT << 8;
515         nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
516         if (nlh == NULL)
517                 goto nlmsg_failure;
518
519         nfmsg = nlmsg_data(nlh);
520         nfmsg->nfgen_family = family;
521         nfmsg->version = NFNETLINK_V0;
522         nfmsg->res_id = 0;
523
524         if (nla_put_string(skb, NFTA_COMPAT_NAME, name) ||
525             nla_put_be32(skb, NFTA_COMPAT_REV, htonl(rev)) ||
526             nla_put_be32(skb, NFTA_COMPAT_TYPE, htonl(target)))
527                 goto nla_put_failure;
528
529         nlmsg_end(skb, nlh);
530         return skb->len;
531
532 nlmsg_failure:
533 nla_put_failure:
534         nlmsg_cancel(skb, nlh);
535         return -1;
536 }
537
538 static int nfnl_compat_get(struct net *net, struct sock *nfnl,
539                            struct sk_buff *skb, const struct nlmsghdr *nlh,
540                            const struct nlattr * const tb[])
541 {
542         int ret = 0, target;
543         struct nfgenmsg *nfmsg;
544         const char *fmt;
545         const char *name;
546         u32 rev;
547         struct sk_buff *skb2;
548
549         if (tb[NFTA_COMPAT_NAME] == NULL ||
550             tb[NFTA_COMPAT_REV] == NULL ||
551             tb[NFTA_COMPAT_TYPE] == NULL)
552                 return -EINVAL;
553
554         name = nla_data(tb[NFTA_COMPAT_NAME]);
555         rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV]));
556         target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE]));
557
558         nfmsg = nlmsg_data(nlh);
559
560         switch(nfmsg->nfgen_family) {
561         case AF_INET:
562                 fmt = "ipt_%s";
563                 break;
564         case AF_INET6:
565                 fmt = "ip6t_%s";
566                 break;
567         case NFPROTO_BRIDGE:
568                 fmt = "ebt_%s";
569                 break;
570         case NFPROTO_ARP:
571                 fmt = "arpt_%s";
572                 break;
573         default:
574                 pr_err("nft_compat: unsupported protocol %d\n",
575                         nfmsg->nfgen_family);
576                 return -EINVAL;
577         }
578
579         try_then_request_module(xt_find_revision(nfmsg->nfgen_family, name,
580                                                  rev, target, &ret),
581                                                  fmt, name);
582
583         if (ret < 0)
584                 return ret;
585
586         skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
587         if (skb2 == NULL)
588                 return -ENOMEM;
589
590         /* include the best revision for this extension in the message */
591         if (nfnl_compat_fill_info(skb2, NETLINK_CB(skb).portid,
592                                   nlh->nlmsg_seq,
593                                   NFNL_MSG_TYPE(nlh->nlmsg_type),
594                                   NFNL_MSG_COMPAT_GET,
595                                   nfmsg->nfgen_family,
596                                   name, ret, target) <= 0) {
597                 kfree_skb(skb2);
598                 return -ENOSPC;
599         }
600
601         ret = netlink_unicast(nfnl, skb2, NETLINK_CB(skb).portid,
602                                 MSG_DONTWAIT);
603         if (ret > 0)
604                 ret = 0;
605
606         return ret == -EAGAIN ? -ENOBUFS : ret;
607 }
608
609 static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
610         [NFTA_COMPAT_NAME]      = { .type = NLA_NUL_STRING,
611                                     .len = NFT_COMPAT_NAME_MAX-1 },
612         [NFTA_COMPAT_REV]       = { .type = NLA_U32 },
613         [NFTA_COMPAT_TYPE]      = { .type = NLA_U32 },
614 };
615
616 static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = {
617         [NFNL_MSG_COMPAT_GET]           = { .call = nfnl_compat_get,
618                                             .attr_count = NFTA_COMPAT_MAX,
619                                             .policy = nfnl_compat_policy_get },
620 };
621
622 static const struct nfnetlink_subsystem nfnl_compat_subsys = {
623         .name           = "nft-compat",
624         .subsys_id      = NFNL_SUBSYS_NFT_COMPAT,
625         .cb_count       = NFNL_MSG_COMPAT_MAX,
626         .cb             = nfnl_nft_compat_cb,
627 };
628
629 static LIST_HEAD(nft_match_list);
630
631 static struct nft_expr_type nft_match_type;
632
633 static bool nft_match_cmp(const struct xt_match *match,
634                           const char *name, u32 rev, u32 family)
635 {
636         return strcmp(match->name, name) == 0 && match->revision == rev &&
637                (match->family == NFPROTO_UNSPEC || match->family == family);
638 }
639
640 static const struct nft_expr_ops *
641 nft_match_select_ops(const struct nft_ctx *ctx,
642                      const struct nlattr * const tb[])
643 {
644         struct nft_xt *nft_match;
645         struct xt_match *match;
646         char *mt_name;
647         u32 rev, family;
648         int err;
649
650         if (tb[NFTA_MATCH_NAME] == NULL ||
651             tb[NFTA_MATCH_REV] == NULL ||
652             tb[NFTA_MATCH_INFO] == NULL)
653                 return ERR_PTR(-EINVAL);
654
655         mt_name = nla_data(tb[NFTA_MATCH_NAME]);
656         rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV]));
657         family = ctx->afi->family;
658
659         /* Re-use the existing match if it's already loaded. */
660         list_for_each_entry(nft_match, &nft_match_list, head) {
661                 struct xt_match *match = nft_match->ops.data;
662
663                 if (nft_match_cmp(match, mt_name, rev, family)) {
664                         if (!try_module_get(match->me))
665                                 return ERR_PTR(-ENOENT);
666
667                         nft_match->refcnt++;
668                         return &nft_match->ops;
669                 }
670         }
671
672         match = xt_request_find_match(family, mt_name, rev);
673         if (IS_ERR(match))
674                 return ERR_PTR(-ENOENT);
675
676         if (match->matchsize > nla_len(tb[NFTA_MATCH_INFO])) {
677                 err = -EINVAL;
678                 goto err;
679         }
680
681         /* This is the first time we use this match, allocate operations */
682         nft_match = kzalloc(sizeof(struct nft_xt), GFP_KERNEL);
683         if (nft_match == NULL) {
684                 err = -ENOMEM;
685                 goto err;
686         }
687
688         nft_match->refcnt = 1;
689         nft_match->ops.type = &nft_match_type;
690         nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize));
691         nft_match->ops.eval = nft_match_eval;
692         nft_match->ops.init = nft_match_init;
693         nft_match->ops.destroy = nft_match_destroy;
694         nft_match->ops.dump = nft_match_dump;
695         nft_match->ops.validate = nft_match_validate;
696         nft_match->ops.data = match;
697
698         list_add(&nft_match->head, &nft_match_list);
699
700         return &nft_match->ops;
701 err:
702         module_put(match->me);
703         return ERR_PTR(err);
704 }
705
706 static struct nft_expr_type nft_match_type __read_mostly = {
707         .name           = "match",
708         .select_ops     = nft_match_select_ops,
709         .policy         = nft_match_policy,
710         .maxattr        = NFTA_MATCH_MAX,
711         .owner          = THIS_MODULE,
712 };
713
714 static LIST_HEAD(nft_target_list);
715
716 static struct nft_expr_type nft_target_type;
717
718 static bool nft_target_cmp(const struct xt_target *tg,
719                            const char *name, u32 rev, u32 family)
720 {
721         return strcmp(tg->name, name) == 0 && tg->revision == rev &&
722                (tg->family == NFPROTO_UNSPEC || tg->family == family);
723 }
724
725 static const struct nft_expr_ops *
726 nft_target_select_ops(const struct nft_ctx *ctx,
727                       const struct nlattr * const tb[])
728 {
729         struct nft_xt *nft_target;
730         struct xt_target *target;
731         char *tg_name;
732         u32 rev, family;
733         int err;
734
735         if (tb[NFTA_TARGET_NAME] == NULL ||
736             tb[NFTA_TARGET_REV] == NULL ||
737             tb[NFTA_TARGET_INFO] == NULL)
738                 return ERR_PTR(-EINVAL);
739
740         tg_name = nla_data(tb[NFTA_TARGET_NAME]);
741         rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV]));
742         family = ctx->afi->family;
743
744         /* Re-use the existing target if it's already loaded. */
745         list_for_each_entry(nft_target, &nft_target_list, head) {
746                 struct xt_target *target = nft_target->ops.data;
747
748                 if (nft_target_cmp(target, tg_name, rev, family)) {
749                         if (!try_module_get(target->me))
750                                 return ERR_PTR(-ENOENT);
751
752                         nft_target->refcnt++;
753                         return &nft_target->ops;
754                 }
755         }
756
757         target = xt_request_find_target(family, tg_name, rev);
758         if (IS_ERR(target))
759                 return ERR_PTR(-ENOENT);
760
761         if (target->targetsize > nla_len(tb[NFTA_TARGET_INFO])) {
762                 err = -EINVAL;
763                 goto err;
764         }
765
766         /* This is the first time we use this target, allocate operations */
767         nft_target = kzalloc(sizeof(struct nft_xt), GFP_KERNEL);
768         if (nft_target == NULL) {
769                 err = -ENOMEM;
770                 goto err;
771         }
772
773         nft_target->refcnt = 1;
774         nft_target->ops.type = &nft_target_type;
775         nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
776         nft_target->ops.init = nft_target_init;
777         nft_target->ops.destroy = nft_target_destroy;
778         nft_target->ops.dump = nft_target_dump;
779         nft_target->ops.validate = nft_target_validate;
780         nft_target->ops.data = target;
781
782         if (family == NFPROTO_BRIDGE)
783                 nft_target->ops.eval = nft_target_eval_bridge;
784         else
785                 nft_target->ops.eval = nft_target_eval_xt;
786
787         list_add(&nft_target->head, &nft_target_list);
788
789         return &nft_target->ops;
790 err:
791         module_put(target->me);
792         return ERR_PTR(err);
793 }
794
795 static struct nft_expr_type nft_target_type __read_mostly = {
796         .name           = "target",
797         .select_ops     = nft_target_select_ops,
798         .policy         = nft_target_policy,
799         .maxattr        = NFTA_TARGET_MAX,
800         .owner          = THIS_MODULE,
801 };
802
803 static int __init nft_compat_module_init(void)
804 {
805         int ret;
806
807         ret = nft_register_expr(&nft_match_type);
808         if (ret < 0)
809                 return ret;
810
811         ret = nft_register_expr(&nft_target_type);
812         if (ret < 0)
813                 goto err_match;
814
815         ret = nfnetlink_subsys_register(&nfnl_compat_subsys);
816         if (ret < 0) {
817                 pr_err("nft_compat: cannot register with nfnetlink.\n");
818                 goto err_target;
819         }
820
821         pr_info("nf_tables_compat: (c) 2012 Pablo Neira Ayuso <pablo@netfilter.org>\n");
822
823         return ret;
824
825 err_target:
826         nft_unregister_expr(&nft_target_type);
827 err_match:
828         nft_unregister_expr(&nft_match_type);
829         return ret;
830 }
831
832 static void __exit nft_compat_module_exit(void)
833 {
834         nfnetlink_subsys_unregister(&nfnl_compat_subsys);
835         nft_unregister_expr(&nft_target_type);
836         nft_unregister_expr(&nft_match_type);
837 }
838
839 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT);
840
841 module_init(nft_compat_module_init);
842 module_exit(nft_compat_module_exit);
843
844 MODULE_LICENSE("GPL");
845 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
846 MODULE_ALIAS_NFT_EXPR("match");
847 MODULE_ALIAS_NFT_EXPR("target");