2 * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
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.
8 * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
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 #include <net/netns/generic.h>
28 struct list_head head
;
29 struct nft_expr_ops ops
;
32 /* used only when transaction mutex is locked */
35 /* Unlike other expressions, ops doesn't have static storage duration.
36 * nft core assumes they do. We use kfree_rcu so that nft core can
37 * can check expr->ops->size even after nft_compat->destroy() frees
38 * the nft_xt struct that holds the ops structure.
40 struct rcu_head rcu_head
;
43 /* Used for matches where *info is larger than X byte */
44 #define NFT_MATCH_LARGE_THRESH 192
46 struct nft_xt_match_priv
{
50 struct nft_compat_net
{
51 struct list_head nft_target_list
;
52 struct list_head nft_match_list
;
55 static unsigned int nft_compat_net_id __read_mostly
;
56 static struct nft_expr_type nft_match_type
;
57 static struct nft_expr_type nft_target_type
;
59 static struct nft_compat_net
*nft_compat_pernet(struct net
*net
)
61 return net_generic(net
, nft_compat_net_id
);
64 static void nft_xt_get(struct nft_xt
*xt
)
66 /* refcount_inc() warns on 0 -> 1 transition, but we can't
67 * init the reference count to 1 in .select_ops -- we can't
68 * undo such an increase when another expression inside the same
69 * rule fails afterwards.
72 refcount_set(&xt
->refcnt
, 1);
74 refcount_inc(&xt
->refcnt
);
79 static bool nft_xt_put(struct nft_xt
*xt
)
81 if (refcount_dec_and_test(&xt
->refcnt
)) {
82 WARN_ON_ONCE(!list_empty(&xt
->head
));
83 kfree_rcu(xt
, rcu_head
);
90 static int nft_compat_chain_validate_dependency(const struct nft_ctx
*ctx
,
91 const char *tablename
)
93 enum nft_chain_types type
= NFT_CHAIN_T_DEFAULT
;
94 const struct nft_chain
*chain
= ctx
->chain
;
95 const struct nft_base_chain
*basechain
;
98 !nft_is_base_chain(chain
))
101 basechain
= nft_base_chain(chain
);
102 if (strcmp(tablename
, "nat") == 0) {
103 if (ctx
->family
!= NFPROTO_BRIDGE
)
104 type
= NFT_CHAIN_T_NAT
;
105 if (basechain
->type
->type
!= type
)
114 struct ip6t_entry e6
;
115 struct ebt_entry ebt
;
116 struct arpt_entry arp
;
120 nft_compat_set_par(struct xt_action_param
*par
, void *xt
, const void *xt_info
)
123 par
->targinfo
= xt_info
;
124 par
->hotdrop
= false;
127 static void nft_target_eval_xt(const struct nft_expr
*expr
,
128 struct nft_regs
*regs
,
129 const struct nft_pktinfo
*pkt
)
131 void *info
= nft_expr_priv(expr
);
132 struct xt_target
*target
= expr
->ops
->data
;
133 struct sk_buff
*skb
= pkt
->skb
;
136 nft_compat_set_par((struct xt_action_param
*)&pkt
->xt
, target
, info
);
138 ret
= target
->target(skb
, &pkt
->xt
);
145 regs
->verdict
.code
= NFT_CONTINUE
;
148 regs
->verdict
.code
= ret
;
153 static void nft_target_eval_bridge(const struct nft_expr
*expr
,
154 struct nft_regs
*regs
,
155 const struct nft_pktinfo
*pkt
)
157 void *info
= nft_expr_priv(expr
);
158 struct xt_target
*target
= expr
->ops
->data
;
159 struct sk_buff
*skb
= pkt
->skb
;
162 nft_compat_set_par((struct xt_action_param
*)&pkt
->xt
, target
, info
);
164 ret
= target
->target(skb
, &pkt
->xt
);
171 regs
->verdict
.code
= NF_ACCEPT
;
174 regs
->verdict
.code
= NF_DROP
;
177 regs
->verdict
.code
= NFT_CONTINUE
;
180 regs
->verdict
.code
= NFT_RETURN
;
183 regs
->verdict
.code
= ret
;
188 static const struct nla_policy nft_target_policy
[NFTA_TARGET_MAX
+ 1] = {
189 [NFTA_TARGET_NAME
] = { .type
= NLA_NUL_STRING
},
190 [NFTA_TARGET_REV
] = { .type
= NLA_U32
},
191 [NFTA_TARGET_INFO
] = { .type
= NLA_BINARY
},
195 nft_target_set_tgchk_param(struct xt_tgchk_param
*par
,
196 const struct nft_ctx
*ctx
,
197 struct xt_target
*target
, void *info
,
198 union nft_entry
*entry
, u16 proto
, bool inv
)
201 par
->table
= ctx
->table
->name
;
202 switch (ctx
->family
) {
204 entry
->e4
.ip
.proto
= proto
;
205 entry
->e4
.ip
.invflags
= inv
? IPT_INV_PROTO
: 0;
209 entry
->e6
.ipv6
.flags
|= IP6T_F_PROTO
;
211 entry
->e6
.ipv6
.proto
= proto
;
212 entry
->e6
.ipv6
.invflags
= inv
? IP6T_INV_PROTO
: 0;
215 entry
->ebt
.ethproto
= (__force __be16
)proto
;
216 entry
->ebt
.invflags
= inv
? EBT_IPROTO
: 0;
221 par
->entryinfo
= entry
;
222 par
->target
= target
;
223 par
->targinfo
= info
;
224 if (nft_is_base_chain(ctx
->chain
)) {
225 const struct nft_base_chain
*basechain
=
226 nft_base_chain(ctx
->chain
);
227 const struct nf_hook_ops
*ops
= &basechain
->ops
;
229 par
->hook_mask
= 1 << ops
->hooknum
;
233 par
->family
= ctx
->family
;
234 par
->nft_compat
= true;
237 static void target_compat_from_user(struct xt_target
*t
, void *in
, void *out
)
241 memcpy(out
, in
, t
->targetsize
);
242 pad
= XT_ALIGN(t
->targetsize
) - t
->targetsize
;
244 memset(out
+ t
->targetsize
, 0, pad
);
247 static const struct nla_policy nft_rule_compat_policy
[NFTA_RULE_COMPAT_MAX
+ 1] = {
248 [NFTA_RULE_COMPAT_PROTO
] = { .type
= NLA_U32
},
249 [NFTA_RULE_COMPAT_FLAGS
] = { .type
= NLA_U32
},
252 static int nft_parse_compat(const struct nlattr
*attr
, u16
*proto
, bool *inv
)
254 struct nlattr
*tb
[NFTA_RULE_COMPAT_MAX
+1];
258 err
= nla_parse_nested(tb
, NFTA_RULE_COMPAT_MAX
, attr
,
259 nft_rule_compat_policy
, NULL
);
263 if (!tb
[NFTA_RULE_COMPAT_PROTO
] || !tb
[NFTA_RULE_COMPAT_FLAGS
])
266 flags
= ntohl(nla_get_be32(tb
[NFTA_RULE_COMPAT_FLAGS
]));
267 if (flags
& ~NFT_RULE_COMPAT_F_MASK
)
269 if (flags
& NFT_RULE_COMPAT_F_INV
)
272 *proto
= ntohl(nla_get_be32(tb
[NFTA_RULE_COMPAT_PROTO
]));
277 nft_target_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
278 const struct nlattr
* const tb
[])
280 void *info
= nft_expr_priv(expr
);
281 struct xt_target
*target
= expr
->ops
->data
;
282 struct xt_tgchk_param par
;
283 size_t size
= XT_ALIGN(nla_len(tb
[NFTA_TARGET_INFO
]));
284 struct nft_xt
*nft_xt
;
287 union nft_entry e
= {};
290 target_compat_from_user(target
, nla_data(tb
[NFTA_TARGET_INFO
]), info
);
292 if (ctx
->nla
[NFTA_RULE_COMPAT
]) {
293 ret
= nft_parse_compat(ctx
->nla
[NFTA_RULE_COMPAT
], &proto
, &inv
);
298 nft_target_set_tgchk_param(&par
, ctx
, target
, info
, &e
, proto
, inv
);
300 ret
= xt_check_target(&par
, size
, proto
, inv
);
304 /* The standard target cannot be used */
308 nft_xt
= container_of(expr
->ops
, struct nft_xt
, ops
);
314 nft_target_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
)
316 struct xt_target
*target
= expr
->ops
->data
;
317 void *info
= nft_expr_priv(expr
);
318 struct xt_tgdtor_param par
;
323 par
.family
= ctx
->family
;
324 if (par
.target
->destroy
!= NULL
)
325 par
.target
->destroy(&par
);
327 if (nft_xt_put(container_of(expr
->ops
, struct nft_xt
, ops
)))
328 module_put(target
->me
);
331 static int nft_extension_dump_info(struct sk_buff
*skb
, int attr
,
333 unsigned int size
, unsigned int user_size
)
335 unsigned int info_size
, aligned_size
= XT_ALIGN(size
);
338 nla
= nla_reserve(skb
, attr
, aligned_size
);
342 info_size
= user_size
? : size
;
343 memcpy(nla_data(nla
), info
, info_size
);
344 memset(nla_data(nla
) + info_size
, 0, aligned_size
- info_size
);
349 static int nft_target_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
)
351 const struct xt_target
*target
= expr
->ops
->data
;
352 void *info
= nft_expr_priv(expr
);
354 if (nla_put_string(skb
, NFTA_TARGET_NAME
, target
->name
) ||
355 nla_put_be32(skb
, NFTA_TARGET_REV
, htonl(target
->revision
)) ||
356 nft_extension_dump_info(skb
, NFTA_TARGET_INFO
, info
,
357 target
->targetsize
, target
->usersize
))
358 goto nla_put_failure
;
366 static int nft_target_validate(const struct nft_ctx
*ctx
,
367 const struct nft_expr
*expr
,
368 const struct nft_data
**data
)
370 struct xt_target
*target
= expr
->ops
->data
;
371 unsigned int hook_mask
= 0;
374 if (nft_is_base_chain(ctx
->chain
)) {
375 const struct nft_base_chain
*basechain
=
376 nft_base_chain(ctx
->chain
);
377 const struct nf_hook_ops
*ops
= &basechain
->ops
;
379 hook_mask
= 1 << ops
->hooknum
;
380 if (target
->hooks
&& !(hook_mask
& target
->hooks
))
383 ret
= nft_compat_chain_validate_dependency(ctx
, target
->table
);
390 static void __nft_match_eval(const struct nft_expr
*expr
,
391 struct nft_regs
*regs
,
392 const struct nft_pktinfo
*pkt
,
395 struct xt_match
*match
= expr
->ops
->data
;
396 struct sk_buff
*skb
= pkt
->skb
;
399 nft_compat_set_par((struct xt_action_param
*)&pkt
->xt
, match
, info
);
401 ret
= match
->match(skb
, (struct xt_action_param
*)&pkt
->xt
);
403 if (pkt
->xt
.hotdrop
) {
404 regs
->verdict
.code
= NF_DROP
;
408 switch (ret
? 1 : 0) {
410 regs
->verdict
.code
= NFT_CONTINUE
;
413 regs
->verdict
.code
= NFT_BREAK
;
418 static void nft_match_large_eval(const struct nft_expr
*expr
,
419 struct nft_regs
*regs
,
420 const struct nft_pktinfo
*pkt
)
422 struct nft_xt_match_priv
*priv
= nft_expr_priv(expr
);
424 __nft_match_eval(expr
, regs
, pkt
, priv
->info
);
427 static void nft_match_eval(const struct nft_expr
*expr
,
428 struct nft_regs
*regs
,
429 const struct nft_pktinfo
*pkt
)
431 __nft_match_eval(expr
, regs
, pkt
, nft_expr_priv(expr
));
434 static const struct nla_policy nft_match_policy
[NFTA_MATCH_MAX
+ 1] = {
435 [NFTA_MATCH_NAME
] = { .type
= NLA_NUL_STRING
},
436 [NFTA_MATCH_REV
] = { .type
= NLA_U32
},
437 [NFTA_MATCH_INFO
] = { .type
= NLA_BINARY
},
440 /* struct xt_mtchk_param and xt_tgchk_param look very similar */
442 nft_match_set_mtchk_param(struct xt_mtchk_param
*par
, const struct nft_ctx
*ctx
,
443 struct xt_match
*match
, void *info
,
444 union nft_entry
*entry
, u16 proto
, bool inv
)
447 par
->table
= ctx
->table
->name
;
448 switch (ctx
->family
) {
450 entry
->e4
.ip
.proto
= proto
;
451 entry
->e4
.ip
.invflags
= inv
? IPT_INV_PROTO
: 0;
455 entry
->e6
.ipv6
.flags
|= IP6T_F_PROTO
;
457 entry
->e6
.ipv6
.proto
= proto
;
458 entry
->e6
.ipv6
.invflags
= inv
? IP6T_INV_PROTO
: 0;
461 entry
->ebt
.ethproto
= (__force __be16
)proto
;
462 entry
->ebt
.invflags
= inv
? EBT_IPROTO
: 0;
467 par
->entryinfo
= entry
;
469 par
->matchinfo
= info
;
470 if (nft_is_base_chain(ctx
->chain
)) {
471 const struct nft_base_chain
*basechain
=
472 nft_base_chain(ctx
->chain
);
473 const struct nf_hook_ops
*ops
= &basechain
->ops
;
475 par
->hook_mask
= 1 << ops
->hooknum
;
479 par
->family
= ctx
->family
;
480 par
->nft_compat
= true;
483 static void match_compat_from_user(struct xt_match
*m
, void *in
, void *out
)
487 memcpy(out
, in
, m
->matchsize
);
488 pad
= XT_ALIGN(m
->matchsize
) - m
->matchsize
;
490 memset(out
+ m
->matchsize
, 0, pad
);
494 __nft_match_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
495 const struct nlattr
* const tb
[],
498 struct xt_match
*match
= expr
->ops
->data
;
499 struct xt_mtchk_param par
;
500 size_t size
= XT_ALIGN(nla_len(tb
[NFTA_MATCH_INFO
]));
501 struct nft_xt
*nft_xt
;
504 union nft_entry e
= {};
507 match_compat_from_user(match
, nla_data(tb
[NFTA_MATCH_INFO
]), info
);
509 if (ctx
->nla
[NFTA_RULE_COMPAT
]) {
510 ret
= nft_parse_compat(ctx
->nla
[NFTA_RULE_COMPAT
], &proto
, &inv
);
515 nft_match_set_mtchk_param(&par
, ctx
, match
, info
, &e
, proto
, inv
);
517 ret
= xt_check_match(&par
, size
, proto
, inv
);
521 nft_xt
= container_of(expr
->ops
, struct nft_xt
, ops
);
527 nft_match_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
528 const struct nlattr
* const tb
[])
530 return __nft_match_init(ctx
, expr
, tb
, nft_expr_priv(expr
));
534 nft_match_large_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
535 const struct nlattr
* const tb
[])
537 struct nft_xt_match_priv
*priv
= nft_expr_priv(expr
);
538 struct xt_match
*m
= expr
->ops
->data
;
541 priv
->info
= kmalloc(XT_ALIGN(m
->matchsize
), GFP_KERNEL
);
545 ret
= __nft_match_init(ctx
, expr
, tb
, priv
->info
);
552 __nft_match_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
555 struct xt_match
*match
= expr
->ops
->data
;
556 struct module
*me
= match
->me
;
557 struct xt_mtdtor_param par
;
561 par
.matchinfo
= info
;
562 par
.family
= ctx
->family
;
563 if (par
.match
->destroy
!= NULL
)
564 par
.match
->destroy(&par
);
566 if (nft_xt_put(container_of(expr
->ops
, struct nft_xt
, ops
)))
571 nft_match_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
)
573 __nft_match_destroy(ctx
, expr
, nft_expr_priv(expr
));
576 static void nft_compat_deactivate(const struct nft_ctx
*ctx
,
577 const struct nft_expr
*expr
,
578 enum nft_trans_phase phase
)
580 struct nft_xt
*xt
= container_of(expr
->ops
, struct nft_xt
, ops
);
582 if (phase
== NFT_TRANS_ABORT
|| phase
== NFT_TRANS_COMMIT
) {
583 if (--xt
->listcnt
== 0)
584 list_del_init(&xt
->head
);
589 nft_match_large_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
)
591 struct nft_xt_match_priv
*priv
= nft_expr_priv(expr
);
593 __nft_match_destroy(ctx
, expr
, priv
->info
);
597 static int __nft_match_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
,
600 struct xt_match
*match
= expr
->ops
->data
;
602 if (nla_put_string(skb
, NFTA_MATCH_NAME
, match
->name
) ||
603 nla_put_be32(skb
, NFTA_MATCH_REV
, htonl(match
->revision
)) ||
604 nft_extension_dump_info(skb
, NFTA_MATCH_INFO
, info
,
605 match
->matchsize
, match
->usersize
))
606 goto nla_put_failure
;
614 static int nft_match_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
)
616 return __nft_match_dump(skb
, expr
, nft_expr_priv(expr
));
619 static int nft_match_large_dump(struct sk_buff
*skb
, const struct nft_expr
*e
)
621 struct nft_xt_match_priv
*priv
= nft_expr_priv(e
);
623 return __nft_match_dump(skb
, e
, priv
->info
);
626 static int nft_match_validate(const struct nft_ctx
*ctx
,
627 const struct nft_expr
*expr
,
628 const struct nft_data
**data
)
630 struct xt_match
*match
= expr
->ops
->data
;
631 unsigned int hook_mask
= 0;
634 if (nft_is_base_chain(ctx
->chain
)) {
635 const struct nft_base_chain
*basechain
=
636 nft_base_chain(ctx
->chain
);
637 const struct nf_hook_ops
*ops
= &basechain
->ops
;
639 hook_mask
= 1 << ops
->hooknum
;
640 if (match
->hooks
&& !(hook_mask
& match
->hooks
))
643 ret
= nft_compat_chain_validate_dependency(ctx
, match
->table
);
651 nfnl_compat_fill_info(struct sk_buff
*skb
, u32 portid
, u32 seq
, u32 type
,
652 int event
, u16 family
, const char *name
,
655 struct nlmsghdr
*nlh
;
656 struct nfgenmsg
*nfmsg
;
657 unsigned int flags
= portid
? NLM_F_MULTI
: 0;
659 event
= nfnl_msg_type(NFNL_SUBSYS_NFT_COMPAT
, event
);
660 nlh
= nlmsg_put(skb
, portid
, seq
, event
, sizeof(*nfmsg
), flags
);
664 nfmsg
= nlmsg_data(nlh
);
665 nfmsg
->nfgen_family
= family
;
666 nfmsg
->version
= NFNETLINK_V0
;
669 if (nla_put_string(skb
, NFTA_COMPAT_NAME
, name
) ||
670 nla_put_be32(skb
, NFTA_COMPAT_REV
, htonl(rev
)) ||
671 nla_put_be32(skb
, NFTA_COMPAT_TYPE
, htonl(target
)))
672 goto nla_put_failure
;
679 nlmsg_cancel(skb
, nlh
);
683 static int nfnl_compat_get_rcu(struct net
*net
, struct sock
*nfnl
,
684 struct sk_buff
*skb
, const struct nlmsghdr
*nlh
,
685 const struct nlattr
* const tb
[],
686 struct netlink_ext_ack
*extack
)
689 struct nfgenmsg
*nfmsg
;
693 struct sk_buff
*skb2
;
695 if (tb
[NFTA_COMPAT_NAME
] == NULL
||
696 tb
[NFTA_COMPAT_REV
] == NULL
||
697 tb
[NFTA_COMPAT_TYPE
] == NULL
)
700 name
= nla_data(tb
[NFTA_COMPAT_NAME
]);
701 rev
= ntohl(nla_get_be32(tb
[NFTA_COMPAT_REV
]));
702 target
= ntohl(nla_get_be32(tb
[NFTA_COMPAT_TYPE
]));
704 nfmsg
= nlmsg_data(nlh
);
706 switch(nfmsg
->nfgen_family
) {
720 pr_err("nft_compat: unsupported protocol %d\n",
721 nfmsg
->nfgen_family
);
725 if (!try_module_get(THIS_MODULE
))
729 try_then_request_module(xt_find_revision(nfmsg
->nfgen_family
, name
,
735 skb2
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
741 /* include the best revision for this extension in the message */
742 if (nfnl_compat_fill_info(skb2
, NETLINK_CB(skb
).portid
,
744 NFNL_MSG_TYPE(nlh
->nlmsg_type
),
747 name
, ret
, target
) <= 0) {
752 ret
= netlink_unicast(nfnl
, skb2
, NETLINK_CB(skb
).portid
,
758 module_put(THIS_MODULE
);
759 return ret
== -EAGAIN
? -ENOBUFS
: ret
;
762 static const struct nla_policy nfnl_compat_policy_get
[NFTA_COMPAT_MAX
+1] = {
763 [NFTA_COMPAT_NAME
] = { .type
= NLA_NUL_STRING
,
764 .len
= NFT_COMPAT_NAME_MAX
-1 },
765 [NFTA_COMPAT_REV
] = { .type
= NLA_U32
},
766 [NFTA_COMPAT_TYPE
] = { .type
= NLA_U32
},
769 static const struct nfnl_callback nfnl_nft_compat_cb
[NFNL_MSG_COMPAT_MAX
] = {
770 [NFNL_MSG_COMPAT_GET
] = { .call_rcu
= nfnl_compat_get_rcu
,
771 .attr_count
= NFTA_COMPAT_MAX
,
772 .policy
= nfnl_compat_policy_get
},
775 static const struct nfnetlink_subsystem nfnl_compat_subsys
= {
776 .name
= "nft-compat",
777 .subsys_id
= NFNL_SUBSYS_NFT_COMPAT
,
778 .cb_count
= NFNL_MSG_COMPAT_MAX
,
779 .cb
= nfnl_nft_compat_cb
,
782 static bool nft_match_cmp(const struct xt_match
*match
,
783 const char *name
, u32 rev
, u32 family
)
785 return strcmp(match
->name
, name
) == 0 && match
->revision
== rev
&&
786 (match
->family
== NFPROTO_UNSPEC
|| match
->family
== family
);
789 static const struct nft_expr_ops
*
790 nft_match_select_ops(const struct nft_ctx
*ctx
,
791 const struct nlattr
* const tb
[])
793 struct nft_compat_net
*cn
;
794 struct nft_xt
*nft_match
;
795 struct xt_match
*match
;
796 unsigned int matchsize
;
801 if (tb
[NFTA_MATCH_NAME
] == NULL
||
802 tb
[NFTA_MATCH_REV
] == NULL
||
803 tb
[NFTA_MATCH_INFO
] == NULL
)
804 return ERR_PTR(-EINVAL
);
806 mt_name
= nla_data(tb
[NFTA_MATCH_NAME
]);
807 rev
= ntohl(nla_get_be32(tb
[NFTA_MATCH_REV
]));
808 family
= ctx
->family
;
810 cn
= nft_compat_pernet(ctx
->net
);
812 /* Re-use the existing match if it's already loaded. */
813 list_for_each_entry(nft_match
, &cn
->nft_match_list
, head
) {
814 struct xt_match
*match
= nft_match
->ops
.data
;
816 if (nft_match_cmp(match
, mt_name
, rev
, family
))
817 return &nft_match
->ops
;
820 match
= xt_request_find_match(family
, mt_name
, rev
);
822 return ERR_PTR(-ENOENT
);
824 if (match
->matchsize
> nla_len(tb
[NFTA_MATCH_INFO
])) {
829 /* This is the first time we use this match, allocate operations */
830 nft_match
= kzalloc(sizeof(struct nft_xt
), GFP_KERNEL
);
831 if (nft_match
== NULL
) {
836 refcount_set(&nft_match
->refcnt
, 0);
837 nft_match
->ops
.type
= &nft_match_type
;
838 nft_match
->ops
.eval
= nft_match_eval
;
839 nft_match
->ops
.init
= nft_match_init
;
840 nft_match
->ops
.destroy
= nft_match_destroy
;
841 nft_match
->ops
.deactivate
= nft_compat_deactivate
;
842 nft_match
->ops
.dump
= nft_match_dump
;
843 nft_match
->ops
.validate
= nft_match_validate
;
844 nft_match
->ops
.data
= match
;
846 matchsize
= NFT_EXPR_SIZE(XT_ALIGN(match
->matchsize
));
847 if (matchsize
> NFT_MATCH_LARGE_THRESH
) {
848 matchsize
= NFT_EXPR_SIZE(sizeof(struct nft_xt_match_priv
));
850 nft_match
->ops
.eval
= nft_match_large_eval
;
851 nft_match
->ops
.init
= nft_match_large_init
;
852 nft_match
->ops
.destroy
= nft_match_large_destroy
;
853 nft_match
->ops
.dump
= nft_match_large_dump
;
856 nft_match
->ops
.size
= matchsize
;
858 nft_match
->listcnt
= 0;
859 list_add(&nft_match
->head
, &cn
->nft_match_list
);
861 return &nft_match
->ops
;
863 module_put(match
->me
);
867 static struct nft_expr_type nft_match_type __read_mostly
= {
869 .select_ops
= nft_match_select_ops
,
870 .policy
= nft_match_policy
,
871 .maxattr
= NFTA_MATCH_MAX
,
872 .owner
= THIS_MODULE
,
875 static bool nft_target_cmp(const struct xt_target
*tg
,
876 const char *name
, u32 rev
, u32 family
)
878 return strcmp(tg
->name
, name
) == 0 && tg
->revision
== rev
&&
879 (tg
->family
== NFPROTO_UNSPEC
|| tg
->family
== family
);
882 static const struct nft_expr_ops
*
883 nft_target_select_ops(const struct nft_ctx
*ctx
,
884 const struct nlattr
* const tb
[])
886 struct nft_compat_net
*cn
;
887 struct nft_xt
*nft_target
;
888 struct xt_target
*target
;
893 if (tb
[NFTA_TARGET_NAME
] == NULL
||
894 tb
[NFTA_TARGET_REV
] == NULL
||
895 tb
[NFTA_TARGET_INFO
] == NULL
)
896 return ERR_PTR(-EINVAL
);
898 tg_name
= nla_data(tb
[NFTA_TARGET_NAME
]);
899 rev
= ntohl(nla_get_be32(tb
[NFTA_TARGET_REV
]));
900 family
= ctx
->family
;
902 if (strcmp(tg_name
, XT_ERROR_TARGET
) == 0 ||
903 strcmp(tg_name
, XT_STANDARD_TARGET
) == 0 ||
904 strcmp(tg_name
, "standard") == 0)
905 return ERR_PTR(-EINVAL
);
907 cn
= nft_compat_pernet(ctx
->net
);
908 /* Re-use the existing target if it's already loaded. */
909 list_for_each_entry(nft_target
, &cn
->nft_target_list
, head
) {
910 struct xt_target
*target
= nft_target
->ops
.data
;
915 if (nft_target_cmp(target
, tg_name
, rev
, family
))
916 return &nft_target
->ops
;
919 target
= xt_request_find_target(family
, tg_name
, rev
);
921 return ERR_PTR(-ENOENT
);
923 if (!target
->target
) {
928 if (target
->targetsize
> nla_len(tb
[NFTA_TARGET_INFO
])) {
933 /* This is the first time we use this target, allocate operations */
934 nft_target
= kzalloc(sizeof(struct nft_xt
), GFP_KERNEL
);
935 if (nft_target
== NULL
) {
940 refcount_set(&nft_target
->refcnt
, 0);
941 nft_target
->ops
.type
= &nft_target_type
;
942 nft_target
->ops
.size
= NFT_EXPR_SIZE(XT_ALIGN(target
->targetsize
));
943 nft_target
->ops
.init
= nft_target_init
;
944 nft_target
->ops
.destroy
= nft_target_destroy
;
945 nft_target
->ops
.deactivate
= nft_compat_deactivate
;
946 nft_target
->ops
.dump
= nft_target_dump
;
947 nft_target
->ops
.validate
= nft_target_validate
;
948 nft_target
->ops
.data
= target
;
950 if (family
== NFPROTO_BRIDGE
)
951 nft_target
->ops
.eval
= nft_target_eval_bridge
;
953 nft_target
->ops
.eval
= nft_target_eval_xt
;
955 nft_target
->listcnt
= 0;
956 list_add(&nft_target
->head
, &cn
->nft_target_list
);
958 return &nft_target
->ops
;
960 module_put(target
->me
);
964 static struct nft_expr_type nft_target_type __read_mostly
= {
966 .select_ops
= nft_target_select_ops
,
967 .policy
= nft_target_policy
,
968 .maxattr
= NFTA_TARGET_MAX
,
969 .owner
= THIS_MODULE
,
972 static int __net_init
nft_compat_init_net(struct net
*net
)
974 struct nft_compat_net
*cn
= nft_compat_pernet(net
);
976 INIT_LIST_HEAD(&cn
->nft_target_list
);
977 INIT_LIST_HEAD(&cn
->nft_match_list
);
982 static void __net_exit
nft_compat_exit_net(struct net
*net
)
984 struct nft_compat_net
*cn
= nft_compat_pernet(net
);
985 struct nft_xt
*xt
, *next
;
987 if (list_empty(&cn
->nft_match_list
) &&
988 list_empty(&cn
->nft_target_list
))
991 /* If there was an error that caused nft_xt expr to not be initialized
992 * fully and noone else requested the same expression later, the lists
993 * contain 0-refcount entries that still hold module reference.
997 mutex_lock(&net
->nft
.commit_mutex
);
998 list_for_each_entry_safe(xt
, next
, &cn
->nft_target_list
, head
) {
999 struct xt_target
*target
= xt
->ops
.data
;
1001 list_del_init(&xt
->head
);
1003 if (refcount_read(&xt
->refcnt
))
1005 module_put(target
->me
);
1009 list_for_each_entry_safe(xt
, next
, &cn
->nft_match_list
, head
) {
1010 struct xt_match
*match
= xt
->ops
.data
;
1012 list_del_init(&xt
->head
);
1014 if (refcount_read(&xt
->refcnt
))
1016 module_put(match
->me
);
1019 mutex_unlock(&net
->nft
.commit_mutex
);
1022 static struct pernet_operations nft_compat_net_ops
= {
1023 .init
= nft_compat_init_net
,
1024 .exit
= nft_compat_exit_net
,
1025 .id
= &nft_compat_net_id
,
1026 .size
= sizeof(struct nft_compat_net
),
1029 static int __init
nft_compat_module_init(void)
1033 ret
= register_pernet_subsys(&nft_compat_net_ops
);
1037 ret
= nft_register_expr(&nft_match_type
);
1041 ret
= nft_register_expr(&nft_target_type
);
1045 ret
= nfnetlink_subsys_register(&nfnl_compat_subsys
);
1047 pr_err("nft_compat: cannot register with nfnetlink.\n");
1053 nft_unregister_expr(&nft_target_type
);
1055 nft_unregister_expr(&nft_match_type
);
1057 unregister_pernet_subsys(&nft_compat_net_ops
);
1061 static void __exit
nft_compat_module_exit(void)
1063 nfnetlink_subsys_unregister(&nfnl_compat_subsys
);
1064 nft_unregister_expr(&nft_target_type
);
1065 nft_unregister_expr(&nft_match_type
);
1066 unregister_pernet_subsys(&nft_compat_net_ops
);
1069 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT
);
1071 module_init(nft_compat_module_init
);
1072 module_exit(nft_compat_module_exit
);
1074 MODULE_LICENSE("GPL");
1075 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
1076 MODULE_ALIAS_NFT_EXPR("match");
1077 MODULE_ALIAS_NFT_EXPR("target");