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 = ®s->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(®s->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 ®s->data[priv->sreg],
311 ®s->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