xref: /openbmc/linux/net/netfilter/nft_compat.c (revision c3859c14)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
4  *
5  * This software has been sponsored by Sophos Astaro <http://www.sophos.com>
6  */
7 
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>
23 
24 /* Used for matches where *info is larger than X byte */
25 #define NFT_MATCH_LARGE_THRESH	192
26 
27 struct nft_xt_match_priv {
28 	void *info;
29 };
30 
31 static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx,
32 						const char *tablename)
33 {
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;
37 
38 	if (!tablename ||
39 	    !nft_is_base_chain(chain))
40 		return 0;
41 
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)
47 			return -EINVAL;
48 	}
49 
50 	return 0;
51 }
52 
53 union nft_entry {
54 	struct ipt_entry e4;
55 	struct ip6t_entry e6;
56 	struct ebt_entry ebt;
57 	struct arpt_entry arp;
58 };
59 
60 static inline void
61 nft_compat_set_par(struct xt_action_param *par,
62 		   const struct nft_pktinfo *pkt,
63 		   const void *xt, const void *xt_info)
64 {
65 	par->state	= pkt->state;
66 	par->thoff	= nft_thoff(pkt);
67 	par->fragoff	= pkt->fragoff;
68 	par->target	= xt;
69 	par->targinfo	= xt_info;
70 	par->hotdrop	= false;
71 }
72 
73 static void nft_target_eval_xt(const struct nft_expr *expr,
74 			       struct nft_regs *regs,
75 			       const struct nft_pktinfo *pkt)
76 {
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;
81 	int ret;
82 
83 	nft_compat_set_par(&xt, pkt, target, info);
84 
85 	ret = target->target(skb, &xt);
86 
87 	if (xt.hotdrop)
88 		ret = NF_DROP;
89 
90 	switch (ret) {
91 	case XT_CONTINUE:
92 		regs->verdict.code = NFT_CONTINUE;
93 		break;
94 	default:
95 		regs->verdict.code = ret;
96 		break;
97 	}
98 }
99 
100 static void nft_target_eval_bridge(const struct nft_expr *expr,
101 				   struct nft_regs *regs,
102 				   const struct nft_pktinfo *pkt)
103 {
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;
108 	int ret;
109 
110 	nft_compat_set_par(&xt, pkt, target, info);
111 
112 	ret = target->target(skb, &xt);
113 
114 	if (xt.hotdrop)
115 		ret = NF_DROP;
116 
117 	switch (ret) {
118 	case EBT_ACCEPT:
119 		regs->verdict.code = NF_ACCEPT;
120 		break;
121 	case EBT_DROP:
122 		regs->verdict.code = NF_DROP;
123 		break;
124 	case EBT_CONTINUE:
125 		regs->verdict.code = NFT_CONTINUE;
126 		break;
127 	case EBT_RETURN:
128 		regs->verdict.code = NFT_RETURN;
129 		break;
130 	default:
131 		regs->verdict.code = ret;
132 		break;
133 	}
134 }
135 
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]	= { .type = NLA_U32 },
139 	[NFTA_TARGET_INFO]	= { .type = NLA_BINARY },
140 };
141 
142 static void
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)
147 {
148 	par->net	= ctx->net;
149 	par->table	= ctx->table->name;
150 	switch (ctx->family) {
151 	case AF_INET:
152 		entry->e4.ip.proto = proto;
153 		entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
154 		break;
155 	case AF_INET6:
156 		if (proto)
157 			entry->e6.ipv6.flags |= IP6T_F_PROTO;
158 
159 		entry->e6.ipv6.proto = proto;
160 		entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
161 		break;
162 	case NFPROTO_BRIDGE:
163 		entry->ebt.ethproto = (__force __be16)proto;
164 		entry->ebt.invflags = inv ? EBT_IPROTO : 0;
165 		break;
166 	case NFPROTO_ARP:
167 		break;
168 	}
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;
176 
177 		par->hook_mask = 1 << ops->hooknum;
178 	} else {
179 		par->hook_mask = 0;
180 	}
181 	par->family	= ctx->family;
182 	par->nft_compat = true;
183 }
184 
185 static void target_compat_from_user(struct xt_target *t, void *in, void *out)
186 {
187 	int pad;
188 
189 	memcpy(out, in, t->targetsize);
190 	pad = XT_ALIGN(t->targetsize) - t->targetsize;
191 	if (pad > 0)
192 		memset(out + t->targetsize, 0, pad);
193 }
194 
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 },
198 };
199 
200 static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
201 {
202 	struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
203 	u32 flags;
204 	int err;
205 
206 	err = nla_parse_nested_deprecated(tb, NFTA_RULE_COMPAT_MAX, attr,
207 					  nft_rule_compat_policy, NULL);
208 	if (err < 0)
209 		return err;
210 
211 	if (!tb[NFTA_RULE_COMPAT_PROTO] || !tb[NFTA_RULE_COMPAT_FLAGS])
212 		return -EINVAL;
213 
214 	flags = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_FLAGS]));
215 	if (flags & ~NFT_RULE_COMPAT_F_MASK)
216 		return -EINVAL;
217 	if (flags & NFT_RULE_COMPAT_F_INV)
218 		*inv = true;
219 
220 	*proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO]));
221 	return 0;
222 }
223 
224 static void nft_compat_wait_for_destructors(void)
225 {
226 	/* xtables matches or targets can have side effects, e.g.
227 	 * creation/destruction of /proc files.
228 	 * The xt ->destroy functions are run asynchronously from
229 	 * work queue.  If we have pending invocations we thus
230 	 * need to wait for those to finish.
231 	 */
232 	nf_tables_trans_destroy_flush_work();
233 }
234 
235 static int
236 nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
237 		const struct nlattr * const tb[])
238 {
239 	void *info = nft_expr_priv(expr);
240 	struct xt_target *target = expr->ops->data;
241 	struct xt_tgchk_param par;
242 	size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO]));
243 	u16 proto = 0;
244 	bool inv = false;
245 	union nft_entry e = {};
246 	int ret;
247 
248 	target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
249 
250 	if (ctx->nla[NFTA_RULE_COMPAT]) {
251 		ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
252 		if (ret < 0)
253 			return ret;
254 	}
255 
256 	nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv);
257 
258 	nft_compat_wait_for_destructors();
259 
260 	ret = xt_check_target(&par, size, proto, inv);
261 	if (ret < 0) {
262 		if (ret == -ENOENT) {
263 			const char *modname = NULL;
264 
265 			if (strcmp(target->name, "LOG") == 0)
266 				modname = "nf_log_syslog";
267 			else if (strcmp(target->name, "NFLOG") == 0)
268 				modname = "nfnetlink_log";
269 
270 			if (modname &&
271 			    nft_request_module(ctx->net, "%s", modname) == -EAGAIN)
272 				return -EAGAIN;
273 		}
274 
275 		return ret;
276 	}
277 
278 	/* The standard target cannot be used */
279 	if (!target->target)
280 		return -EINVAL;
281 
282 	return 0;
283 }
284 
285 static void __nft_mt_tg_destroy(struct module *me, const struct nft_expr *expr)
286 {
287 	module_put(me);
288 	kfree(expr->ops);
289 }
290 
291 static void
292 nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
293 {
294 	struct xt_target *target = expr->ops->data;
295 	void *info = nft_expr_priv(expr);
296 	struct module *me = target->me;
297 	struct xt_tgdtor_param par;
298 
299 	par.net = ctx->net;
300 	par.target = target;
301 	par.targinfo = info;
302 	par.family = ctx->family;
303 	if (par.target->destroy != NULL)
304 		par.target->destroy(&par);
305 
306 	__nft_mt_tg_destroy(me, expr);
307 }
308 
309 static int nft_extension_dump_info(struct sk_buff *skb, int attr,
310 				   const void *info,
311 				   unsigned int size, unsigned int user_size)
312 {
313 	unsigned int info_size, aligned_size = XT_ALIGN(size);
314 	struct nlattr *nla;
315 
316 	nla = nla_reserve(skb, attr, aligned_size);
317 	if (!nla)
318 		return -1;
319 
320 	info_size = user_size ? : size;
321 	memcpy(nla_data(nla), info, info_size);
322 	memset(nla_data(nla) + info_size, 0, aligned_size - info_size);
323 
324 	return 0;
325 }
326 
327 static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr)
328 {
329 	const struct xt_target *target = expr->ops->data;
330 	void *info = nft_expr_priv(expr);
331 
332 	if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) ||
333 	    nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) ||
334 	    nft_extension_dump_info(skb, NFTA_TARGET_INFO, info,
335 				    target->targetsize, target->usersize))
336 		goto nla_put_failure;
337 
338 	return 0;
339 
340 nla_put_failure:
341 	return -1;
342 }
343 
344 static int nft_target_validate(const struct nft_ctx *ctx,
345 			       const struct nft_expr *expr,
346 			       const struct nft_data **data)
347 {
348 	struct xt_target *target = expr->ops->data;
349 	unsigned int hook_mask = 0;
350 	int ret;
351 
352 	if (nft_is_base_chain(ctx->chain)) {
353 		const struct nft_base_chain *basechain =
354 						nft_base_chain(ctx->chain);
355 		const struct nf_hook_ops *ops = &basechain->ops;
356 
357 		hook_mask = 1 << ops->hooknum;
358 		if (target->hooks && !(hook_mask & target->hooks))
359 			return -EINVAL;
360 
361 		ret = nft_compat_chain_validate_dependency(ctx, target->table);
362 		if (ret < 0)
363 			return ret;
364 	}
365 	return 0;
366 }
367 
368 static void __nft_match_eval(const struct nft_expr *expr,
369 			     struct nft_regs *regs,
370 			     const struct nft_pktinfo *pkt,
371 			     void *info)
372 {
373 	struct xt_match *match = expr->ops->data;
374 	struct sk_buff *skb = pkt->skb;
375 	struct xt_action_param xt;
376 	bool ret;
377 
378 	nft_compat_set_par(&xt, pkt, match, info);
379 
380 	ret = match->match(skb, &xt);
381 
382 	if (xt.hotdrop) {
383 		regs->verdict.code = NF_DROP;
384 		return;
385 	}
386 
387 	switch (ret ? 1 : 0) {
388 	case 1:
389 		regs->verdict.code = NFT_CONTINUE;
390 		break;
391 	case 0:
392 		regs->verdict.code = NFT_BREAK;
393 		break;
394 	}
395 }
396 
397 static void nft_match_large_eval(const struct nft_expr *expr,
398 				 struct nft_regs *regs,
399 				 const struct nft_pktinfo *pkt)
400 {
401 	struct nft_xt_match_priv *priv = nft_expr_priv(expr);
402 
403 	__nft_match_eval(expr, regs, pkt, priv->info);
404 }
405 
406 static void nft_match_eval(const struct nft_expr *expr,
407 			   struct nft_regs *regs,
408 			   const struct nft_pktinfo *pkt)
409 {
410 	__nft_match_eval(expr, regs, pkt, nft_expr_priv(expr));
411 }
412 
413 static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = {
414 	[NFTA_MATCH_NAME]	= { .type = NLA_NUL_STRING },
415 	[NFTA_MATCH_REV]	= { .type = NLA_U32 },
416 	[NFTA_MATCH_INFO]	= { .type = NLA_BINARY },
417 };
418 
419 /* struct xt_mtchk_param and xt_tgchk_param look very similar */
420 static void
421 nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
422 			  struct xt_match *match, void *info,
423 			  union nft_entry *entry, u16 proto, bool inv)
424 {
425 	par->net	= ctx->net;
426 	par->table	= ctx->table->name;
427 	switch (ctx->family) {
428 	case AF_INET:
429 		entry->e4.ip.proto = proto;
430 		entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
431 		break;
432 	case AF_INET6:
433 		if (proto)
434 			entry->e6.ipv6.flags |= IP6T_F_PROTO;
435 
436 		entry->e6.ipv6.proto = proto;
437 		entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
438 		break;
439 	case NFPROTO_BRIDGE:
440 		entry->ebt.ethproto = (__force __be16)proto;
441 		entry->ebt.invflags = inv ? EBT_IPROTO : 0;
442 		break;
443 	case NFPROTO_ARP:
444 		break;
445 	}
446 	par->entryinfo	= entry;
447 	par->match	= match;
448 	par->matchinfo	= info;
449 	if (nft_is_base_chain(ctx->chain)) {
450 		const struct nft_base_chain *basechain =
451 						nft_base_chain(ctx->chain);
452 		const struct nf_hook_ops *ops = &basechain->ops;
453 
454 		par->hook_mask = 1 << ops->hooknum;
455 	} else {
456 		par->hook_mask = 0;
457 	}
458 	par->family	= ctx->family;
459 	par->nft_compat = true;
460 }
461 
462 static void match_compat_from_user(struct xt_match *m, void *in, void *out)
463 {
464 	int pad;
465 
466 	memcpy(out, in, m->matchsize);
467 	pad = XT_ALIGN(m->matchsize) - m->matchsize;
468 	if (pad > 0)
469 		memset(out + m->matchsize, 0, pad);
470 }
471 
472 static int
473 __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
474 		 const struct nlattr * const tb[],
475 		 void *info)
476 {
477 	struct xt_match *match = expr->ops->data;
478 	struct xt_mtchk_param par;
479 	size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO]));
480 	u16 proto = 0;
481 	bool inv = false;
482 	union nft_entry e = {};
483 	int ret;
484 
485 	match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
486 
487 	if (ctx->nla[NFTA_RULE_COMPAT]) {
488 		ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
489 		if (ret < 0)
490 			return ret;
491 	}
492 
493 	nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv);
494 
495 	nft_compat_wait_for_destructors();
496 
497 	return xt_check_match(&par, size, proto, inv);
498 }
499 
500 static int
501 nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
502 	       const struct nlattr * const tb[])
503 {
504 	return __nft_match_init(ctx, expr, tb, nft_expr_priv(expr));
505 }
506 
507 static int
508 nft_match_large_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
509 		     const struct nlattr * const tb[])
510 {
511 	struct nft_xt_match_priv *priv = nft_expr_priv(expr);
512 	struct xt_match *m = expr->ops->data;
513 	int ret;
514 
515 	priv->info = kmalloc(XT_ALIGN(m->matchsize), GFP_KERNEL);
516 	if (!priv->info)
517 		return -ENOMEM;
518 
519 	ret = __nft_match_init(ctx, expr, tb, priv->info);
520 	if (ret)
521 		kfree(priv->info);
522 	return ret;
523 }
524 
525 static void
526 __nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr,
527 		    void *info)
528 {
529 	struct xt_match *match = expr->ops->data;
530 	struct module *me = match->me;
531 	struct xt_mtdtor_param par;
532 
533 	par.net = ctx->net;
534 	par.match = match;
535 	par.matchinfo = info;
536 	par.family = ctx->family;
537 	if (par.match->destroy != NULL)
538 		par.match->destroy(&par);
539 
540 	__nft_mt_tg_destroy(me, expr);
541 }
542 
543 static void
544 nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
545 {
546 	__nft_match_destroy(ctx, expr, nft_expr_priv(expr));
547 }
548 
549 static void
550 nft_match_large_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
551 {
552 	struct nft_xt_match_priv *priv = nft_expr_priv(expr);
553 
554 	__nft_match_destroy(ctx, expr, priv->info);
555 	kfree(priv->info);
556 }
557 
558 static int __nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr,
559 			    void *info)
560 {
561 	struct xt_match *match = expr->ops->data;
562 
563 	if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) ||
564 	    nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) ||
565 	    nft_extension_dump_info(skb, NFTA_MATCH_INFO, info,
566 				    match->matchsize, match->usersize))
567 		goto nla_put_failure;
568 
569 	return 0;
570 
571 nla_put_failure:
572 	return -1;
573 }
574 
575 static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr)
576 {
577 	return __nft_match_dump(skb, expr, nft_expr_priv(expr));
578 }
579 
580 static int nft_match_large_dump(struct sk_buff *skb, const struct nft_expr *e)
581 {
582 	struct nft_xt_match_priv *priv = nft_expr_priv(e);
583 
584 	return __nft_match_dump(skb, e, priv->info);
585 }
586 
587 static int nft_match_validate(const struct nft_ctx *ctx,
588 			      const struct nft_expr *expr,
589 			      const struct nft_data **data)
590 {
591 	struct xt_match *match = expr->ops->data;
592 	unsigned int hook_mask = 0;
593 	int ret;
594 
595 	if (nft_is_base_chain(ctx->chain)) {
596 		const struct nft_base_chain *basechain =
597 						nft_base_chain(ctx->chain);
598 		const struct nf_hook_ops *ops = &basechain->ops;
599 
600 		hook_mask = 1 << ops->hooknum;
601 		if (match->hooks && !(hook_mask & match->hooks))
602 			return -EINVAL;
603 
604 		ret = nft_compat_chain_validate_dependency(ctx, match->table);
605 		if (ret < 0)
606 			return ret;
607 	}
608 	return 0;
609 }
610 
611 static int
612 nfnl_compat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
613 		      int event, u16 family, const char *name,
614 		      int rev, int target)
615 {
616 	struct nlmsghdr *nlh;
617 	unsigned int flags = portid ? NLM_F_MULTI : 0;
618 
619 	event = nfnl_msg_type(NFNL_SUBSYS_NFT_COMPAT, event);
620 	nlh = nfnl_msg_put(skb, portid, seq, event, flags, family,
621 			   NFNETLINK_V0, 0);
622 	if (!nlh)
623 		goto nlmsg_failure;
624 
625 	if (nla_put_string(skb, NFTA_COMPAT_NAME, name) ||
626 	    nla_put_be32(skb, NFTA_COMPAT_REV, htonl(rev)) ||
627 	    nla_put_be32(skb, NFTA_COMPAT_TYPE, htonl(target)))
628 		goto nla_put_failure;
629 
630 	nlmsg_end(skb, nlh);
631 	return skb->len;
632 
633 nlmsg_failure:
634 nla_put_failure:
635 	nlmsg_cancel(skb, nlh);
636 	return -1;
637 }
638 
639 static int nfnl_compat_get_rcu(struct sk_buff *skb,
640 			       const struct nfnl_info *info,
641 			       const struct nlattr * const tb[])
642 {
643 	u8 family = info->nfmsg->nfgen_family;
644 	const char *name, *fmt;
645 	struct sk_buff *skb2;
646 	int ret = 0, target;
647 	u32 rev;
648 
649 	if (tb[NFTA_COMPAT_NAME] == NULL ||
650 	    tb[NFTA_COMPAT_REV] == NULL ||
651 	    tb[NFTA_COMPAT_TYPE] == NULL)
652 		return -EINVAL;
653 
654 	name = nla_data(tb[NFTA_COMPAT_NAME]);
655 	rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV]));
656 	target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE]));
657 
658 	switch(family) {
659 	case AF_INET:
660 		fmt = "ipt_%s";
661 		break;
662 	case AF_INET6:
663 		fmt = "ip6t_%s";
664 		break;
665 	case NFPROTO_BRIDGE:
666 		fmt = "ebt_%s";
667 		break;
668 	case NFPROTO_ARP:
669 		fmt = "arpt_%s";
670 		break;
671 	default:
672 		pr_err("nft_compat: unsupported protocol %d\n", family);
673 		return -EINVAL;
674 	}
675 
676 	if (!try_module_get(THIS_MODULE))
677 		return -EINVAL;
678 
679 	rcu_read_unlock();
680 	try_then_request_module(xt_find_revision(family, name, rev, target, &ret),
681 				fmt, name);
682 	if (ret < 0)
683 		goto out_put;
684 
685 	skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
686 	if (skb2 == NULL) {
687 		ret = -ENOMEM;
688 		goto out_put;
689 	}
690 
691 	/* include the best revision for this extension in the message */
692 	if (nfnl_compat_fill_info(skb2, NETLINK_CB(skb).portid,
693 				  info->nlh->nlmsg_seq,
694 				  NFNL_MSG_TYPE(info->nlh->nlmsg_type),
695 				  NFNL_MSG_COMPAT_GET,
696 				  family, name, ret, target) <= 0) {
697 		kfree_skb(skb2);
698 		goto out_put;
699 	}
700 
701 	ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
702 out_put:
703 	rcu_read_lock();
704 	module_put(THIS_MODULE);
705 
706 	return ret;
707 }
708 
709 static const struct nla_policy nfnl_compat_policy_get[NFTA_COMPAT_MAX+1] = {
710 	[NFTA_COMPAT_NAME]	= { .type = NLA_NUL_STRING,
711 				    .len = NFT_COMPAT_NAME_MAX-1 },
712 	[NFTA_COMPAT_REV]	= { .type = NLA_U32 },
713 	[NFTA_COMPAT_TYPE]	= { .type = NLA_U32 },
714 };
715 
716 static const struct nfnl_callback nfnl_nft_compat_cb[NFNL_MSG_COMPAT_MAX] = {
717 	[NFNL_MSG_COMPAT_GET]	= {
718 		.call		= nfnl_compat_get_rcu,
719 		.type		= NFNL_CB_RCU,
720 		.attr_count	= NFTA_COMPAT_MAX,
721 		.policy		= nfnl_compat_policy_get
722 	},
723 };
724 
725 static const struct nfnetlink_subsystem nfnl_compat_subsys = {
726 	.name		= "nft-compat",
727 	.subsys_id	= NFNL_SUBSYS_NFT_COMPAT,
728 	.cb_count	= NFNL_MSG_COMPAT_MAX,
729 	.cb		= nfnl_nft_compat_cb,
730 };
731 
732 static struct nft_expr_type nft_match_type;
733 
734 static const struct nft_expr_ops *
735 nft_match_select_ops(const struct nft_ctx *ctx,
736 		     const struct nlattr * const tb[])
737 {
738 	struct nft_expr_ops *ops;
739 	struct xt_match *match;
740 	unsigned int matchsize;
741 	char *mt_name;
742 	u32 rev, family;
743 	int err;
744 
745 	if (tb[NFTA_MATCH_NAME] == NULL ||
746 	    tb[NFTA_MATCH_REV] == NULL ||
747 	    tb[NFTA_MATCH_INFO] == NULL)
748 		return ERR_PTR(-EINVAL);
749 
750 	mt_name = nla_data(tb[NFTA_MATCH_NAME]);
751 	rev = ntohl(nla_get_be32(tb[NFTA_MATCH_REV]));
752 	family = ctx->family;
753 
754 	match = xt_request_find_match(family, mt_name, rev);
755 	if (IS_ERR(match))
756 		return ERR_PTR(-ENOENT);
757 
758 	if (match->matchsize > nla_len(tb[NFTA_MATCH_INFO])) {
759 		err = -EINVAL;
760 		goto err;
761 	}
762 
763 	ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL);
764 	if (!ops) {
765 		err = -ENOMEM;
766 		goto err;
767 	}
768 
769 	ops->type = &nft_match_type;
770 	ops->eval = nft_match_eval;
771 	ops->init = nft_match_init;
772 	ops->destroy = nft_match_destroy;
773 	ops->dump = nft_match_dump;
774 	ops->validate = nft_match_validate;
775 	ops->data = match;
776 
777 	matchsize = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize));
778 	if (matchsize > NFT_MATCH_LARGE_THRESH) {
779 		matchsize = NFT_EXPR_SIZE(sizeof(struct nft_xt_match_priv));
780 
781 		ops->eval = nft_match_large_eval;
782 		ops->init = nft_match_large_init;
783 		ops->destroy = nft_match_large_destroy;
784 		ops->dump = nft_match_large_dump;
785 	}
786 
787 	ops->size = matchsize;
788 
789 	return ops;
790 err:
791 	module_put(match->me);
792 	return ERR_PTR(err);
793 }
794 
795 static void nft_match_release_ops(const struct nft_expr_ops *ops)
796 {
797 	struct xt_match *match = ops->data;
798 
799 	module_put(match->me);
800 	kfree(ops);
801 }
802 
803 static struct nft_expr_type nft_match_type __read_mostly = {
804 	.name		= "match",
805 	.select_ops	= nft_match_select_ops,
806 	.release_ops	= nft_match_release_ops,
807 	.policy		= nft_match_policy,
808 	.maxattr	= NFTA_MATCH_MAX,
809 	.owner		= THIS_MODULE,
810 };
811 
812 static struct nft_expr_type nft_target_type;
813 
814 static const struct nft_expr_ops *
815 nft_target_select_ops(const struct nft_ctx *ctx,
816 		      const struct nlattr * const tb[])
817 {
818 	struct nft_expr_ops *ops;
819 	struct xt_target *target;
820 	char *tg_name;
821 	u32 rev, family;
822 	int err;
823 
824 	if (tb[NFTA_TARGET_NAME] == NULL ||
825 	    tb[NFTA_TARGET_REV] == NULL ||
826 	    tb[NFTA_TARGET_INFO] == NULL)
827 		return ERR_PTR(-EINVAL);
828 
829 	tg_name = nla_data(tb[NFTA_TARGET_NAME]);
830 	rev = ntohl(nla_get_be32(tb[NFTA_TARGET_REV]));
831 	family = ctx->family;
832 
833 	if (strcmp(tg_name, XT_ERROR_TARGET) == 0 ||
834 	    strcmp(tg_name, XT_STANDARD_TARGET) == 0 ||
835 	    strcmp(tg_name, "standard") == 0)
836 		return ERR_PTR(-EINVAL);
837 
838 	target = xt_request_find_target(family, tg_name, rev);
839 	if (IS_ERR(target))
840 		return ERR_PTR(-ENOENT);
841 
842 	if (!target->target) {
843 		err = -EINVAL;
844 		goto err;
845 	}
846 
847 	if (target->targetsize > nla_len(tb[NFTA_TARGET_INFO])) {
848 		err = -EINVAL;
849 		goto err;
850 	}
851 
852 	ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL);
853 	if (!ops) {
854 		err = -ENOMEM;
855 		goto err;
856 	}
857 
858 	ops->type = &nft_target_type;
859 	ops->size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
860 	ops->init = nft_target_init;
861 	ops->destroy = nft_target_destroy;
862 	ops->dump = nft_target_dump;
863 	ops->validate = nft_target_validate;
864 	ops->data = target;
865 
866 	if (family == NFPROTO_BRIDGE)
867 		ops->eval = nft_target_eval_bridge;
868 	else
869 		ops->eval = nft_target_eval_xt;
870 
871 	return ops;
872 err:
873 	module_put(target->me);
874 	return ERR_PTR(err);
875 }
876 
877 static void nft_target_release_ops(const struct nft_expr_ops *ops)
878 {
879 	struct xt_target *target = ops->data;
880 
881 	module_put(target->me);
882 	kfree(ops);
883 }
884 
885 static struct nft_expr_type nft_target_type __read_mostly = {
886 	.name		= "target",
887 	.select_ops	= nft_target_select_ops,
888 	.release_ops	= nft_target_release_ops,
889 	.policy		= nft_target_policy,
890 	.maxattr	= NFTA_TARGET_MAX,
891 	.owner		= THIS_MODULE,
892 };
893 
894 static int __init nft_compat_module_init(void)
895 {
896 	int ret;
897 
898 	ret = nft_register_expr(&nft_match_type);
899 	if (ret < 0)
900 		return ret;
901 
902 	ret = nft_register_expr(&nft_target_type);
903 	if (ret < 0)
904 		goto err_match;
905 
906 	ret = nfnetlink_subsys_register(&nfnl_compat_subsys);
907 	if (ret < 0) {
908 		pr_err("nft_compat: cannot register with nfnetlink.\n");
909 		goto err_target;
910 	}
911 
912 	return ret;
913 err_target:
914 	nft_unregister_expr(&nft_target_type);
915 err_match:
916 	nft_unregister_expr(&nft_match_type);
917 	return ret;
918 }
919 
920 static void __exit nft_compat_module_exit(void)
921 {
922 	nfnetlink_subsys_unregister(&nfnl_compat_subsys);
923 	nft_unregister_expr(&nft_target_type);
924 	nft_unregister_expr(&nft_match_type);
925 }
926 
927 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT);
928 
929 module_init(nft_compat_module_init);
930 module_exit(nft_compat_module_exit);
931 
932 MODULE_LICENSE("GPL");
933 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
934 MODULE_ALIAS_NFT_EXPR("match");
935 MODULE_ALIAS_NFT_EXPR("target");
936 MODULE_DESCRIPTION("x_tables over nftables support");
937