1 // SPDX-License-Identifier: GPL-2.0-only
3 * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
5 * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
8 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/module.h>
11 #include <linux/netlink.h>
12 #include <linux/netfilter.h>
13 #include <linux/netfilter/nfnetlink.h>
14 #include <linux/netfilter/nf_tables.h>
15 #include <linux/netfilter/nf_tables_compat.h>
16 #include <linux/netfilter/x_tables.h>
17 #include <linux/netfilter_ipv4/ip_tables.h>
18 #include <linux/netfilter_ipv6/ip6_tables.h>
19 #include <linux/netfilter_bridge/ebtables.h>
20 #include <linux/netfilter_arp/arp_tables.h>
21 #include <net/netfilter/nf_tables.h>
22 #include <net/netfilter/nf_log.h>
24 /* Used for matches where *info is larger than X byte */
25 #define NFT_MATCH_LARGE_THRESH 192
27 struct nft_xt_match_priv
{
31 static int nft_compat_chain_validate_dependency(const struct nft_ctx
*ctx
,
32 const char *tablename
)
34 enum nft_chain_types type
= NFT_CHAIN_T_DEFAULT
;
35 const struct nft_chain
*chain
= ctx
->chain
;
36 const struct nft_base_chain
*basechain
;
39 !nft_is_base_chain(chain
))
42 basechain
= nft_base_chain(chain
);
43 if (strcmp(tablename
, "nat") == 0) {
44 if (ctx
->family
!= NFPROTO_BRIDGE
)
45 type
= NFT_CHAIN_T_NAT
;
46 if (basechain
->type
->type
!= type
)
57 struct arpt_entry arp
;
61 nft_compat_set_par(struct xt_action_param
*par
,
62 const struct nft_pktinfo
*pkt
,
63 const void *xt
, const void *xt_info
)
65 par
->state
= pkt
->state
;
66 par
->thoff
= nft_thoff(pkt
);
67 par
->fragoff
= pkt
->fragoff
;
69 par
->targinfo
= xt_info
;
73 static void nft_target_eval_xt(const struct nft_expr
*expr
,
74 struct nft_regs
*regs
,
75 const struct nft_pktinfo
*pkt
)
77 void *info
= nft_expr_priv(expr
);
78 struct xt_target
*target
= expr
->ops
->data
;
79 struct sk_buff
*skb
= pkt
->skb
;
80 struct xt_action_param xt
;
83 nft_compat_set_par(&xt
, pkt
, target
, info
);
85 ret
= target
->target(skb
, &xt
);
92 regs
->verdict
.code
= NFT_CONTINUE
;
95 regs
->verdict
.code
= ret
;
100 static void nft_target_eval_bridge(const struct nft_expr
*expr
,
101 struct nft_regs
*regs
,
102 const struct nft_pktinfo
*pkt
)
104 void *info
= nft_expr_priv(expr
);
105 struct xt_target
*target
= expr
->ops
->data
;
106 struct sk_buff
*skb
= pkt
->skb
;
107 struct xt_action_param xt
;
110 nft_compat_set_par(&xt
, pkt
, target
, info
);
112 ret
= target
->target(skb
, &xt
);
119 regs
->verdict
.code
= NF_ACCEPT
;
122 regs
->verdict
.code
= NF_DROP
;
125 regs
->verdict
.code
= NFT_CONTINUE
;
128 regs
->verdict
.code
= NFT_RETURN
;
131 regs
->verdict
.code
= ret
;
136 static const struct nla_policy nft_target_policy
[NFTA_TARGET_MAX
+ 1] = {
137 [NFTA_TARGET_NAME
] = { .type
= NLA_NUL_STRING
},
138 [NFTA_TARGET_REV
] = NLA_POLICY_MAX(NLA_BE32
, 255),
139 [NFTA_TARGET_INFO
] = { .type
= NLA_BINARY
},
143 nft_target_set_tgchk_param(struct xt_tgchk_param
*par
,
144 const struct nft_ctx
*ctx
,
145 struct xt_target
*target
, void *info
,
146 union nft_entry
*entry
, u16 proto
, bool inv
)
149 par
->table
= ctx
->table
->name
;
150 switch (ctx
->family
) {
152 entry
->e4
.ip
.proto
= proto
;
153 entry
->e4
.ip
.invflags
= inv
? IPT_INV_PROTO
: 0;
157 entry
->e6
.ipv6
.flags
|= IP6T_F_PROTO
;
159 entry
->e6
.ipv6
.proto
= proto
;
160 entry
->e6
.ipv6
.invflags
= inv
? IP6T_INV_PROTO
: 0;
163 entry
->ebt
.ethproto
= (__force __be16
)proto
;
164 entry
->ebt
.invflags
= inv
? EBT_IPROTO
: 0;
169 par
->entryinfo
= entry
;
170 par
->target
= target
;
171 par
->targinfo
= info
;
172 if (nft_is_base_chain(ctx
->chain
)) {
173 const struct nft_base_chain
*basechain
=
174 nft_base_chain(ctx
->chain
);
175 const struct nf_hook_ops
*ops
= &basechain
->ops
;
177 par
->hook_mask
= 1 << ops
->hooknum
;
181 par
->family
= ctx
->family
;
182 par
->nft_compat
= true;
185 static void target_compat_from_user(struct xt_target
*t
, void *in
, void *out
)
189 memcpy(out
, in
, t
->targetsize
);
190 pad
= XT_ALIGN(t
->targetsize
) - t
->targetsize
;
192 memset(out
+ t
->targetsize
, 0, pad
);
195 static const struct nla_policy nft_rule_compat_policy
[NFTA_RULE_COMPAT_MAX
+ 1] = {
196 [NFTA_RULE_COMPAT_PROTO
] = { .type
= NLA_U32
},
197 [NFTA_RULE_COMPAT_FLAGS
] = { .type
= NLA_U32
},
200 static int nft_parse_compat(const struct nlattr
*attr
, u16
*proto
, bool *inv
)
202 struct nlattr
*tb
[NFTA_RULE_COMPAT_MAX
+1];
207 err
= nla_parse_nested_deprecated(tb
, NFTA_RULE_COMPAT_MAX
, attr
,
208 nft_rule_compat_policy
, NULL
);
212 if (!tb
[NFTA_RULE_COMPAT_PROTO
] || !tb
[NFTA_RULE_COMPAT_FLAGS
])
215 flags
= ntohl(nla_get_be32(tb
[NFTA_RULE_COMPAT_FLAGS
]));
216 if (flags
& NFT_RULE_COMPAT_F_UNUSED
||
217 flags
& ~NFT_RULE_COMPAT_F_MASK
)
219 if (flags
& NFT_RULE_COMPAT_F_INV
)
222 l4proto
= ntohl(nla_get_be32(tb
[NFTA_RULE_COMPAT_PROTO
]));
223 if (l4proto
> U16_MAX
)
231 static void nft_compat_wait_for_destructors(void)
233 /* xtables matches or targets can have side effects, e.g.
234 * creation/destruction of /proc files.
235 * The xt ->destroy functions are run asynchronously from
236 * work queue. If we have pending invocations we thus
237 * need to wait for those to finish.
239 nf_tables_trans_destroy_flush_work();
243 nft_target_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
244 const struct nlattr
* const tb
[])
246 void *info
= nft_expr_priv(expr
);
247 struct xt_target
*target
= expr
->ops
->data
;
248 struct xt_tgchk_param par
;
249 size_t size
= XT_ALIGN(nla_len(tb
[NFTA_TARGET_INFO
]));
252 union nft_entry e
= {};
255 target_compat_from_user(target
, nla_data(tb
[NFTA_TARGET_INFO
]), info
);
257 if (ctx
->nla
[NFTA_RULE_COMPAT
]) {
258 ret
= nft_parse_compat(ctx
->nla
[NFTA_RULE_COMPAT
], &proto
, &inv
);
263 nft_target_set_tgchk_param(&par
, ctx
, target
, info
, &e
, proto
, inv
);
265 nft_compat_wait_for_destructors();
267 ret
= xt_check_target(&par
, size
, proto
, inv
);
269 if (ret
== -ENOENT
) {
270 const char *modname
= NULL
;
272 if (strcmp(target
->name
, "LOG") == 0)
273 modname
= "nf_log_syslog";
274 else if (strcmp(target
->name
, "NFLOG") == 0)
275 modname
= "nfnetlink_log";
278 nft_request_module(ctx
->net
, "%s", modname
) == -EAGAIN
)
285 /* The standard target cannot be used */
292 static void __nft_mt_tg_destroy(struct module
*me
, const struct nft_expr
*expr
)
299 nft_target_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
)
301 struct xt_target
*target
= expr
->ops
->data
;
302 void *info
= nft_expr_priv(expr
);
303 struct module
*me
= target
->me
;
304 struct xt_tgdtor_param par
;
309 par
.family
= ctx
->family
;
310 if (par
.target
->destroy
!= NULL
)
311 par
.target
->destroy(&par
);
313 __nft_mt_tg_destroy(me
, expr
);
316 static int nft_extension_dump_info(struct sk_buff
*skb
, int attr
,
318 unsigned int size
, unsigned int user_size
)
320 unsigned int info_size
, aligned_size
= XT_ALIGN(size
);
323 nla
= nla_reserve(skb
, attr
, aligned_size
);
327 info_size
= user_size
? : size
;
328 memcpy(nla_data(nla
), info
, info_size
);
329 memset(nla_data(nla
) + info_size
, 0, aligned_size
- info_size
);
334 static int nft_target_dump(struct sk_buff
*skb
,
335 const struct nft_expr
*expr
, bool reset
)
337 const struct xt_target
*target
= expr
->ops
->data
;
338 void *info
= nft_expr_priv(expr
);
340 if (nla_put_string(skb
, NFTA_TARGET_NAME
, target
->name
) ||
341 nla_put_be32(skb
, NFTA_TARGET_REV
, htonl(target
->revision
)) ||
342 nft_extension_dump_info(skb
, NFTA_TARGET_INFO
, info
,
343 target
->targetsize
, target
->usersize
))
344 goto nla_put_failure
;
352 static int nft_target_validate(const struct nft_ctx
*ctx
,
353 const struct nft_expr
*expr
)
355 struct xt_target
*target
= expr
->ops
->data
;
356 unsigned int hook_mask
= 0;
359 if (ctx
->family
!= NFPROTO_IPV4
&&
360 ctx
->family
!= NFPROTO_IPV6
&&
361 ctx
->family
!= NFPROTO_INET
&&
362 ctx
->family
!= NFPROTO_BRIDGE
&&
363 ctx
->family
!= NFPROTO_ARP
)
366 ret
= nft_chain_validate_hooks(ctx
->chain
,
367 (1 << NF_INET_PRE_ROUTING
) |
368 (1 << NF_INET_LOCAL_IN
) |
369 (1 << NF_INET_FORWARD
) |
370 (1 << NF_INET_LOCAL_OUT
) |
371 (1 << NF_INET_POST_ROUTING
));
375 if (nft_is_base_chain(ctx
->chain
)) {
376 const struct nft_base_chain
*basechain
=
377 nft_base_chain(ctx
->chain
);
378 const struct nf_hook_ops
*ops
= &basechain
->ops
;
380 hook_mask
= 1 << ops
->hooknum
;
381 if (target
->hooks
&& !(hook_mask
& target
->hooks
))
384 ret
= nft_compat_chain_validate_dependency(ctx
, target
->table
);
391 static void __nft_match_eval(const struct nft_expr
*expr
,
392 struct nft_regs
*regs
,
393 const struct nft_pktinfo
*pkt
,
396 struct xt_match
*match
= expr
->ops
->data
;
397 struct sk_buff
*skb
= pkt
->skb
;
398 struct xt_action_param xt
;
401 nft_compat_set_par(&xt
, pkt
, match
, info
);
403 ret
= match
->match(skb
, &xt
);
406 regs
->verdict
.code
= NF_DROP
;
410 switch (ret
? 1 : 0) {
412 regs
->verdict
.code
= NFT_CONTINUE
;
415 regs
->verdict
.code
= NFT_BREAK
;
420 static void nft_match_large_eval(const struct nft_expr
*expr
,
421 struct nft_regs
*regs
,
422 const struct nft_pktinfo
*pkt
)
424 struct nft_xt_match_priv
*priv
= nft_expr_priv(expr
);
426 __nft_match_eval(expr
, regs
, pkt
, priv
->info
);
429 static void nft_match_eval(const struct nft_expr
*expr
,
430 struct nft_regs
*regs
,
431 const struct nft_pktinfo
*pkt
)
433 __nft_match_eval(expr
, regs
, pkt
, nft_expr_priv(expr
));
436 static const struct nla_policy nft_match_policy
[NFTA_MATCH_MAX
+ 1] = {
437 [NFTA_MATCH_NAME
] = { .type
= NLA_NUL_STRING
},
438 [NFTA_MATCH_REV
] = NLA_POLICY_MAX(NLA_BE32
, 255),
439 [NFTA_MATCH_INFO
] = { .type
= NLA_BINARY
},
442 /* struct xt_mtchk_param and xt_tgchk_param look very similar */
444 nft_match_set_mtchk_param(struct xt_mtchk_param
*par
, const struct nft_ctx
*ctx
,
445 struct xt_match
*match
, void *info
,
446 union nft_entry
*entry
, u16 proto
, bool inv
)
449 par
->table
= ctx
->table
->name
;
450 switch (ctx
->family
) {
452 entry
->e4
.ip
.proto
= proto
;
453 entry
->e4
.ip
.invflags
= inv
? IPT_INV_PROTO
: 0;
457 entry
->e6
.ipv6
.flags
|= IP6T_F_PROTO
;
459 entry
->e6
.ipv6
.proto
= proto
;
460 entry
->e6
.ipv6
.invflags
= inv
? IP6T_INV_PROTO
: 0;
463 entry
->ebt
.ethproto
= (__force __be16
)proto
;
464 entry
->ebt
.invflags
= inv
? EBT_IPROTO
: 0;
469 par
->entryinfo
= entry
;
471 par
->matchinfo
= info
;
472 if (nft_is_base_chain(ctx
->chain
)) {
473 const struct nft_base_chain
*basechain
=
474 nft_base_chain(ctx
->chain
);
475 const struct nf_hook_ops
*ops
= &basechain
->ops
;
477 par
->hook_mask
= 1 << ops
->hooknum
;
481 par
->family
= ctx
->family
;
482 par
->nft_compat
= true;
485 static void match_compat_from_user(struct xt_match
*m
, void *in
, void *out
)
489 memcpy(out
, in
, m
->matchsize
);
490 pad
= XT_ALIGN(m
->matchsize
) - m
->matchsize
;
492 memset(out
+ m
->matchsize
, 0, pad
);
496 __nft_match_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
497 const struct nlattr
* const tb
[],
500 struct xt_match
*match
= expr
->ops
->data
;
501 struct xt_mtchk_param par
;
502 size_t size
= XT_ALIGN(nla_len(tb
[NFTA_MATCH_INFO
]));
505 union nft_entry e
= {};
508 match_compat_from_user(match
, nla_data(tb
[NFTA_MATCH_INFO
]), info
);
510 if (ctx
->nla
[NFTA_RULE_COMPAT
]) {
511 ret
= nft_parse_compat(ctx
->nla
[NFTA_RULE_COMPAT
], &proto
, &inv
);
516 nft_match_set_mtchk_param(&par
, ctx
, match
, info
, &e
, proto
, inv
);
518 nft_compat_wait_for_destructors();
520 return xt_check_match(&par
, size
, proto
, inv
);
524 nft_match_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
525 const struct nlattr
* const tb
[])
527 return __nft_match_init(ctx
, expr
, tb
, nft_expr_priv(expr
));
531 nft_match_large_init(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
532 const struct nlattr
* const tb
[])
534 struct nft_xt_match_priv
*priv
= nft_expr_priv(expr
);
535 struct xt_match
*m
= expr
->ops
->data
;
538 priv
->info
= kmalloc(XT_ALIGN(m
->matchsize
), GFP_KERNEL_ACCOUNT
);
542 ret
= __nft_match_init(ctx
, expr
, tb
, priv
->info
);
549 __nft_match_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
,
552 struct xt_match
*match
= expr
->ops
->data
;
553 struct module
*me
= match
->me
;
554 struct xt_mtdtor_param par
;
558 par
.matchinfo
= info
;
559 par
.family
= ctx
->family
;
560 if (par
.match
->destroy
!= NULL
)
561 par
.match
->destroy(&par
);
563 __nft_mt_tg_destroy(me
, expr
);
567 nft_match_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
)
569 __nft_match_destroy(ctx
, expr
, nft_expr_priv(expr
));
573 nft_match_large_destroy(const struct nft_ctx
*ctx
, const struct nft_expr
*expr
)
575 struct nft_xt_match_priv
*priv
= nft_expr_priv(expr
);
577 __nft_match_destroy(ctx
, expr
, priv
->info
);
581 static int __nft_match_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
,
584 struct xt_match
*match
= expr
->ops
->data
;
586 if (nla_put_string(skb
, NFTA_MATCH_NAME
, match
->name
) ||
587 nla_put_be32(skb
, NFTA_MATCH_REV
, htonl(match
->revision
)) ||
588 nft_extension_dump_info(skb
, NFTA_MATCH_INFO
, info
,
589 match
->matchsize
, match
->usersize
))
590 goto nla_put_failure
;
598 static int nft_match_dump(struct sk_buff
*skb
,
599 const struct nft_expr
*expr
, bool reset
)
601 return __nft_match_dump(skb
, expr
, nft_expr_priv(expr
));
604 static int nft_match_large_dump(struct sk_buff
*skb
,
605 const struct nft_expr
*e
, bool reset
)
607 struct nft_xt_match_priv
*priv
= nft_expr_priv(e
);
609 return __nft_match_dump(skb
, e
, priv
->info
);
612 static int nft_match_validate(const struct nft_ctx
*ctx
,
613 const struct nft_expr
*expr
)
615 struct xt_match
*match
= expr
->ops
->data
;
616 unsigned int hook_mask
= 0;
619 if (ctx
->family
!= NFPROTO_IPV4
&&
620 ctx
->family
!= NFPROTO_IPV6
&&
621 ctx
->family
!= NFPROTO_INET
&&
622 ctx
->family
!= NFPROTO_BRIDGE
&&
623 ctx
->family
!= NFPROTO_ARP
)
626 ret
= nft_chain_validate_hooks(ctx
->chain
,
627 (1 << NF_INET_PRE_ROUTING
) |
628 (1 << NF_INET_LOCAL_IN
) |
629 (1 << NF_INET_FORWARD
) |
630 (1 << NF_INET_LOCAL_OUT
) |
631 (1 << NF_INET_POST_ROUTING
));
635 if (nft_is_base_chain(ctx
->chain
)) {
636 const struct nft_base_chain
*basechain
=
637 nft_base_chain(ctx
->chain
);
638 const struct nf_hook_ops
*ops
= &basechain
->ops
;
640 hook_mask
= 1 << ops
->hooknum
;
641 if (match
->hooks
&& !(hook_mask
& match
->hooks
))
644 ret
= nft_compat_chain_validate_dependency(ctx
, match
->table
);
652 nfnl_compat_fill_info(struct sk_buff
*skb
, u32 portid
, u32 seq
, u32 type
,
653 int event
, u16 family
, const char *name
,
656 struct nlmsghdr
*nlh
;
657 unsigned int flags
= portid
? NLM_F_MULTI
: 0;
659 event
= nfnl_msg_type(NFNL_SUBSYS_NFT_COMPAT
, event
);
660 nlh
= nfnl_msg_put(skb
, portid
, seq
, event
, flags
, family
,
665 if (nla_put_string(skb
, NFTA_COMPAT_NAME
, name
) ||
666 nla_put_be32(skb
, NFTA_COMPAT_REV
, htonl(rev
)) ||
667 nla_put_be32(skb
, NFTA_COMPAT_TYPE
, htonl(target
)))
668 goto nla_put_failure
;
675 nlmsg_cancel(skb
, nlh
);
679 static int nfnl_compat_get_rcu(struct sk_buff
*skb
,
680 const struct nfnl_info
*info
,
681 const struct nlattr
* const tb
[])
683 u8 family
= info
->nfmsg
->nfgen_family
;
684 const char *name
, *fmt
;
685 struct sk_buff
*skb2
;
689 if (tb
[NFTA_COMPAT_NAME
] == NULL
||
690 tb
[NFTA_COMPAT_REV
] == NULL
||
691 tb
[NFTA_COMPAT_TYPE
] == NULL
)
694 name
= nla_data(tb
[NFTA_COMPAT_NAME
]);
695 rev
= ntohl(nla_get_be32(tb
[NFTA_COMPAT_REV
]));
696 target
= ntohl(nla_get_be32(tb
[NFTA_COMPAT_TYPE
]));
712 pr_err("nft_compat: unsupported protocol %d\n", family
);
716 if (!try_module_get(THIS_MODULE
))
720 try_then_request_module(xt_find_revision(family
, name
, rev
, target
, &ret
),
725 skb2
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
731 /* include the best revision for this extension in the message */
732 if (nfnl_compat_fill_info(skb2
, NETLINK_CB(skb
).portid
,
733 info
->nlh
->nlmsg_seq
,
734 NFNL_MSG_TYPE(info
->nlh
->nlmsg_type
),
736 family
, name
, ret
, target
) <= 0) {
741 ret
= nfnetlink_unicast(skb2
, info
->net
, NETLINK_CB(skb
).portid
);
744 module_put(THIS_MODULE
);
749 static const struct nla_policy nfnl_compat_policy_get
[NFTA_COMPAT_MAX
+1] = {
750 [NFTA_COMPAT_NAME
] = { .type
= NLA_NUL_STRING
,
751 .len
= NFT_COMPAT_NAME_MAX
-1 },
752 [NFTA_COMPAT_REV
] = NLA_POLICY_MAX(NLA_BE32
, 255),
753 [NFTA_COMPAT_TYPE
] = { .type
= NLA_U32
},
756 static const struct nfnl_callback nfnl_nft_compat_cb
[NFNL_MSG_COMPAT_MAX
] = {
757 [NFNL_MSG_COMPAT_GET
] = {
758 .call
= nfnl_compat_get_rcu
,
760 .attr_count
= NFTA_COMPAT_MAX
,
761 .policy
= nfnl_compat_policy_get
765 static const struct nfnetlink_subsystem nfnl_compat_subsys
= {
766 .name
= "nft-compat",
767 .subsys_id
= NFNL_SUBSYS_NFT_COMPAT
,
768 .cb_count
= NFNL_MSG_COMPAT_MAX
,
769 .cb
= nfnl_nft_compat_cb
,
772 static struct nft_expr_type nft_match_type
;
774 static bool nft_match_reduce(struct nft_regs_track
*track
,
775 const struct nft_expr
*expr
)
777 const struct xt_match
*match
= expr
->ops
->data
;
779 return strcmp(match
->name
, "comment") == 0;
782 static const struct nft_expr_ops
*
783 nft_match_select_ops(const struct nft_ctx
*ctx
,
784 const struct nlattr
* const tb
[])
786 struct nft_expr_ops
*ops
;
787 struct xt_match
*match
;
788 unsigned int matchsize
;
793 if (tb
[NFTA_MATCH_NAME
] == NULL
||
794 tb
[NFTA_MATCH_REV
] == NULL
||
795 tb
[NFTA_MATCH_INFO
] == NULL
)
796 return ERR_PTR(-EINVAL
);
798 mt_name
= nla_data(tb
[NFTA_MATCH_NAME
]);
799 rev
= ntohl(nla_get_be32(tb
[NFTA_MATCH_REV
]));
800 family
= ctx
->family
;
802 match
= xt_request_find_match(family
, mt_name
, rev
);
804 return ERR_PTR(-ENOENT
);
806 if (match
->matchsize
> nla_len(tb
[NFTA_MATCH_INFO
])) {
811 ops
= kzalloc(sizeof(struct nft_expr_ops
), GFP_KERNEL_ACCOUNT
);
817 ops
->type
= &nft_match_type
;
818 ops
->eval
= nft_match_eval
;
819 ops
->init
= nft_match_init
;
820 ops
->destroy
= nft_match_destroy
;
821 ops
->dump
= nft_match_dump
;
822 ops
->validate
= nft_match_validate
;
824 ops
->reduce
= nft_match_reduce
;
826 matchsize
= NFT_EXPR_SIZE(XT_ALIGN(match
->matchsize
));
827 if (matchsize
> NFT_MATCH_LARGE_THRESH
) {
828 matchsize
= NFT_EXPR_SIZE(sizeof(struct nft_xt_match_priv
));
830 ops
->eval
= nft_match_large_eval
;
831 ops
->init
= nft_match_large_init
;
832 ops
->destroy
= nft_match_large_destroy
;
833 ops
->dump
= nft_match_large_dump
;
836 ops
->size
= matchsize
;
840 module_put(match
->me
);
844 static void nft_match_release_ops(const struct nft_expr_ops
*ops
)
846 struct xt_match
*match
= ops
->data
;
848 module_put(match
->me
);
852 static struct nft_expr_type nft_match_type __read_mostly
= {
854 .select_ops
= nft_match_select_ops
,
855 .release_ops
= nft_match_release_ops
,
856 .policy
= nft_match_policy
,
857 .maxattr
= NFTA_MATCH_MAX
,
858 .owner
= THIS_MODULE
,
861 static struct nft_expr_type nft_target_type
;
863 static const struct nft_expr_ops
*
864 nft_target_select_ops(const struct nft_ctx
*ctx
,
865 const struct nlattr
* const tb
[])
867 struct nft_expr_ops
*ops
;
868 struct xt_target
*target
;
873 if (tb
[NFTA_TARGET_NAME
] == NULL
||
874 tb
[NFTA_TARGET_REV
] == NULL
||
875 tb
[NFTA_TARGET_INFO
] == NULL
)
876 return ERR_PTR(-EINVAL
);
878 tg_name
= nla_data(tb
[NFTA_TARGET_NAME
]);
879 rev
= ntohl(nla_get_be32(tb
[NFTA_TARGET_REV
]));
880 family
= ctx
->family
;
882 if (strcmp(tg_name
, XT_ERROR_TARGET
) == 0 ||
883 strcmp(tg_name
, XT_STANDARD_TARGET
) == 0 ||
884 strcmp(tg_name
, "standard") == 0)
885 return ERR_PTR(-EINVAL
);
887 target
= xt_request_find_target(family
, tg_name
, rev
);
889 return ERR_PTR(-ENOENT
);
891 if (!target
->target
) {
896 if (target
->targetsize
> nla_len(tb
[NFTA_TARGET_INFO
])) {
901 ops
= kzalloc(sizeof(struct nft_expr_ops
), GFP_KERNEL_ACCOUNT
);
907 ops
->type
= &nft_target_type
;
908 ops
->size
= NFT_EXPR_SIZE(XT_ALIGN(target
->targetsize
));
909 ops
->init
= nft_target_init
;
910 ops
->destroy
= nft_target_destroy
;
911 ops
->dump
= nft_target_dump
;
912 ops
->validate
= nft_target_validate
;
914 ops
->reduce
= NFT_REDUCE_READONLY
;
916 if (family
== NFPROTO_BRIDGE
)
917 ops
->eval
= nft_target_eval_bridge
;
919 ops
->eval
= nft_target_eval_xt
;
923 module_put(target
->me
);
927 static void nft_target_release_ops(const struct nft_expr_ops
*ops
)
929 struct xt_target
*target
= ops
->data
;
931 module_put(target
->me
);
935 static struct nft_expr_type nft_target_type __read_mostly
= {
937 .select_ops
= nft_target_select_ops
,
938 .release_ops
= nft_target_release_ops
,
939 .policy
= nft_target_policy
,
940 .maxattr
= NFTA_TARGET_MAX
,
941 .owner
= THIS_MODULE
,
944 static int __init
nft_compat_module_init(void)
948 ret
= nft_register_expr(&nft_match_type
);
952 ret
= nft_register_expr(&nft_target_type
);
956 ret
= nfnetlink_subsys_register(&nfnl_compat_subsys
);
958 pr_err("nft_compat: cannot register with nfnetlink.\n");
964 nft_unregister_expr(&nft_target_type
);
966 nft_unregister_expr(&nft_match_type
);
970 static void __exit
nft_compat_module_exit(void)
972 nfnetlink_subsys_unregister(&nfnl_compat_subsys
);
973 nft_unregister_expr(&nft_target_type
);
974 nft_unregister_expr(&nft_match_type
);
977 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT
);
979 module_init(nft_compat_module_init
);
980 module_exit(nft_compat_module_exit
);
982 MODULE_LICENSE("GPL");
983 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
984 MODULE_ALIAS_NFT_EXPR("match");
985 MODULE_ALIAS_NFT_EXPR("target");
986 MODULE_DESCRIPTION("x_tables over nftables support");