xref: /linux-6.15/net/netfilter/nft_ct.c (revision 564f7dfd)
1 /*
2  * Copyright (c) 2008-2009 Patrick McHardy <[email protected]>
3  * Copyright (c) 2016 Pablo Neira Ayuso <[email protected]>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Development of this code funded by Astaro AG (http://www.astaro.com/)
10  */
11 
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/netlink.h>
16 #include <linux/netfilter.h>
17 #include <linux/netfilter/nf_tables.h>
18 #include <net/netfilter/nf_tables.h>
19 #include <net/netfilter/nf_conntrack.h>
20 #include <net/netfilter/nf_conntrack_acct.h>
21 #include <net/netfilter/nf_conntrack_tuple.h>
22 #include <net/netfilter/nf_conntrack_helper.h>
23 #include <net/netfilter/nf_conntrack_ecache.h>
24 #include <net/netfilter/nf_conntrack_labels.h>
25 
26 struct nft_ct {
27 	enum nft_ct_keys	key:8;
28 	enum ip_conntrack_dir	dir:8;
29 	union {
30 		enum nft_registers	dreg:8;
31 		enum nft_registers	sreg:8;
32 	};
33 };
34 
35 #ifdef CONFIG_NF_CONNTRACK_ZONES
36 static DEFINE_PER_CPU(struct nf_conn *, nft_ct_pcpu_template);
37 static unsigned int nft_ct_pcpu_template_refcnt __read_mostly;
38 #endif
39 
40 static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c,
41 				   enum nft_ct_keys k,
42 				   enum ip_conntrack_dir d)
43 {
44 	if (d < IP_CT_DIR_MAX)
45 		return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) :
46 					   atomic64_read(&c[d].packets);
47 
48 	return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) +
49 	       nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY);
50 }
51 
52 static void nft_ct_get_eval(const struct nft_expr *expr,
53 			    struct nft_regs *regs,
54 			    const struct nft_pktinfo *pkt)
55 {
56 	const struct nft_ct *priv = nft_expr_priv(expr);
57 	u32 *dest = &regs->data[priv->dreg];
58 	enum ip_conntrack_info ctinfo;
59 	const struct nf_conn *ct;
60 	const struct nf_conn_help *help;
61 	const struct nf_conntrack_tuple *tuple;
62 	const struct nf_conntrack_helper *helper;
63 	unsigned int state;
64 
65 	ct = nf_ct_get(pkt->skb, &ctinfo);
66 
67 	switch (priv->key) {
68 	case NFT_CT_STATE:
69 		if (ct == NULL)
70 			state = NF_CT_STATE_INVALID_BIT;
71 		else if (nf_ct_is_untracked(ct))
72 			state = NF_CT_STATE_UNTRACKED_BIT;
73 		else
74 			state = NF_CT_STATE_BIT(ctinfo);
75 		*dest = state;
76 		return;
77 	default:
78 		break;
79 	}
80 
81 	if (ct == NULL)
82 		goto err;
83 
84 	switch (priv->key) {
85 	case NFT_CT_DIRECTION:
86 		nft_reg_store8(dest, CTINFO2DIR(ctinfo));
87 		return;
88 	case NFT_CT_STATUS:
89 		*dest = ct->status;
90 		return;
91 #ifdef CONFIG_NF_CONNTRACK_MARK
92 	case NFT_CT_MARK:
93 		*dest = ct->mark;
94 		return;
95 #endif
96 #ifdef CONFIG_NF_CONNTRACK_SECMARK
97 	case NFT_CT_SECMARK:
98 		*dest = ct->secmark;
99 		return;
100 #endif
101 	case NFT_CT_EXPIRATION:
102 		*dest = jiffies_to_msecs(nf_ct_expires(ct));
103 		return;
104 	case NFT_CT_HELPER:
105 		if (ct->master == NULL)
106 			goto err;
107 		help = nfct_help(ct->master);
108 		if (help == NULL)
109 			goto err;
110 		helper = rcu_dereference(help->helper);
111 		if (helper == NULL)
112 			goto err;
113 		strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
114 		return;
115 #ifdef CONFIG_NF_CONNTRACK_LABELS
116 	case NFT_CT_LABELS: {
117 		struct nf_conn_labels *labels = nf_ct_labels_find(ct);
118 
119 		if (labels)
120 			memcpy(dest, labels->bits, NF_CT_LABELS_MAX_SIZE);
121 		else
122 			memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
123 		return;
124 	}
125 #endif
126 	case NFT_CT_BYTES: /* fallthrough */
127 	case NFT_CT_PKTS: {
128 		const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
129 		u64 count = 0;
130 
131 		if (acct)
132 			count = nft_ct_get_eval_counter(acct->counter,
133 							priv->key, priv->dir);
134 		memcpy(dest, &count, sizeof(count));
135 		return;
136 	}
137 	case NFT_CT_AVGPKT: {
138 		const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
139 		u64 avgcnt = 0, bcnt = 0, pcnt = 0;
140 
141 		if (acct) {
142 			pcnt = nft_ct_get_eval_counter(acct->counter,
143 						       NFT_CT_PKTS, priv->dir);
144 			bcnt = nft_ct_get_eval_counter(acct->counter,
145 						       NFT_CT_BYTES, priv->dir);
146 			if (pcnt != 0)
147 				avgcnt = div64_u64(bcnt, pcnt);
148 		}
149 
150 		memcpy(dest, &avgcnt, sizeof(avgcnt));
151 		return;
152 	}
153 	case NFT_CT_L3PROTOCOL:
154 		nft_reg_store8(dest, nf_ct_l3num(ct));
155 		return;
156 	case NFT_CT_PROTOCOL:
157 		nft_reg_store8(dest, nf_ct_protonum(ct));
158 		return;
159 #ifdef CONFIG_NF_CONNTRACK_ZONES
160 	case NFT_CT_ZONE: {
161 		const struct nf_conntrack_zone *zone = nf_ct_zone(ct);
162 		u16 zoneid;
163 
164 		if (priv->dir < IP_CT_DIR_MAX)
165 			zoneid = nf_ct_zone_id(zone, priv->dir);
166 		else
167 			zoneid = zone->id;
168 
169 		nft_reg_store16(dest, zoneid);
170 		return;
171 	}
172 #endif
173 	default:
174 		break;
175 	}
176 
177 	tuple = &ct->tuplehash[priv->dir].tuple;
178 	switch (priv->key) {
179 	case NFT_CT_SRC:
180 		memcpy(dest, tuple->src.u3.all,
181 		       nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
182 		return;
183 	case NFT_CT_DST:
184 		memcpy(dest, tuple->dst.u3.all,
185 		       nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
186 		return;
187 	case NFT_CT_PROTO_SRC:
188 		nft_reg_store16(dest, (__force u16)tuple->src.u.all);
189 		return;
190 	case NFT_CT_PROTO_DST:
191 		nft_reg_store16(dest, (__force u16)tuple->dst.u.all);
192 		return;
193 	default:
194 		break;
195 	}
196 	return;
197 err:
198 	regs->verdict.code = NFT_BREAK;
199 }
200 
201 #ifdef CONFIG_NF_CONNTRACK_ZONES
202 static void nft_ct_set_zone_eval(const struct nft_expr *expr,
203 				 struct nft_regs *regs,
204 				 const struct nft_pktinfo *pkt)
205 {
206 	struct nf_conntrack_zone zone = { .dir = NF_CT_DEFAULT_ZONE_DIR };
207 	const struct nft_ct *priv = nft_expr_priv(expr);
208 	struct sk_buff *skb = pkt->skb;
209 	enum ip_conntrack_info ctinfo;
210 	u16 value = nft_reg_load16(&regs->data[priv->sreg]);
211 	struct nf_conn *ct;
212 
213 	ct = nf_ct_get(skb, &ctinfo);
214 	if (ct) /* already tracked */
215 		return;
216 
217 	zone.id = value;
218 
219 	switch (priv->dir) {
220 	case IP_CT_DIR_ORIGINAL:
221 		zone.dir = NF_CT_ZONE_DIR_ORIG;
222 		break;
223 	case IP_CT_DIR_REPLY:
224 		zone.dir = NF_CT_ZONE_DIR_REPL;
225 		break;
226 	default:
227 		break;
228 	}
229 
230 	ct = this_cpu_read(nft_ct_pcpu_template);
231 
232 	if (likely(atomic_read(&ct->ct_general.use) == 1)) {
233 		nf_ct_zone_add(ct, &zone);
234 	} else {
235 		/* previous skb got queued to userspace */
236 		ct = nf_ct_tmpl_alloc(nft_net(pkt), &zone, GFP_ATOMIC);
237 		if (!ct) {
238 			regs->verdict.code = NF_DROP;
239 			return;
240 		}
241 	}
242 
243 	atomic_inc(&ct->ct_general.use);
244 	nf_ct_set(skb, ct, IP_CT_NEW);
245 }
246 #endif
247 
248 static void nft_ct_set_eval(const struct nft_expr *expr,
249 			    struct nft_regs *regs,
250 			    const struct nft_pktinfo *pkt)
251 {
252 	const struct nft_ct *priv = nft_expr_priv(expr);
253 	struct sk_buff *skb = pkt->skb;
254 #ifdef CONFIG_NF_CONNTRACK_MARK
255 	u32 value = regs->data[priv->sreg];
256 #endif
257 	enum ip_conntrack_info ctinfo;
258 	struct nf_conn *ct;
259 
260 	ct = nf_ct_get(skb, &ctinfo);
261 	if (ct == NULL)
262 		return;
263 
264 	switch (priv->key) {
265 #ifdef CONFIG_NF_CONNTRACK_MARK
266 	case NFT_CT_MARK:
267 		if (ct->mark != value) {
268 			ct->mark = value;
269 			nf_conntrack_event_cache(IPCT_MARK, ct);
270 		}
271 		break;
272 #endif
273 #ifdef CONFIG_NF_CONNTRACK_LABELS
274 	case NFT_CT_LABELS:
275 		nf_connlabels_replace(ct,
276 				      &regs->data[priv->sreg],
277 				      &regs->data[priv->sreg],
278 				      NF_CT_LABELS_MAX_SIZE / sizeof(u32));
279 		break;
280 #endif
281 	default:
282 		break;
283 	}
284 }
285 
286 static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
287 	[NFTA_CT_DREG]		= { .type = NLA_U32 },
288 	[NFTA_CT_KEY]		= { .type = NLA_U32 },
289 	[NFTA_CT_DIRECTION]	= { .type = NLA_U8 },
290 	[NFTA_CT_SREG]		= { .type = NLA_U32 },
291 };
292 
293 static int nft_ct_netns_get(struct net *net, uint8_t family)
294 {
295 	int err;
296 
297 	if (family == NFPROTO_INET) {
298 		err = nf_ct_netns_get(net, NFPROTO_IPV4);
299 		if (err < 0)
300 			goto err1;
301 		err = nf_ct_netns_get(net, NFPROTO_IPV6);
302 		if (err < 0)
303 			goto err2;
304 	} else {
305 		err = nf_ct_netns_get(net, family);
306 		if (err < 0)
307 			goto err1;
308 	}
309 	return 0;
310 
311 err2:
312 	nf_ct_netns_put(net, NFPROTO_IPV4);
313 err1:
314 	return err;
315 }
316 
317 static void nft_ct_netns_put(struct net *net, uint8_t family)
318 {
319 	if (family == NFPROTO_INET) {
320 		nf_ct_netns_put(net, NFPROTO_IPV4);
321 		nf_ct_netns_put(net, NFPROTO_IPV6);
322 	} else
323 		nf_ct_netns_put(net, family);
324 }
325 
326 #ifdef CONFIG_NF_CONNTRACK_ZONES
327 static void nft_ct_tmpl_put_pcpu(void)
328 {
329 	struct nf_conn *ct;
330 	int cpu;
331 
332 	for_each_possible_cpu(cpu) {
333 		ct = per_cpu(nft_ct_pcpu_template, cpu);
334 		if (!ct)
335 			break;
336 		nf_ct_put(ct);
337 		per_cpu(nft_ct_pcpu_template, cpu) = NULL;
338 	}
339 }
340 
341 static bool nft_ct_tmpl_alloc_pcpu(void)
342 {
343 	struct nf_conntrack_zone zone = { .id = 0 };
344 	struct nf_conn *tmp;
345 	int cpu;
346 
347 	if (nft_ct_pcpu_template_refcnt)
348 		return true;
349 
350 	for_each_possible_cpu(cpu) {
351 		tmp = nf_ct_tmpl_alloc(&init_net, &zone, GFP_KERNEL);
352 		if (!tmp) {
353 			nft_ct_tmpl_put_pcpu();
354 			return false;
355 		}
356 
357 		atomic_set(&tmp->ct_general.use, 1);
358 		per_cpu(nft_ct_pcpu_template, cpu) = tmp;
359 	}
360 
361 	return true;
362 }
363 #endif
364 
365 static int nft_ct_get_init(const struct nft_ctx *ctx,
366 			   const struct nft_expr *expr,
367 			   const struct nlattr * const tb[])
368 {
369 	struct nft_ct *priv = nft_expr_priv(expr);
370 	unsigned int len;
371 	int err;
372 
373 	priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
374 	priv->dir = IP_CT_DIR_MAX;
375 	switch (priv->key) {
376 	case NFT_CT_DIRECTION:
377 		if (tb[NFTA_CT_DIRECTION] != NULL)
378 			return -EINVAL;
379 		len = sizeof(u8);
380 		break;
381 	case NFT_CT_STATE:
382 	case NFT_CT_STATUS:
383 #ifdef CONFIG_NF_CONNTRACK_MARK
384 	case NFT_CT_MARK:
385 #endif
386 #ifdef CONFIG_NF_CONNTRACK_SECMARK
387 	case NFT_CT_SECMARK:
388 #endif
389 	case NFT_CT_EXPIRATION:
390 		if (tb[NFTA_CT_DIRECTION] != NULL)
391 			return -EINVAL;
392 		len = sizeof(u32);
393 		break;
394 #ifdef CONFIG_NF_CONNTRACK_LABELS
395 	case NFT_CT_LABELS:
396 		if (tb[NFTA_CT_DIRECTION] != NULL)
397 			return -EINVAL;
398 		len = NF_CT_LABELS_MAX_SIZE;
399 		break;
400 #endif
401 	case NFT_CT_HELPER:
402 		if (tb[NFTA_CT_DIRECTION] != NULL)
403 			return -EINVAL;
404 		len = NF_CT_HELPER_NAME_LEN;
405 		break;
406 
407 	case NFT_CT_L3PROTOCOL:
408 	case NFT_CT_PROTOCOL:
409 		/* For compatibility, do not report error if NFTA_CT_DIRECTION
410 		 * attribute is specified.
411 		 */
412 		len = sizeof(u8);
413 		break;
414 	case NFT_CT_SRC:
415 	case NFT_CT_DST:
416 		if (tb[NFTA_CT_DIRECTION] == NULL)
417 			return -EINVAL;
418 
419 		switch (ctx->afi->family) {
420 		case NFPROTO_IPV4:
421 			len = FIELD_SIZEOF(struct nf_conntrack_tuple,
422 					   src.u3.ip);
423 			break;
424 		case NFPROTO_IPV6:
425 		case NFPROTO_INET:
426 			len = FIELD_SIZEOF(struct nf_conntrack_tuple,
427 					   src.u3.ip6);
428 			break;
429 		default:
430 			return -EAFNOSUPPORT;
431 		}
432 		break;
433 	case NFT_CT_PROTO_SRC:
434 	case NFT_CT_PROTO_DST:
435 		if (tb[NFTA_CT_DIRECTION] == NULL)
436 			return -EINVAL;
437 		len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
438 		break;
439 	case NFT_CT_BYTES:
440 	case NFT_CT_PKTS:
441 	case NFT_CT_AVGPKT:
442 		len = sizeof(u64);
443 		break;
444 #ifdef CONFIG_NF_CONNTRACK_ZONES
445 	case NFT_CT_ZONE:
446 		len = sizeof(u16);
447 		break;
448 #endif
449 	default:
450 		return -EOPNOTSUPP;
451 	}
452 
453 	if (tb[NFTA_CT_DIRECTION] != NULL) {
454 		priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
455 		switch (priv->dir) {
456 		case IP_CT_DIR_ORIGINAL:
457 		case IP_CT_DIR_REPLY:
458 			break;
459 		default:
460 			return -EINVAL;
461 		}
462 	}
463 
464 	priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
465 	err = nft_validate_register_store(ctx, priv->dreg, NULL,
466 					  NFT_DATA_VALUE, len);
467 	if (err < 0)
468 		return err;
469 
470 	err = nft_ct_netns_get(ctx->net, ctx->afi->family);
471 	if (err < 0)
472 		return err;
473 
474 	if (priv->key == NFT_CT_BYTES ||
475 	    priv->key == NFT_CT_PKTS  ||
476 	    priv->key == NFT_CT_AVGPKT)
477 		nf_ct_set_acct(ctx->net, true);
478 
479 	return 0;
480 }
481 
482 static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv)
483 {
484 	switch (priv->key) {
485 #ifdef CONFIG_NF_CONNTRACK_LABELS
486 	case NFT_CT_LABELS:
487 		nf_connlabels_put(ctx->net);
488 		break;
489 #endif
490 #ifdef CONFIG_NF_CONNTRACK_ZONES
491 	case NFT_CT_ZONE:
492 		if (--nft_ct_pcpu_template_refcnt == 0)
493 			nft_ct_tmpl_put_pcpu();
494 #endif
495 	default:
496 		break;
497 	}
498 }
499 
500 static int nft_ct_set_init(const struct nft_ctx *ctx,
501 			   const struct nft_expr *expr,
502 			   const struct nlattr * const tb[])
503 {
504 	struct nft_ct *priv = nft_expr_priv(expr);
505 	unsigned int len;
506 	int err;
507 
508 	priv->dir = IP_CT_DIR_MAX;
509 	priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
510 	switch (priv->key) {
511 #ifdef CONFIG_NF_CONNTRACK_MARK
512 	case NFT_CT_MARK:
513 		if (tb[NFTA_CT_DIRECTION])
514 			return -EINVAL;
515 		len = FIELD_SIZEOF(struct nf_conn, mark);
516 		break;
517 #endif
518 #ifdef CONFIG_NF_CONNTRACK_LABELS
519 	case NFT_CT_LABELS:
520 		if (tb[NFTA_CT_DIRECTION])
521 			return -EINVAL;
522 		len = NF_CT_LABELS_MAX_SIZE;
523 		err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
524 		if (err)
525 			return err;
526 		break;
527 #endif
528 #ifdef CONFIG_NF_CONNTRACK_ZONES
529 	case NFT_CT_ZONE:
530 		if (!nft_ct_tmpl_alloc_pcpu())
531 			return -ENOMEM;
532 		nft_ct_pcpu_template_refcnt++;
533 		len = sizeof(u16);
534 		break;
535 #endif
536 	default:
537 		return -EOPNOTSUPP;
538 	}
539 
540 	if (tb[NFTA_CT_DIRECTION]) {
541 		priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
542 		switch (priv->dir) {
543 		case IP_CT_DIR_ORIGINAL:
544 		case IP_CT_DIR_REPLY:
545 			break;
546 		default:
547 			err = -EINVAL;
548 			goto err1;
549 		}
550 	}
551 
552 	priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
553 	err = nft_validate_register_load(priv->sreg, len);
554 	if (err < 0)
555 		goto err1;
556 
557 	err = nft_ct_netns_get(ctx->net, ctx->afi->family);
558 	if (err < 0)
559 		goto err1;
560 
561 	return 0;
562 
563 err1:
564 	__nft_ct_set_destroy(ctx, priv);
565 	return err;
566 }
567 
568 static void nft_ct_get_destroy(const struct nft_ctx *ctx,
569 			       const struct nft_expr *expr)
570 {
571 	nf_ct_netns_put(ctx->net, ctx->afi->family);
572 }
573 
574 static void nft_ct_set_destroy(const struct nft_ctx *ctx,
575 			       const struct nft_expr *expr)
576 {
577 	struct nft_ct *priv = nft_expr_priv(expr);
578 
579 	__nft_ct_set_destroy(ctx, priv);
580 	nft_ct_netns_put(ctx->net, ctx->afi->family);
581 }
582 
583 static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
584 {
585 	const struct nft_ct *priv = nft_expr_priv(expr);
586 
587 	if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
588 		goto nla_put_failure;
589 	if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
590 		goto nla_put_failure;
591 
592 	switch (priv->key) {
593 	case NFT_CT_SRC:
594 	case NFT_CT_DST:
595 	case NFT_CT_PROTO_SRC:
596 	case NFT_CT_PROTO_DST:
597 		if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
598 			goto nla_put_failure;
599 		break;
600 	case NFT_CT_BYTES:
601 	case NFT_CT_PKTS:
602 	case NFT_CT_AVGPKT:
603 	case NFT_CT_ZONE:
604 		if (priv->dir < IP_CT_DIR_MAX &&
605 		    nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
606 			goto nla_put_failure;
607 		break;
608 	default:
609 		break;
610 	}
611 
612 	return 0;
613 
614 nla_put_failure:
615 	return -1;
616 }
617 
618 static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
619 {
620 	const struct nft_ct *priv = nft_expr_priv(expr);
621 
622 	if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
623 		goto nla_put_failure;
624 	if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
625 		goto nla_put_failure;
626 
627 	switch (priv->key) {
628 	case NFT_CT_ZONE:
629 		if (priv->dir < IP_CT_DIR_MAX &&
630 		    nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
631 			goto nla_put_failure;
632 		break;
633 	default:
634 		break;
635 	}
636 
637 	return 0;
638 
639 nla_put_failure:
640 	return -1;
641 }
642 
643 static struct nft_expr_type nft_ct_type;
644 static const struct nft_expr_ops nft_ct_get_ops = {
645 	.type		= &nft_ct_type,
646 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_ct)),
647 	.eval		= nft_ct_get_eval,
648 	.init		= nft_ct_get_init,
649 	.destroy	= nft_ct_get_destroy,
650 	.dump		= nft_ct_get_dump,
651 };
652 
653 static const struct nft_expr_ops nft_ct_set_ops = {
654 	.type		= &nft_ct_type,
655 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_ct)),
656 	.eval		= nft_ct_set_eval,
657 	.init		= nft_ct_set_init,
658 	.destroy	= nft_ct_set_destroy,
659 	.dump		= nft_ct_set_dump,
660 };
661 
662 #ifdef CONFIG_NF_CONNTRACK_ZONES
663 static const struct nft_expr_ops nft_ct_set_zone_ops = {
664 	.type		= &nft_ct_type,
665 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_ct)),
666 	.eval		= nft_ct_set_zone_eval,
667 	.init		= nft_ct_set_init,
668 	.destroy	= nft_ct_set_destroy,
669 	.dump		= nft_ct_set_dump,
670 };
671 #endif
672 
673 static const struct nft_expr_ops *
674 nft_ct_select_ops(const struct nft_ctx *ctx,
675 		    const struct nlattr * const tb[])
676 {
677 	if (tb[NFTA_CT_KEY] == NULL)
678 		return ERR_PTR(-EINVAL);
679 
680 	if (tb[NFTA_CT_DREG] && tb[NFTA_CT_SREG])
681 		return ERR_PTR(-EINVAL);
682 
683 	if (tb[NFTA_CT_DREG])
684 		return &nft_ct_get_ops;
685 
686 	if (tb[NFTA_CT_SREG]) {
687 #ifdef CONFIG_NF_CONNTRACK_ZONES
688 		if (nla_get_be32(tb[NFTA_CT_KEY]) == htonl(NFT_CT_ZONE))
689 			return &nft_ct_set_zone_ops;
690 #endif
691 		return &nft_ct_set_ops;
692 	}
693 
694 	return ERR_PTR(-EINVAL);
695 }
696 
697 static struct nft_expr_type nft_ct_type __read_mostly = {
698 	.name		= "ct",
699 	.select_ops	= &nft_ct_select_ops,
700 	.policy		= nft_ct_policy,
701 	.maxattr	= NFTA_CT_MAX,
702 	.owner		= THIS_MODULE,
703 };
704 
705 static void nft_notrack_eval(const struct nft_expr *expr,
706 			     struct nft_regs *regs,
707 			     const struct nft_pktinfo *pkt)
708 {
709 	struct sk_buff *skb = pkt->skb;
710 	enum ip_conntrack_info ctinfo;
711 	struct nf_conn *ct;
712 
713 	ct = nf_ct_get(pkt->skb, &ctinfo);
714 	/* Previously seen (loopback or untracked)?  Ignore. */
715 	if (ct)
716 		return;
717 
718 	ct = nf_ct_untracked_get();
719 	atomic_inc(&ct->ct_general.use);
720 	nf_ct_set(skb, ct, IP_CT_NEW);
721 }
722 
723 static struct nft_expr_type nft_notrack_type;
724 static const struct nft_expr_ops nft_notrack_ops = {
725 	.type		= &nft_notrack_type,
726 	.size		= NFT_EXPR_SIZE(0),
727 	.eval		= nft_notrack_eval,
728 };
729 
730 static struct nft_expr_type nft_notrack_type __read_mostly = {
731 	.name		= "notrack",
732 	.ops		= &nft_notrack_ops,
733 	.owner		= THIS_MODULE,
734 };
735 
736 static int __init nft_ct_module_init(void)
737 {
738 	int err;
739 
740 	BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > NFT_REG_SIZE);
741 
742 	err = nft_register_expr(&nft_ct_type);
743 	if (err < 0)
744 		return err;
745 
746 	err = nft_register_expr(&nft_notrack_type);
747 	if (err < 0)
748 		goto err1;
749 
750 	return 0;
751 err1:
752 	nft_unregister_expr(&nft_ct_type);
753 	return err;
754 }
755 
756 static void __exit nft_ct_module_exit(void)
757 {
758 	nft_unregister_expr(&nft_notrack_type);
759 	nft_unregister_expr(&nft_ct_type);
760 }
761 
762 module_init(nft_ct_module_init);
763 module_exit(nft_ct_module_exit);
764 
765 MODULE_LICENSE("GPL");
766 MODULE_AUTHOR("Patrick McHardy <[email protected]>");
767 MODULE_ALIAS_NFT_EXPR("ct");
768 MODULE_ALIAS_NFT_EXPR("notrack");
769