• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
4  * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org>
5  *
6  * Development of this code funded by Astaro AG (http://www.astaro.com/)
7  */
8 
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/netlink.h>
13 #include <linux/netfilter.h>
14 #include <linux/netfilter/nf_tables.h>
15 #include <net/netfilter/nf_tables.h>
16 #include <net/netfilter/nf_conntrack.h>
17 #include <net/netfilter/nf_conntrack_acct.h>
18 #include <net/netfilter/nf_conntrack_tuple.h>
19 #include <net/netfilter/nf_conntrack_helper.h>
20 #include <net/netfilter/nf_conntrack_ecache.h>
21 #include <net/netfilter/nf_conntrack_labels.h>
22 #include <net/netfilter/nf_conntrack_timeout.h>
23 #include <net/netfilter/nf_conntrack_l4proto.h>
24 #include <net/netfilter/nf_conntrack_expect.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 struct nft_ct_helper_obj  {
36 	struct nf_conntrack_helper *helper4;
37 	struct nf_conntrack_helper *helper6;
38 	u8 l4proto;
39 };
40 
41 #ifdef CONFIG_NF_CONNTRACK_ZONES
42 static DEFINE_PER_CPU(struct nf_conn *, nft_ct_pcpu_template);
43 static unsigned int nft_ct_pcpu_template_refcnt __read_mostly;
44 #endif
45 
nft_ct_get_eval_counter(const struct nf_conn_counter * c,enum nft_ct_keys k,enum ip_conntrack_dir d)46 static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c,
47 				   enum nft_ct_keys k,
48 				   enum ip_conntrack_dir d)
49 {
50 	if (d < IP_CT_DIR_MAX)
51 		return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) :
52 					   atomic64_read(&c[d].packets);
53 
54 	return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) +
55 	       nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY);
56 }
57 
nft_ct_get_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)58 static void nft_ct_get_eval(const struct nft_expr *expr,
59 			    struct nft_regs *regs,
60 			    const struct nft_pktinfo *pkt)
61 {
62 	const struct nft_ct *priv = nft_expr_priv(expr);
63 	u32 *dest = &regs->data[priv->dreg];
64 	enum ip_conntrack_info ctinfo;
65 	const struct nf_conn *ct;
66 	const struct nf_conn_help *help;
67 	const struct nf_conntrack_tuple *tuple;
68 	const struct nf_conntrack_helper *helper;
69 	unsigned int state;
70 
71 	ct = nf_ct_get(pkt->skb, &ctinfo);
72 
73 	switch (priv->key) {
74 	case NFT_CT_STATE:
75 		if (ct)
76 			state = NF_CT_STATE_BIT(ctinfo);
77 		else if (ctinfo == IP_CT_UNTRACKED)
78 			state = NF_CT_STATE_UNTRACKED_BIT;
79 		else
80 			state = NF_CT_STATE_INVALID_BIT;
81 		*dest = state;
82 		return;
83 	default:
84 		break;
85 	}
86 
87 	if (ct == NULL)
88 		goto err;
89 
90 	switch (priv->key) {
91 	case NFT_CT_DIRECTION:
92 		nft_reg_store8(dest, CTINFO2DIR(ctinfo));
93 		return;
94 	case NFT_CT_STATUS:
95 		*dest = ct->status;
96 		return;
97 #ifdef CONFIG_NF_CONNTRACK_MARK
98 	case NFT_CT_MARK:
99 		*dest = ct->mark;
100 		return;
101 #endif
102 #ifdef CONFIG_NF_CONNTRACK_SECMARK
103 	case NFT_CT_SECMARK:
104 		*dest = ct->secmark;
105 		return;
106 #endif
107 	case NFT_CT_EXPIRATION:
108 		*dest = jiffies_to_msecs(nf_ct_expires(ct));
109 		return;
110 	case NFT_CT_HELPER:
111 		if (ct->master == NULL)
112 			goto err;
113 		help = nfct_help(ct->master);
114 		if (help == NULL)
115 			goto err;
116 		helper = rcu_dereference(help->helper);
117 		if (helper == NULL)
118 			goto err;
119 		strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
120 		return;
121 #ifdef CONFIG_NF_CONNTRACK_LABELS
122 	case NFT_CT_LABELS: {
123 		struct nf_conn_labels *labels = nf_ct_labels_find(ct);
124 
125 		if (labels)
126 			memcpy(dest, labels->bits, NF_CT_LABELS_MAX_SIZE);
127 		else
128 			memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
129 		return;
130 	}
131 #endif
132 	case NFT_CT_BYTES: /* fallthrough */
133 	case NFT_CT_PKTS: {
134 		const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
135 		u64 count = 0;
136 
137 		if (acct)
138 			count = nft_ct_get_eval_counter(acct->counter,
139 							priv->key, priv->dir);
140 		memcpy(dest, &count, sizeof(count));
141 		return;
142 	}
143 	case NFT_CT_AVGPKT: {
144 		const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
145 		u64 avgcnt = 0, bcnt = 0, pcnt = 0;
146 
147 		if (acct) {
148 			pcnt = nft_ct_get_eval_counter(acct->counter,
149 						       NFT_CT_PKTS, priv->dir);
150 			bcnt = nft_ct_get_eval_counter(acct->counter,
151 						       NFT_CT_BYTES, priv->dir);
152 			if (pcnt != 0)
153 				avgcnt = div64_u64(bcnt, pcnt);
154 		}
155 
156 		memcpy(dest, &avgcnt, sizeof(avgcnt));
157 		return;
158 	}
159 	case NFT_CT_L3PROTOCOL:
160 		nft_reg_store8(dest, nf_ct_l3num(ct));
161 		return;
162 	case NFT_CT_PROTOCOL:
163 		nft_reg_store8(dest, nf_ct_protonum(ct));
164 		return;
165 #ifdef CONFIG_NF_CONNTRACK_ZONES
166 	case NFT_CT_ZONE: {
167 		const struct nf_conntrack_zone *zone = nf_ct_zone(ct);
168 		u16 zoneid;
169 
170 		if (priv->dir < IP_CT_DIR_MAX)
171 			zoneid = nf_ct_zone_id(zone, priv->dir);
172 		else
173 			zoneid = zone->id;
174 
175 		nft_reg_store16(dest, zoneid);
176 		return;
177 	}
178 #endif
179 	case NFT_CT_ID:
180 		if (!nf_ct_is_confirmed(ct))
181 			goto err;
182 		*dest = nf_ct_get_id(ct);
183 		return;
184 	default:
185 		break;
186 	}
187 
188 	tuple = &ct->tuplehash[priv->dir].tuple;
189 	switch (priv->key) {
190 	case NFT_CT_SRC:
191 		memcpy(dest, tuple->src.u3.all,
192 		       nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
193 		return;
194 	case NFT_CT_DST:
195 		memcpy(dest, tuple->dst.u3.all,
196 		       nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
197 		return;
198 	case NFT_CT_PROTO_SRC:
199 		nft_reg_store16(dest, (__force u16)tuple->src.u.all);
200 		return;
201 	case NFT_CT_PROTO_DST:
202 		nft_reg_store16(dest, (__force u16)tuple->dst.u.all);
203 		return;
204 	case NFT_CT_SRC_IP:
205 		if (nf_ct_l3num(ct) != NFPROTO_IPV4)
206 			goto err;
207 		*dest = tuple->src.u3.ip;
208 		return;
209 	case NFT_CT_DST_IP:
210 		if (nf_ct_l3num(ct) != NFPROTO_IPV4)
211 			goto err;
212 		*dest = tuple->dst.u3.ip;
213 		return;
214 	case NFT_CT_SRC_IP6:
215 		if (nf_ct_l3num(ct) != NFPROTO_IPV6)
216 			goto err;
217 		memcpy(dest, tuple->src.u3.ip6, sizeof(struct in6_addr));
218 		return;
219 	case NFT_CT_DST_IP6:
220 		if (nf_ct_l3num(ct) != NFPROTO_IPV6)
221 			goto err;
222 		memcpy(dest, tuple->dst.u3.ip6, sizeof(struct in6_addr));
223 		return;
224 	default:
225 		break;
226 	}
227 	return;
228 err:
229 	regs->verdict.code = NFT_BREAK;
230 }
231 
232 #ifdef CONFIG_NF_CONNTRACK_ZONES
nft_ct_set_zone_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)233 static void nft_ct_set_zone_eval(const struct nft_expr *expr,
234 				 struct nft_regs *regs,
235 				 const struct nft_pktinfo *pkt)
236 {
237 	struct nf_conntrack_zone zone = { .dir = NF_CT_DEFAULT_ZONE_DIR };
238 	const struct nft_ct *priv = nft_expr_priv(expr);
239 	struct sk_buff *skb = pkt->skb;
240 	enum ip_conntrack_info ctinfo;
241 	u16 value = nft_reg_load16(&regs->data[priv->sreg]);
242 	struct nf_conn *ct;
243 
244 	ct = nf_ct_get(skb, &ctinfo);
245 	if (ct) /* already tracked */
246 		return;
247 
248 	zone.id = value;
249 
250 	switch (priv->dir) {
251 	case IP_CT_DIR_ORIGINAL:
252 		zone.dir = NF_CT_ZONE_DIR_ORIG;
253 		break;
254 	case IP_CT_DIR_REPLY:
255 		zone.dir = NF_CT_ZONE_DIR_REPL;
256 		break;
257 	default:
258 		break;
259 	}
260 
261 	ct = this_cpu_read(nft_ct_pcpu_template);
262 
263 	if (likely(atomic_read(&ct->ct_general.use) == 1)) {
264 		nf_ct_zone_add(ct, &zone);
265 	} else {
266 		/* previous skb got queued to userspace */
267 		ct = nf_ct_tmpl_alloc(nft_net(pkt), &zone, GFP_ATOMIC);
268 		if (!ct) {
269 			regs->verdict.code = NF_DROP;
270 			return;
271 		}
272 	}
273 
274 	atomic_inc(&ct->ct_general.use);
275 	nf_ct_set(skb, ct, IP_CT_NEW);
276 }
277 #endif
278 
nft_ct_set_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)279 static void nft_ct_set_eval(const struct nft_expr *expr,
280 			    struct nft_regs *regs,
281 			    const struct nft_pktinfo *pkt)
282 {
283 	const struct nft_ct *priv = nft_expr_priv(expr);
284 	struct sk_buff *skb = pkt->skb;
285 #if defined(CONFIG_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_SECMARK)
286 	u32 value = regs->data[priv->sreg];
287 #endif
288 	enum ip_conntrack_info ctinfo;
289 	struct nf_conn *ct;
290 
291 	ct = nf_ct_get(skb, &ctinfo);
292 	if (ct == NULL || nf_ct_is_template(ct))
293 		return;
294 
295 	switch (priv->key) {
296 #ifdef CONFIG_NF_CONNTRACK_MARK
297 	case NFT_CT_MARK:
298 		if (ct->mark != value) {
299 			ct->mark = value;
300 			nf_conntrack_event_cache(IPCT_MARK, ct);
301 		}
302 		break;
303 #endif
304 #ifdef CONFIG_NF_CONNTRACK_SECMARK
305 	case NFT_CT_SECMARK:
306 		if (ct->secmark != value) {
307 			ct->secmark = value;
308 			nf_conntrack_event_cache(IPCT_SECMARK, ct);
309 		}
310 		break;
311 #endif
312 #ifdef CONFIG_NF_CONNTRACK_LABELS
313 	case NFT_CT_LABELS:
314 		nf_connlabels_replace(ct,
315 				      &regs->data[priv->sreg],
316 				      &regs->data[priv->sreg],
317 				      NF_CT_LABELS_MAX_SIZE / sizeof(u32));
318 		break;
319 #endif
320 #ifdef CONFIG_NF_CONNTRACK_EVENTS
321 	case NFT_CT_EVENTMASK: {
322 		struct nf_conntrack_ecache *e = nf_ct_ecache_find(ct);
323 		u32 ctmask = regs->data[priv->sreg];
324 
325 		if (e) {
326 			if (e->ctmask != ctmask)
327 				e->ctmask = ctmask;
328 			break;
329 		}
330 
331 		if (ctmask && !nf_ct_is_confirmed(ct))
332 			nf_ct_ecache_ext_add(ct, ctmask, 0, GFP_ATOMIC);
333 		break;
334 	}
335 #endif
336 	default:
337 		break;
338 	}
339 }
340 
341 static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
342 	[NFTA_CT_DREG]		= { .type = NLA_U32 },
343 	[NFTA_CT_KEY]		= { .type = NLA_U32 },
344 	[NFTA_CT_DIRECTION]	= { .type = NLA_U8 },
345 	[NFTA_CT_SREG]		= { .type = NLA_U32 },
346 };
347 
348 #ifdef CONFIG_NF_CONNTRACK_ZONES
nft_ct_tmpl_put_pcpu(void)349 static void nft_ct_tmpl_put_pcpu(void)
350 {
351 	struct nf_conn *ct;
352 	int cpu;
353 
354 	for_each_possible_cpu(cpu) {
355 		ct = per_cpu(nft_ct_pcpu_template, cpu);
356 		if (!ct)
357 			break;
358 		nf_ct_put(ct);
359 		per_cpu(nft_ct_pcpu_template, cpu) = NULL;
360 	}
361 }
362 
nft_ct_tmpl_alloc_pcpu(void)363 static bool nft_ct_tmpl_alloc_pcpu(void)
364 {
365 	struct nf_conntrack_zone zone = { .id = 0 };
366 	struct nf_conn *tmp;
367 	int cpu;
368 
369 	if (nft_ct_pcpu_template_refcnt)
370 		return true;
371 
372 	for_each_possible_cpu(cpu) {
373 		tmp = nf_ct_tmpl_alloc(&init_net, &zone, GFP_KERNEL);
374 		if (!tmp) {
375 			nft_ct_tmpl_put_pcpu();
376 			return false;
377 		}
378 
379 		atomic_set(&tmp->ct_general.use, 1);
380 		per_cpu(nft_ct_pcpu_template, cpu) = tmp;
381 	}
382 
383 	return true;
384 }
385 #endif
386 
nft_ct_get_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])387 static int nft_ct_get_init(const struct nft_ctx *ctx,
388 			   const struct nft_expr *expr,
389 			   const struct nlattr * const tb[])
390 {
391 	struct nft_ct *priv = nft_expr_priv(expr);
392 	unsigned int len;
393 	int err;
394 
395 	priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
396 	priv->dir = IP_CT_DIR_MAX;
397 	switch (priv->key) {
398 	case NFT_CT_DIRECTION:
399 		if (tb[NFTA_CT_DIRECTION] != NULL)
400 			return -EINVAL;
401 		len = sizeof(u8);
402 		break;
403 	case NFT_CT_STATE:
404 	case NFT_CT_STATUS:
405 #ifdef CONFIG_NF_CONNTRACK_MARK
406 	case NFT_CT_MARK:
407 #endif
408 #ifdef CONFIG_NF_CONNTRACK_SECMARK
409 	case NFT_CT_SECMARK:
410 #endif
411 	case NFT_CT_EXPIRATION:
412 		if (tb[NFTA_CT_DIRECTION] != NULL)
413 			return -EINVAL;
414 		len = sizeof(u32);
415 		break;
416 #ifdef CONFIG_NF_CONNTRACK_LABELS
417 	case NFT_CT_LABELS:
418 		if (tb[NFTA_CT_DIRECTION] != NULL)
419 			return -EINVAL;
420 		len = NF_CT_LABELS_MAX_SIZE;
421 		break;
422 #endif
423 	case NFT_CT_HELPER:
424 		if (tb[NFTA_CT_DIRECTION] != NULL)
425 			return -EINVAL;
426 		len = NF_CT_HELPER_NAME_LEN;
427 		break;
428 
429 	case NFT_CT_L3PROTOCOL:
430 	case NFT_CT_PROTOCOL:
431 		/* For compatibility, do not report error if NFTA_CT_DIRECTION
432 		 * attribute is specified.
433 		 */
434 		len = sizeof(u8);
435 		break;
436 	case NFT_CT_SRC:
437 	case NFT_CT_DST:
438 		if (tb[NFTA_CT_DIRECTION] == NULL)
439 			return -EINVAL;
440 
441 		switch (ctx->family) {
442 		case NFPROTO_IPV4:
443 			len = FIELD_SIZEOF(struct nf_conntrack_tuple,
444 					   src.u3.ip);
445 			break;
446 		case NFPROTO_IPV6:
447 		case NFPROTO_INET:
448 			len = FIELD_SIZEOF(struct nf_conntrack_tuple,
449 					   src.u3.ip6);
450 			break;
451 		default:
452 			return -EAFNOSUPPORT;
453 		}
454 		break;
455 	case NFT_CT_SRC_IP:
456 	case NFT_CT_DST_IP:
457 		if (tb[NFTA_CT_DIRECTION] == NULL)
458 			return -EINVAL;
459 
460 		len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip);
461 		break;
462 	case NFT_CT_SRC_IP6:
463 	case NFT_CT_DST_IP6:
464 		if (tb[NFTA_CT_DIRECTION] == NULL)
465 			return -EINVAL;
466 
467 		len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip6);
468 		break;
469 	case NFT_CT_PROTO_SRC:
470 	case NFT_CT_PROTO_DST:
471 		if (tb[NFTA_CT_DIRECTION] == NULL)
472 			return -EINVAL;
473 		len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
474 		break;
475 	case NFT_CT_BYTES:
476 	case NFT_CT_PKTS:
477 	case NFT_CT_AVGPKT:
478 		len = sizeof(u64);
479 		break;
480 #ifdef CONFIG_NF_CONNTRACK_ZONES
481 	case NFT_CT_ZONE:
482 		len = sizeof(u16);
483 		break;
484 #endif
485 	case NFT_CT_ID:
486 		len = sizeof(u32);
487 		break;
488 	default:
489 		return -EOPNOTSUPP;
490 	}
491 
492 	if (tb[NFTA_CT_DIRECTION] != NULL) {
493 		priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
494 		switch (priv->dir) {
495 		case IP_CT_DIR_ORIGINAL:
496 		case IP_CT_DIR_REPLY:
497 			break;
498 		default:
499 			return -EINVAL;
500 		}
501 	}
502 
503 	priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
504 	err = nft_validate_register_store(ctx, priv->dreg, NULL,
505 					  NFT_DATA_VALUE, len);
506 	if (err < 0)
507 		return err;
508 
509 	err = nf_ct_netns_get(ctx->net, ctx->family);
510 	if (err < 0)
511 		return err;
512 
513 	if (priv->key == NFT_CT_BYTES ||
514 	    priv->key == NFT_CT_PKTS  ||
515 	    priv->key == NFT_CT_AVGPKT)
516 		nf_ct_set_acct(ctx->net, true);
517 
518 	return 0;
519 }
520 
__nft_ct_set_destroy(const struct nft_ctx * ctx,struct nft_ct * priv)521 static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv)
522 {
523 	switch (priv->key) {
524 #ifdef CONFIG_NF_CONNTRACK_LABELS
525 	case NFT_CT_LABELS:
526 		nf_connlabels_put(ctx->net);
527 		break;
528 #endif
529 #ifdef CONFIG_NF_CONNTRACK_ZONES
530 	case NFT_CT_ZONE:
531 		if (--nft_ct_pcpu_template_refcnt == 0)
532 			nft_ct_tmpl_put_pcpu();
533 #endif
534 	default:
535 		break;
536 	}
537 }
538 
nft_ct_set_init(const struct nft_ctx * ctx,const struct nft_expr * expr,const struct nlattr * const tb[])539 static int nft_ct_set_init(const struct nft_ctx *ctx,
540 			   const struct nft_expr *expr,
541 			   const struct nlattr * const tb[])
542 {
543 	struct nft_ct *priv = nft_expr_priv(expr);
544 	unsigned int len;
545 	int err;
546 
547 	priv->dir = IP_CT_DIR_MAX;
548 	priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
549 	switch (priv->key) {
550 #ifdef CONFIG_NF_CONNTRACK_MARK
551 	case NFT_CT_MARK:
552 		if (tb[NFTA_CT_DIRECTION])
553 			return -EINVAL;
554 		len = FIELD_SIZEOF(struct nf_conn, mark);
555 		break;
556 #endif
557 #ifdef CONFIG_NF_CONNTRACK_LABELS
558 	case NFT_CT_LABELS:
559 		if (tb[NFTA_CT_DIRECTION])
560 			return -EINVAL;
561 		len = NF_CT_LABELS_MAX_SIZE;
562 		err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
563 		if (err)
564 			return err;
565 		break;
566 #endif
567 #ifdef CONFIG_NF_CONNTRACK_ZONES
568 	case NFT_CT_ZONE:
569 		if (!nft_ct_tmpl_alloc_pcpu())
570 			return -ENOMEM;
571 		nft_ct_pcpu_template_refcnt++;
572 		len = sizeof(u16);
573 		break;
574 #endif
575 #ifdef CONFIG_NF_CONNTRACK_EVENTS
576 	case NFT_CT_EVENTMASK:
577 		if (tb[NFTA_CT_DIRECTION])
578 			return -EINVAL;
579 		len = sizeof(u32);
580 		break;
581 #endif
582 #ifdef CONFIG_NF_CONNTRACK_SECMARK
583 	case NFT_CT_SECMARK:
584 		if (tb[NFTA_CT_DIRECTION])
585 			return -EINVAL;
586 		len = sizeof(u32);
587 		break;
588 #endif
589 	default:
590 		return -EOPNOTSUPP;
591 	}
592 
593 	if (tb[NFTA_CT_DIRECTION]) {
594 		priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
595 		switch (priv->dir) {
596 		case IP_CT_DIR_ORIGINAL:
597 		case IP_CT_DIR_REPLY:
598 			break;
599 		default:
600 			err = -EINVAL;
601 			goto err1;
602 		}
603 	}
604 
605 	priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
606 	err = nft_validate_register_load(priv->sreg, len);
607 	if (err < 0)
608 		goto err1;
609 
610 	err = nf_ct_netns_get(ctx->net, ctx->family);
611 	if (err < 0)
612 		goto err1;
613 
614 	return 0;
615 
616 err1:
617 	__nft_ct_set_destroy(ctx, priv);
618 	return err;
619 }
620 
nft_ct_get_destroy(const struct nft_ctx * ctx,const struct nft_expr * expr)621 static void nft_ct_get_destroy(const struct nft_ctx *ctx,
622 			       const struct nft_expr *expr)
623 {
624 	nf_ct_netns_put(ctx->net, ctx->family);
625 }
626 
nft_ct_set_destroy(const struct nft_ctx * ctx,const struct nft_expr * expr)627 static void nft_ct_set_destroy(const struct nft_ctx *ctx,
628 			       const struct nft_expr *expr)
629 {
630 	struct nft_ct *priv = nft_expr_priv(expr);
631 
632 	__nft_ct_set_destroy(ctx, priv);
633 	nf_ct_netns_put(ctx->net, ctx->family);
634 }
635 
nft_ct_get_dump(struct sk_buff * skb,const struct nft_expr * expr)636 static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
637 {
638 	const struct nft_ct *priv = nft_expr_priv(expr);
639 
640 	if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
641 		goto nla_put_failure;
642 	if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
643 		goto nla_put_failure;
644 
645 	switch (priv->key) {
646 	case NFT_CT_SRC:
647 	case NFT_CT_DST:
648 	case NFT_CT_SRC_IP:
649 	case NFT_CT_DST_IP:
650 	case NFT_CT_SRC_IP6:
651 	case NFT_CT_DST_IP6:
652 	case NFT_CT_PROTO_SRC:
653 	case NFT_CT_PROTO_DST:
654 		if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
655 			goto nla_put_failure;
656 		break;
657 	case NFT_CT_BYTES:
658 	case NFT_CT_PKTS:
659 	case NFT_CT_AVGPKT:
660 	case NFT_CT_ZONE:
661 		if (priv->dir < IP_CT_DIR_MAX &&
662 		    nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
663 			goto nla_put_failure;
664 		break;
665 	default:
666 		break;
667 	}
668 
669 	return 0;
670 
671 nla_put_failure:
672 	return -1;
673 }
674 
nft_ct_set_dump(struct sk_buff * skb,const struct nft_expr * expr)675 static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
676 {
677 	const struct nft_ct *priv = nft_expr_priv(expr);
678 
679 	if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
680 		goto nla_put_failure;
681 	if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
682 		goto nla_put_failure;
683 
684 	switch (priv->key) {
685 	case NFT_CT_ZONE:
686 		if (priv->dir < IP_CT_DIR_MAX &&
687 		    nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
688 			goto nla_put_failure;
689 		break;
690 	default:
691 		break;
692 	}
693 
694 	return 0;
695 
696 nla_put_failure:
697 	return -1;
698 }
699 
700 static struct nft_expr_type nft_ct_type;
701 static const struct nft_expr_ops nft_ct_get_ops = {
702 	.type		= &nft_ct_type,
703 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_ct)),
704 	.eval		= nft_ct_get_eval,
705 	.init		= nft_ct_get_init,
706 	.destroy	= nft_ct_get_destroy,
707 	.dump		= nft_ct_get_dump,
708 };
709 
710 static const struct nft_expr_ops nft_ct_set_ops = {
711 	.type		= &nft_ct_type,
712 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_ct)),
713 	.eval		= nft_ct_set_eval,
714 	.init		= nft_ct_set_init,
715 	.destroy	= nft_ct_set_destroy,
716 	.dump		= nft_ct_set_dump,
717 };
718 
719 #ifdef CONFIG_NF_CONNTRACK_ZONES
720 static const struct nft_expr_ops nft_ct_set_zone_ops = {
721 	.type		= &nft_ct_type,
722 	.size		= NFT_EXPR_SIZE(sizeof(struct nft_ct)),
723 	.eval		= nft_ct_set_zone_eval,
724 	.init		= nft_ct_set_init,
725 	.destroy	= nft_ct_set_destroy,
726 	.dump		= nft_ct_set_dump,
727 };
728 #endif
729 
730 static const struct nft_expr_ops *
nft_ct_select_ops(const struct nft_ctx * ctx,const struct nlattr * const tb[])731 nft_ct_select_ops(const struct nft_ctx *ctx,
732 		    const struct nlattr * const tb[])
733 {
734 	if (tb[NFTA_CT_KEY] == NULL)
735 		return ERR_PTR(-EINVAL);
736 
737 	if (tb[NFTA_CT_DREG] && tb[NFTA_CT_SREG])
738 		return ERR_PTR(-EINVAL);
739 
740 	if (tb[NFTA_CT_DREG])
741 		return &nft_ct_get_ops;
742 
743 	if (tb[NFTA_CT_SREG]) {
744 #ifdef CONFIG_NF_CONNTRACK_ZONES
745 		if (nla_get_be32(tb[NFTA_CT_KEY]) == htonl(NFT_CT_ZONE))
746 			return &nft_ct_set_zone_ops;
747 #endif
748 		return &nft_ct_set_ops;
749 	}
750 
751 	return ERR_PTR(-EINVAL);
752 }
753 
754 static struct nft_expr_type nft_ct_type __read_mostly = {
755 	.name		= "ct",
756 	.select_ops	= nft_ct_select_ops,
757 	.policy		= nft_ct_policy,
758 	.maxattr	= NFTA_CT_MAX,
759 	.owner		= THIS_MODULE,
760 };
761 
nft_notrack_eval(const struct nft_expr * expr,struct nft_regs * regs,const struct nft_pktinfo * pkt)762 static void nft_notrack_eval(const struct nft_expr *expr,
763 			     struct nft_regs *regs,
764 			     const struct nft_pktinfo *pkt)
765 {
766 	struct sk_buff *skb = pkt->skb;
767 	enum ip_conntrack_info ctinfo;
768 	struct nf_conn *ct;
769 
770 	ct = nf_ct_get(pkt->skb, &ctinfo);
771 	/* Previously seen (loopback or untracked)?  Ignore. */
772 	if (ct || ctinfo == IP_CT_UNTRACKED)
773 		return;
774 
775 	nf_ct_set(skb, ct, IP_CT_UNTRACKED);
776 }
777 
778 static struct nft_expr_type nft_notrack_type;
779 static const struct nft_expr_ops nft_notrack_ops = {
780 	.type		= &nft_notrack_type,
781 	.size		= NFT_EXPR_SIZE(0),
782 	.eval		= nft_notrack_eval,
783 };
784 
785 static struct nft_expr_type nft_notrack_type __read_mostly = {
786 	.name		= "notrack",
787 	.ops		= &nft_notrack_ops,
788 	.owner		= THIS_MODULE,
789 };
790 
791 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
792 static int
nft_ct_timeout_parse_policy(void * timeouts,const struct nf_conntrack_l4proto * l4proto,struct net * net,const struct nlattr * attr)793 nft_ct_timeout_parse_policy(void *timeouts,
794 			    const struct nf_conntrack_l4proto *l4proto,
795 			    struct net *net, const struct nlattr *attr)
796 {
797 	struct nlattr **tb;
798 	int ret = 0;
799 
800 	tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb),
801 		     GFP_KERNEL);
802 
803 	if (!tb)
804 		return -ENOMEM;
805 
806 	ret = nla_parse_nested_deprecated(tb,
807 					  l4proto->ctnl_timeout.nlattr_max,
808 					  attr,
809 					  l4proto->ctnl_timeout.nla_policy,
810 					  NULL);
811 	if (ret < 0)
812 		goto err;
813 
814 	ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts);
815 
816 err:
817 	kfree(tb);
818 	return ret;
819 }
820 
821 struct nft_ct_timeout_obj {
822 	struct nf_ct_timeout    *timeout;
823 	u8			l4proto;
824 };
825 
nft_ct_timeout_obj_eval(struct nft_object * obj,struct nft_regs * regs,const struct nft_pktinfo * pkt)826 static void nft_ct_timeout_obj_eval(struct nft_object *obj,
827 				    struct nft_regs *regs,
828 				    const struct nft_pktinfo *pkt)
829 {
830 	const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
831 	struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
832 	struct nf_conn_timeout *timeout;
833 	const unsigned int *values;
834 
835 	if (priv->l4proto != pkt->tprot)
836 		return;
837 
838 	if (!ct || nf_ct_is_template(ct) || nf_ct_is_confirmed(ct))
839 		return;
840 
841 	timeout = nf_ct_timeout_find(ct);
842 	if (!timeout) {
843 		timeout = nf_ct_timeout_ext_add(ct, priv->timeout, GFP_ATOMIC);
844 		if (!timeout) {
845 			regs->verdict.code = NF_DROP;
846 			return;
847 		}
848 	}
849 
850 	rcu_assign_pointer(timeout->timeout, priv->timeout);
851 
852 	/* adjust the timeout as per 'new' state. ct is unconfirmed,
853 	 * so the current timestamp must not be added.
854 	 */
855 	values = nf_ct_timeout_data(timeout);
856 	if (values)
857 		nf_ct_refresh(ct, pkt->skb, values[0]);
858 }
859 
nft_ct_timeout_obj_init(const struct nft_ctx * ctx,const struct nlattr * const tb[],struct nft_object * obj)860 static int nft_ct_timeout_obj_init(const struct nft_ctx *ctx,
861 				   const struct nlattr * const tb[],
862 				   struct nft_object *obj)
863 {
864 	struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
865 	const struct nf_conntrack_l4proto *l4proto;
866 	struct nf_ct_timeout *timeout;
867 	int l3num = ctx->family;
868 	__u8 l4num;
869 	int ret;
870 
871 	if (!tb[NFTA_CT_TIMEOUT_L4PROTO] ||
872 	    !tb[NFTA_CT_TIMEOUT_DATA])
873 		return -EINVAL;
874 
875 	if (tb[NFTA_CT_TIMEOUT_L3PROTO])
876 		l3num = ntohs(nla_get_be16(tb[NFTA_CT_TIMEOUT_L3PROTO]));
877 
878 	l4num = nla_get_u8(tb[NFTA_CT_TIMEOUT_L4PROTO]);
879 	priv->l4proto = l4num;
880 
881 	l4proto = nf_ct_l4proto_find(l4num);
882 
883 	if (l4proto->l4proto != l4num) {
884 		ret = -EOPNOTSUPP;
885 		goto err_proto_put;
886 	}
887 
888 	timeout = kzalloc(sizeof(struct nf_ct_timeout) +
889 			  l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
890 	if (timeout == NULL) {
891 		ret = -ENOMEM;
892 		goto err_proto_put;
893 	}
894 
895 	ret = nft_ct_timeout_parse_policy(&timeout->data, l4proto, ctx->net,
896 					  tb[NFTA_CT_TIMEOUT_DATA]);
897 	if (ret < 0)
898 		goto err_free_timeout;
899 
900 	timeout->l3num = l3num;
901 	timeout->l4proto = l4proto;
902 
903 	ret = nf_ct_netns_get(ctx->net, ctx->family);
904 	if (ret < 0)
905 		goto err_free_timeout;
906 
907 	priv->timeout = timeout;
908 	return 0;
909 
910 err_free_timeout:
911 	kfree(timeout);
912 err_proto_put:
913 	return ret;
914 }
915 
nft_ct_timeout_obj_destroy(const struct nft_ctx * ctx,struct nft_object * obj)916 static void nft_ct_timeout_obj_destroy(const struct nft_ctx *ctx,
917 				       struct nft_object *obj)
918 {
919 	struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
920 	struct nf_ct_timeout *timeout = priv->timeout;
921 
922 	nf_ct_untimeout(ctx->net, timeout);
923 	nf_ct_netns_put(ctx->net, ctx->family);
924 	kfree(priv->timeout);
925 }
926 
nft_ct_timeout_obj_dump(struct sk_buff * skb,struct nft_object * obj,bool reset)927 static int nft_ct_timeout_obj_dump(struct sk_buff *skb,
928 				   struct nft_object *obj, bool reset)
929 {
930 	const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
931 	const struct nf_ct_timeout *timeout = priv->timeout;
932 	struct nlattr *nest_params;
933 	int ret;
934 
935 	if (nla_put_u8(skb, NFTA_CT_TIMEOUT_L4PROTO, timeout->l4proto->l4proto) ||
936 	    nla_put_be16(skb, NFTA_CT_TIMEOUT_L3PROTO, htons(timeout->l3num)))
937 		return -1;
938 
939 	nest_params = nla_nest_start(skb, NFTA_CT_TIMEOUT_DATA);
940 	if (!nest_params)
941 		return -1;
942 
943 	ret = timeout->l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->data);
944 	if (ret < 0)
945 		return -1;
946 	nla_nest_end(skb, nest_params);
947 	return 0;
948 }
949 
950 static const struct nla_policy nft_ct_timeout_policy[NFTA_CT_TIMEOUT_MAX + 1] = {
951 	[NFTA_CT_TIMEOUT_L3PROTO] = {.type = NLA_U16 },
952 	[NFTA_CT_TIMEOUT_L4PROTO] = {.type = NLA_U8 },
953 	[NFTA_CT_TIMEOUT_DATA]	  = {.type = NLA_NESTED },
954 };
955 
956 static struct nft_object_type nft_ct_timeout_obj_type;
957 
958 static const struct nft_object_ops nft_ct_timeout_obj_ops = {
959 	.type		= &nft_ct_timeout_obj_type,
960 	.size		= sizeof(struct nft_ct_timeout_obj),
961 	.eval		= nft_ct_timeout_obj_eval,
962 	.init		= nft_ct_timeout_obj_init,
963 	.destroy	= nft_ct_timeout_obj_destroy,
964 	.dump		= nft_ct_timeout_obj_dump,
965 };
966 
967 static struct nft_object_type nft_ct_timeout_obj_type __read_mostly = {
968 	.type		= NFT_OBJECT_CT_TIMEOUT,
969 	.ops		= &nft_ct_timeout_obj_ops,
970 	.maxattr	= NFTA_CT_TIMEOUT_MAX,
971 	.policy		= nft_ct_timeout_policy,
972 	.owner		= THIS_MODULE,
973 };
974 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
975 
nft_ct_helper_obj_init(const struct nft_ctx * ctx,const struct nlattr * const tb[],struct nft_object * obj)976 static int nft_ct_helper_obj_init(const struct nft_ctx *ctx,
977 				  const struct nlattr * const tb[],
978 				  struct nft_object *obj)
979 {
980 	struct nft_ct_helper_obj *priv = nft_obj_data(obj);
981 	struct nf_conntrack_helper *help4, *help6;
982 	char name[NF_CT_HELPER_NAME_LEN];
983 	int family = ctx->family;
984 	int err;
985 
986 	if (!tb[NFTA_CT_HELPER_NAME] || !tb[NFTA_CT_HELPER_L4PROTO])
987 		return -EINVAL;
988 
989 	priv->l4proto = nla_get_u8(tb[NFTA_CT_HELPER_L4PROTO]);
990 	if (!priv->l4proto)
991 		return -ENOENT;
992 
993 	nla_strlcpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
994 
995 	if (tb[NFTA_CT_HELPER_L3PROTO])
996 		family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO]));
997 
998 	help4 = NULL;
999 	help6 = NULL;
1000 
1001 	switch (family) {
1002 	case NFPROTO_IPV4:
1003 		if (ctx->family == NFPROTO_IPV6)
1004 			return -EINVAL;
1005 
1006 		help4 = nf_conntrack_helper_try_module_get(name, family,
1007 							   priv->l4proto);
1008 		break;
1009 	case NFPROTO_IPV6:
1010 		if (ctx->family == NFPROTO_IPV4)
1011 			return -EINVAL;
1012 
1013 		help6 = nf_conntrack_helper_try_module_get(name, family,
1014 							   priv->l4proto);
1015 		break;
1016 	case NFPROTO_NETDEV: /* fallthrough */
1017 	case NFPROTO_BRIDGE: /* same */
1018 	case NFPROTO_INET:
1019 		help4 = nf_conntrack_helper_try_module_get(name, NFPROTO_IPV4,
1020 							   priv->l4proto);
1021 		help6 = nf_conntrack_helper_try_module_get(name, NFPROTO_IPV6,
1022 							   priv->l4proto);
1023 		break;
1024 	default:
1025 		return -EAFNOSUPPORT;
1026 	}
1027 
1028 	/* && is intentional; only error if INET found neither ipv4 or ipv6 */
1029 	if (!help4 && !help6)
1030 		return -ENOENT;
1031 
1032 	priv->helper4 = help4;
1033 	priv->helper6 = help6;
1034 
1035 	err = nf_ct_netns_get(ctx->net, ctx->family);
1036 	if (err < 0)
1037 		goto err_put_helper;
1038 
1039 	return 0;
1040 
1041 err_put_helper:
1042 	if (priv->helper4)
1043 		nf_conntrack_helper_put(priv->helper4);
1044 	if (priv->helper6)
1045 		nf_conntrack_helper_put(priv->helper6);
1046 	return err;
1047 }
1048 
nft_ct_helper_obj_destroy(const struct nft_ctx * ctx,struct nft_object * obj)1049 static void nft_ct_helper_obj_destroy(const struct nft_ctx *ctx,
1050 				      struct nft_object *obj)
1051 {
1052 	struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1053 
1054 	if (priv->helper4)
1055 		nf_conntrack_helper_put(priv->helper4);
1056 	if (priv->helper6)
1057 		nf_conntrack_helper_put(priv->helper6);
1058 
1059 	nf_ct_netns_put(ctx->net, ctx->family);
1060 }
1061 
nft_ct_helper_obj_eval(struct nft_object * obj,struct nft_regs * regs,const struct nft_pktinfo * pkt)1062 static void nft_ct_helper_obj_eval(struct nft_object *obj,
1063 				   struct nft_regs *regs,
1064 				   const struct nft_pktinfo *pkt)
1065 {
1066 	const struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1067 	struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
1068 	struct nf_conntrack_helper *to_assign = NULL;
1069 	struct nf_conn_help *help;
1070 
1071 	if (!ct ||
1072 	    nf_ct_is_confirmed(ct) ||
1073 	    nf_ct_is_template(ct) ||
1074 	    priv->l4proto != nf_ct_protonum(ct))
1075 		return;
1076 
1077 	switch (nf_ct_l3num(ct)) {
1078 	case NFPROTO_IPV4:
1079 		to_assign = priv->helper4;
1080 		break;
1081 	case NFPROTO_IPV6:
1082 		to_assign = priv->helper6;
1083 		break;
1084 	default:
1085 		WARN_ON_ONCE(1);
1086 		return;
1087 	}
1088 
1089 	if (!to_assign)
1090 		return;
1091 
1092 	if (test_bit(IPS_HELPER_BIT, &ct->status))
1093 		return;
1094 
1095 	help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
1096 	if (help) {
1097 		rcu_assign_pointer(help->helper, to_assign);
1098 		set_bit(IPS_HELPER_BIT, &ct->status);
1099 	}
1100 }
1101 
nft_ct_helper_obj_dump(struct sk_buff * skb,struct nft_object * obj,bool reset)1102 static int nft_ct_helper_obj_dump(struct sk_buff *skb,
1103 				  struct nft_object *obj, bool reset)
1104 {
1105 	const struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1106 	const struct nf_conntrack_helper *helper;
1107 	u16 family;
1108 
1109 	if (priv->helper4 && priv->helper6) {
1110 		family = NFPROTO_INET;
1111 		helper = priv->helper4;
1112 	} else if (priv->helper6) {
1113 		family = NFPROTO_IPV6;
1114 		helper = priv->helper6;
1115 	} else {
1116 		family = NFPROTO_IPV4;
1117 		helper = priv->helper4;
1118 	}
1119 
1120 	if (nla_put_string(skb, NFTA_CT_HELPER_NAME, helper->name))
1121 		return -1;
1122 
1123 	if (nla_put_u8(skb, NFTA_CT_HELPER_L4PROTO, priv->l4proto))
1124 		return -1;
1125 
1126 	if (nla_put_be16(skb, NFTA_CT_HELPER_L3PROTO, htons(family)))
1127 		return -1;
1128 
1129 	return 0;
1130 }
1131 
1132 static const struct nla_policy nft_ct_helper_policy[NFTA_CT_HELPER_MAX + 1] = {
1133 	[NFTA_CT_HELPER_NAME] = { .type = NLA_STRING,
1134 				  .len = NF_CT_HELPER_NAME_LEN - 1 },
1135 	[NFTA_CT_HELPER_L3PROTO] = { .type = NLA_U16 },
1136 	[NFTA_CT_HELPER_L4PROTO] = { .type = NLA_U8 },
1137 };
1138 
1139 static struct nft_object_type nft_ct_helper_obj_type;
1140 static const struct nft_object_ops nft_ct_helper_obj_ops = {
1141 	.type		= &nft_ct_helper_obj_type,
1142 	.size		= sizeof(struct nft_ct_helper_obj),
1143 	.eval		= nft_ct_helper_obj_eval,
1144 	.init		= nft_ct_helper_obj_init,
1145 	.destroy	= nft_ct_helper_obj_destroy,
1146 	.dump		= nft_ct_helper_obj_dump,
1147 };
1148 
1149 static struct nft_object_type nft_ct_helper_obj_type __read_mostly = {
1150 	.type		= NFT_OBJECT_CT_HELPER,
1151 	.ops		= &nft_ct_helper_obj_ops,
1152 	.maxattr	= NFTA_CT_HELPER_MAX,
1153 	.policy		= nft_ct_helper_policy,
1154 	.owner		= THIS_MODULE,
1155 };
1156 
1157 struct nft_ct_expect_obj {
1158 	u16		l3num;
1159 	__be16		dport;
1160 	u8		l4proto;
1161 	u8		size;
1162 	u32		timeout;
1163 };
1164 
nft_ct_expect_obj_init(const struct nft_ctx * ctx,const struct nlattr * const tb[],struct nft_object * obj)1165 static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
1166 				  const struct nlattr * const tb[],
1167 				  struct nft_object *obj)
1168 {
1169 	struct nft_ct_expect_obj *priv = nft_obj_data(obj);
1170 
1171 	if (!tb[NFTA_CT_EXPECT_L4PROTO] ||
1172 	    !tb[NFTA_CT_EXPECT_DPORT] ||
1173 	    !tb[NFTA_CT_EXPECT_TIMEOUT] ||
1174 	    !tb[NFTA_CT_EXPECT_SIZE])
1175 		return -EINVAL;
1176 
1177 	priv->l3num = ctx->family;
1178 	if (tb[NFTA_CT_EXPECT_L3PROTO])
1179 		priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO]));
1180 
1181 	priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]);
1182 	priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]);
1183 	priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]);
1184 	priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]);
1185 
1186 	return nf_ct_netns_get(ctx->net, ctx->family);
1187 }
1188 
nft_ct_expect_obj_destroy(const struct nft_ctx * ctx,struct nft_object * obj)1189 static void nft_ct_expect_obj_destroy(const struct nft_ctx *ctx,
1190 				       struct nft_object *obj)
1191 {
1192 	nf_ct_netns_put(ctx->net, ctx->family);
1193 }
1194 
nft_ct_expect_obj_dump(struct sk_buff * skb,struct nft_object * obj,bool reset)1195 static int nft_ct_expect_obj_dump(struct sk_buff *skb,
1196 				  struct nft_object *obj, bool reset)
1197 {
1198 	const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
1199 
1200 	if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) ||
1201 	    nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) ||
1202 	    nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) ||
1203 	    nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout) ||
1204 	    nla_put_u8(skb, NFTA_CT_EXPECT_SIZE, priv->size))
1205 		return -1;
1206 
1207 	return 0;
1208 }
1209 
nft_ct_expect_obj_eval(struct nft_object * obj,struct nft_regs * regs,const struct nft_pktinfo * pkt)1210 static void nft_ct_expect_obj_eval(struct nft_object *obj,
1211 				   struct nft_regs *regs,
1212 				   const struct nft_pktinfo *pkt)
1213 {
1214 	const struct nft_ct_expect_obj *priv = nft_obj_data(obj);
1215 	struct nf_conntrack_expect *exp;
1216 	enum ip_conntrack_info ctinfo;
1217 	struct nf_conn_help *help;
1218 	enum ip_conntrack_dir dir;
1219 	u16 l3num = priv->l3num;
1220 	struct nf_conn *ct;
1221 
1222 	ct = nf_ct_get(pkt->skb, &ctinfo);
1223 	if (!ct || ctinfo == IP_CT_UNTRACKED) {
1224 		regs->verdict.code = NFT_BREAK;
1225 		return;
1226 	}
1227 	dir = CTINFO2DIR(ctinfo);
1228 
1229 	help = nfct_help(ct);
1230 	if (!help)
1231 		help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
1232 	if (!help) {
1233 		regs->verdict.code = NF_DROP;
1234 		return;
1235 	}
1236 
1237 	if (help->expecting[NF_CT_EXPECT_CLASS_DEFAULT] >= priv->size) {
1238 		regs->verdict.code = NFT_BREAK;
1239 		return;
1240 	}
1241 	if (l3num == NFPROTO_INET)
1242 		l3num = nf_ct_l3num(ct);
1243 
1244 	exp = nf_ct_expect_alloc(ct);
1245 	if (exp == NULL) {
1246 		regs->verdict.code = NF_DROP;
1247 		return;
1248 	}
1249 	nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, l3num,
1250 		          &ct->tuplehash[!dir].tuple.src.u3,
1251 		          &ct->tuplehash[!dir].tuple.dst.u3,
1252 		          priv->l4proto, NULL, &priv->dport);
1253 	exp->timeout.expires = jiffies + priv->timeout * HZ;
1254 
1255 	if (nf_ct_expect_related(exp, 0) != 0)
1256 		regs->verdict.code = NF_DROP;
1257 }
1258 
1259 static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX + 1] = {
1260 	[NFTA_CT_EXPECT_L3PROTO]	= { .type = NLA_U16 },
1261 	[NFTA_CT_EXPECT_L4PROTO]	= { .type = NLA_U8 },
1262 	[NFTA_CT_EXPECT_DPORT]		= { .type = NLA_U16 },
1263 	[NFTA_CT_EXPECT_TIMEOUT]	= { .type = NLA_U32 },
1264 	[NFTA_CT_EXPECT_SIZE]		= { .type = NLA_U8 },
1265 };
1266 
1267 static struct nft_object_type nft_ct_expect_obj_type;
1268 
1269 static const struct nft_object_ops nft_ct_expect_obj_ops = {
1270 	.type		= &nft_ct_expect_obj_type,
1271 	.size		= sizeof(struct nft_ct_expect_obj),
1272 	.eval		= nft_ct_expect_obj_eval,
1273 	.init		= nft_ct_expect_obj_init,
1274 	.destroy	= nft_ct_expect_obj_destroy,
1275 	.dump		= nft_ct_expect_obj_dump,
1276 };
1277 
1278 static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {
1279 	.type		= NFT_OBJECT_CT_EXPECT,
1280 	.ops		= &nft_ct_expect_obj_ops,
1281 	.maxattr	= NFTA_CT_EXPECT_MAX,
1282 	.policy		= nft_ct_expect_policy,
1283 	.owner		= THIS_MODULE,
1284 };
1285 
nft_ct_module_init(void)1286 static int __init nft_ct_module_init(void)
1287 {
1288 	int err;
1289 
1290 	BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > NFT_REG_SIZE);
1291 
1292 	err = nft_register_expr(&nft_ct_type);
1293 	if (err < 0)
1294 		return err;
1295 
1296 	err = nft_register_expr(&nft_notrack_type);
1297 	if (err < 0)
1298 		goto err1;
1299 
1300 	err = nft_register_obj(&nft_ct_helper_obj_type);
1301 	if (err < 0)
1302 		goto err2;
1303 
1304 	err = nft_register_obj(&nft_ct_expect_obj_type);
1305 	if (err < 0)
1306 		goto err3;
1307 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1308 	err = nft_register_obj(&nft_ct_timeout_obj_type);
1309 	if (err < 0)
1310 		goto err4;
1311 #endif
1312 	return 0;
1313 
1314 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1315 err4:
1316 	nft_unregister_obj(&nft_ct_expect_obj_type);
1317 #endif
1318 err3:
1319 	nft_unregister_obj(&nft_ct_helper_obj_type);
1320 err2:
1321 	nft_unregister_expr(&nft_notrack_type);
1322 err1:
1323 	nft_unregister_expr(&nft_ct_type);
1324 	return err;
1325 }
1326 
nft_ct_module_exit(void)1327 static void __exit nft_ct_module_exit(void)
1328 {
1329 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1330 	nft_unregister_obj(&nft_ct_timeout_obj_type);
1331 #endif
1332 	nft_unregister_obj(&nft_ct_expect_obj_type);
1333 	nft_unregister_obj(&nft_ct_helper_obj_type);
1334 	nft_unregister_expr(&nft_notrack_type);
1335 	nft_unregister_expr(&nft_ct_type);
1336 }
1337 
1338 module_init(nft_ct_module_init);
1339 module_exit(nft_ct_module_exit);
1340 
1341 MODULE_LICENSE("GPL");
1342 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
1343 MODULE_ALIAS_NFT_EXPR("ct");
1344 MODULE_ALIAS_NFT_EXPR("notrack");
1345 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER);
1346 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT);
1347 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_EXPECT);
1348