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