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