2 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
3 * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Development of this code funded by Astaro AG (http://www.astaro.com/)
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/netlink.h>
16 #include <linux/netfilter.h>
17 #include <linux/netfilter/nf_tables.h>
18 #include <net/netfilter/nf_tables.h>
19 #include <net/netfilter/nf_conntrack.h>
20 #include <net/netfilter/nf_conntrack_acct.h>
21 #include <net/netfilter/nf_conntrack_tuple.h>
22 #include <net/netfilter/nf_conntrack_helper.h>
23 #include <net/netfilter/nf_conntrack_ecache.h>
24 #include <net/netfilter/nf_conntrack_labels.h>
25 #include <net/netfilter/nf_conntrack_timeout.h>
26 #include <net/netfilter/nf_conntrack_l4proto.h>
29 enum nft_ct_keys key:8;
30 enum ip_conntrack_dir dir:8;
32 enum nft_registers dreg:8;
33 enum nft_registers sreg:8;
37 struct nft_ct_helper_obj {
38 struct nf_conntrack_helper *helper4;
39 struct nf_conntrack_helper *helper6;
43 #ifdef CONFIG_NF_CONNTRACK_ZONES
44 static DEFINE_PER_CPU(struct nf_conn *, nft_ct_pcpu_template);
45 static unsigned int nft_ct_pcpu_template_refcnt __read_mostly;
48 static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c,
50 enum ip_conntrack_dir d)
52 if (d < IP_CT_DIR_MAX)
53 return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) :
54 atomic64_read(&c[d].packets);
56 return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) +
57 nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY);
60 static void nft_ct_get_eval(const struct nft_expr *expr,
61 struct nft_regs *regs,
62 const struct nft_pktinfo *pkt)
64 const struct nft_ct *priv = nft_expr_priv(expr);
65 u32 *dest = ®s->data[priv->dreg];
66 enum ip_conntrack_info ctinfo;
67 const struct nf_conn *ct;
68 const struct nf_conn_help *help;
69 const struct nf_conntrack_tuple *tuple;
70 const struct nf_conntrack_helper *helper;
73 ct = nf_ct_get(pkt->skb, &ctinfo);
78 state = NF_CT_STATE_BIT(ctinfo);
79 else if (ctinfo == IP_CT_UNTRACKED)
80 state = NF_CT_STATE_UNTRACKED_BIT;
82 state = NF_CT_STATE_INVALID_BIT;
93 case NFT_CT_DIRECTION:
94 nft_reg_store8(dest, CTINFO2DIR(ctinfo));
99 #ifdef CONFIG_NF_CONNTRACK_MARK
104 #ifdef CONFIG_NF_CONNTRACK_SECMARK
109 case NFT_CT_EXPIRATION:
110 *dest = jiffies_to_msecs(nf_ct_expires(ct));
113 if (ct->master == NULL)
115 help = nfct_help(ct->master);
118 helper = rcu_dereference(help->helper);
121 strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
123 #ifdef CONFIG_NF_CONNTRACK_LABELS
124 case NFT_CT_LABELS: {
125 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
128 memcpy(dest, labels->bits, NF_CT_LABELS_MAX_SIZE);
130 memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
134 case NFT_CT_BYTES: /* fallthrough */
136 const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
140 count = nft_ct_get_eval_counter(acct->counter,
141 priv->key, priv->dir);
142 memcpy(dest, &count, sizeof(count));
145 case NFT_CT_AVGPKT: {
146 const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
147 u64 avgcnt = 0, bcnt = 0, pcnt = 0;
150 pcnt = nft_ct_get_eval_counter(acct->counter,
151 NFT_CT_PKTS, priv->dir);
152 bcnt = nft_ct_get_eval_counter(acct->counter,
153 NFT_CT_BYTES, priv->dir);
155 avgcnt = div64_u64(bcnt, pcnt);
158 memcpy(dest, &avgcnt, sizeof(avgcnt));
161 case NFT_CT_L3PROTOCOL:
162 nft_reg_store8(dest, nf_ct_l3num(ct));
164 case NFT_CT_PROTOCOL:
165 nft_reg_store8(dest, nf_ct_protonum(ct));
167 #ifdef CONFIG_NF_CONNTRACK_ZONES
169 const struct nf_conntrack_zone *zone = nf_ct_zone(ct);
172 if (priv->dir < IP_CT_DIR_MAX)
173 zoneid = nf_ct_zone_id(zone, priv->dir);
177 nft_reg_store16(dest, zoneid);
182 if (!nf_ct_is_confirmed(ct))
184 *dest = nf_ct_get_id(ct);
190 tuple = &ct->tuplehash[priv->dir].tuple;
193 memcpy(dest, tuple->src.u3.all,
194 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
197 memcpy(dest, tuple->dst.u3.all,
198 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
200 case NFT_CT_PROTO_SRC:
201 nft_reg_store16(dest, (__force u16)tuple->src.u.all);
203 case NFT_CT_PROTO_DST:
204 nft_reg_store16(dest, (__force u16)tuple->dst.u.all);
207 if (nf_ct_l3num(ct) != NFPROTO_IPV4)
209 *dest = tuple->src.u3.ip;
212 if (nf_ct_l3num(ct) != NFPROTO_IPV4)
214 *dest = tuple->dst.u3.ip;
217 if (nf_ct_l3num(ct) != NFPROTO_IPV6)
219 memcpy(dest, tuple->src.u3.ip6, sizeof(struct in6_addr));
222 if (nf_ct_l3num(ct) != NFPROTO_IPV6)
224 memcpy(dest, tuple->dst.u3.ip6, sizeof(struct in6_addr));
231 regs->verdict.code = NFT_BREAK;
234 #ifdef CONFIG_NF_CONNTRACK_ZONES
235 static void nft_ct_set_zone_eval(const struct nft_expr *expr,
236 struct nft_regs *regs,
237 const struct nft_pktinfo *pkt)
239 struct nf_conntrack_zone zone = { .dir = NF_CT_DEFAULT_ZONE_DIR };
240 const struct nft_ct *priv = nft_expr_priv(expr);
241 struct sk_buff *skb = pkt->skb;
242 enum ip_conntrack_info ctinfo;
243 u16 value = nft_reg_load16(®s->data[priv->sreg]);
246 ct = nf_ct_get(skb, &ctinfo);
247 if (ct) /* already tracked */
253 case IP_CT_DIR_ORIGINAL:
254 zone.dir = NF_CT_ZONE_DIR_ORIG;
256 case IP_CT_DIR_REPLY:
257 zone.dir = NF_CT_ZONE_DIR_REPL;
263 ct = this_cpu_read(nft_ct_pcpu_template);
265 if (likely(atomic_read(&ct->ct_general.use) == 1)) {
266 nf_ct_zone_add(ct, &zone);
268 /* previous skb got queued to userspace */
269 ct = nf_ct_tmpl_alloc(nft_net(pkt), &zone, GFP_ATOMIC);
271 regs->verdict.code = NF_DROP;
276 atomic_inc(&ct->ct_general.use);
277 nf_ct_set(skb, ct, IP_CT_NEW);
281 static void nft_ct_set_eval(const struct nft_expr *expr,
282 struct nft_regs *regs,
283 const struct nft_pktinfo *pkt)
285 const struct nft_ct *priv = nft_expr_priv(expr);
286 struct sk_buff *skb = pkt->skb;
287 #if defined(CONFIG_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_SECMARK)
288 u32 value = regs->data[priv->sreg];
290 enum ip_conntrack_info ctinfo;
293 ct = nf_ct_get(skb, &ctinfo);
294 if (ct == NULL || nf_ct_is_template(ct))
298 #ifdef CONFIG_NF_CONNTRACK_MARK
300 if (ct->mark != value) {
302 nf_conntrack_event_cache(IPCT_MARK, ct);
306 #ifdef CONFIG_NF_CONNTRACK_SECMARK
308 if (ct->secmark != value) {
310 nf_conntrack_event_cache(IPCT_SECMARK, ct);
314 #ifdef CONFIG_NF_CONNTRACK_LABELS
316 nf_connlabels_replace(ct,
317 ®s->data[priv->sreg],
318 ®s->data[priv->sreg],
319 NF_CT_LABELS_MAX_SIZE / sizeof(u32));
322 #ifdef CONFIG_NF_CONNTRACK_EVENTS
323 case NFT_CT_EVENTMASK: {
324 struct nf_conntrack_ecache *e = nf_ct_ecache_find(ct);
325 u32 ctmask = regs->data[priv->sreg];
328 if (e->ctmask != ctmask)
333 if (ctmask && !nf_ct_is_confirmed(ct))
334 nf_ct_ecache_ext_add(ct, ctmask, 0, GFP_ATOMIC);
343 static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
344 [NFTA_CT_DREG] = { .type = NLA_U32 },
345 [NFTA_CT_KEY] = { .type = NLA_U32 },
346 [NFTA_CT_DIRECTION] = { .type = NLA_U8 },
347 [NFTA_CT_SREG] = { .type = NLA_U32 },
350 #ifdef CONFIG_NF_CONNTRACK_ZONES
351 static void nft_ct_tmpl_put_pcpu(void)
356 for_each_possible_cpu(cpu) {
357 ct = per_cpu(nft_ct_pcpu_template, cpu);
361 per_cpu(nft_ct_pcpu_template, cpu) = NULL;
365 static bool nft_ct_tmpl_alloc_pcpu(void)
367 struct nf_conntrack_zone zone = { .id = 0 };
371 if (nft_ct_pcpu_template_refcnt)
374 for_each_possible_cpu(cpu) {
375 tmp = nf_ct_tmpl_alloc(&init_net, &zone, GFP_KERNEL);
377 nft_ct_tmpl_put_pcpu();
381 atomic_set(&tmp->ct_general.use, 1);
382 per_cpu(nft_ct_pcpu_template, cpu) = tmp;
389 static int nft_ct_get_init(const struct nft_ctx *ctx,
390 const struct nft_expr *expr,
391 const struct nlattr * const tb[])
393 struct nft_ct *priv = nft_expr_priv(expr);
397 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
398 priv->dir = IP_CT_DIR_MAX;
400 case NFT_CT_DIRECTION:
401 if (tb[NFTA_CT_DIRECTION] != NULL)
407 #ifdef CONFIG_NF_CONNTRACK_MARK
410 #ifdef CONFIG_NF_CONNTRACK_SECMARK
413 case NFT_CT_EXPIRATION:
414 if (tb[NFTA_CT_DIRECTION] != NULL)
418 #ifdef CONFIG_NF_CONNTRACK_LABELS
420 if (tb[NFTA_CT_DIRECTION] != NULL)
422 len = NF_CT_LABELS_MAX_SIZE;
426 if (tb[NFTA_CT_DIRECTION] != NULL)
428 len = NF_CT_HELPER_NAME_LEN;
431 case NFT_CT_L3PROTOCOL:
432 case NFT_CT_PROTOCOL:
433 /* For compatibility, do not report error if NFTA_CT_DIRECTION
434 * attribute is specified.
440 if (tb[NFTA_CT_DIRECTION] == NULL)
443 switch (ctx->family) {
445 len = FIELD_SIZEOF(struct nf_conntrack_tuple,
450 len = FIELD_SIZEOF(struct nf_conntrack_tuple,
454 return -EAFNOSUPPORT;
459 if (tb[NFTA_CT_DIRECTION] == NULL)
462 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip);
466 if (tb[NFTA_CT_DIRECTION] == NULL)
469 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip6);
471 case NFT_CT_PROTO_SRC:
472 case NFT_CT_PROTO_DST:
473 if (tb[NFTA_CT_DIRECTION] == NULL)
475 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
482 #ifdef CONFIG_NF_CONNTRACK_ZONES
494 if (tb[NFTA_CT_DIRECTION] != NULL) {
495 priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
497 case IP_CT_DIR_ORIGINAL:
498 case IP_CT_DIR_REPLY:
505 priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
506 err = nft_validate_register_store(ctx, priv->dreg, NULL,
507 NFT_DATA_VALUE, len);
511 err = nf_ct_netns_get(ctx->net, ctx->family);
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);
523 static void __nft_ct_set_destroy(const struct nft_ctx *ctx, struct nft_ct *priv)
526 #ifdef CONFIG_NF_CONNTRACK_LABELS
528 nf_connlabels_put(ctx->net);
531 #ifdef CONFIG_NF_CONNTRACK_ZONES
533 if (--nft_ct_pcpu_template_refcnt == 0)
534 nft_ct_tmpl_put_pcpu();
541 static int nft_ct_set_init(const struct nft_ctx *ctx,
542 const struct nft_expr *expr,
543 const struct nlattr * const tb[])
545 struct nft_ct *priv = nft_expr_priv(expr);
549 priv->dir = IP_CT_DIR_MAX;
550 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
552 #ifdef CONFIG_NF_CONNTRACK_MARK
554 if (tb[NFTA_CT_DIRECTION])
556 len = FIELD_SIZEOF(struct nf_conn, mark);
559 #ifdef CONFIG_NF_CONNTRACK_LABELS
561 if (tb[NFTA_CT_DIRECTION])
563 len = NF_CT_LABELS_MAX_SIZE;
564 err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
569 #ifdef CONFIG_NF_CONNTRACK_ZONES
571 if (!nft_ct_tmpl_alloc_pcpu())
573 nft_ct_pcpu_template_refcnt++;
577 #ifdef CONFIG_NF_CONNTRACK_EVENTS
578 case NFT_CT_EVENTMASK:
579 if (tb[NFTA_CT_DIRECTION])
584 #ifdef CONFIG_NF_CONNTRACK_SECMARK
586 if (tb[NFTA_CT_DIRECTION])
595 if (tb[NFTA_CT_DIRECTION]) {
596 priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
598 case IP_CT_DIR_ORIGINAL:
599 case IP_CT_DIR_REPLY:
607 priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
608 err = nft_validate_register_load(priv->sreg, len);
612 err = nf_ct_netns_get(ctx->net, ctx->family);
619 __nft_ct_set_destroy(ctx, priv);
623 static void nft_ct_get_destroy(const struct nft_ctx *ctx,
624 const struct nft_expr *expr)
626 nf_ct_netns_put(ctx->net, ctx->family);
629 static void nft_ct_set_destroy(const struct nft_ctx *ctx,
630 const struct nft_expr *expr)
632 struct nft_ct *priv = nft_expr_priv(expr);
634 __nft_ct_set_destroy(ctx, priv);
635 nf_ct_netns_put(ctx->net, ctx->family);
638 static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
640 const struct nft_ct *priv = nft_expr_priv(expr);
642 if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
643 goto nla_put_failure;
644 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
645 goto nla_put_failure;
654 case NFT_CT_PROTO_SRC:
655 case NFT_CT_PROTO_DST:
656 if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
657 goto nla_put_failure;
663 if (priv->dir < IP_CT_DIR_MAX &&
664 nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
665 goto nla_put_failure;
677 static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
679 const struct nft_ct *priv = nft_expr_priv(expr);
681 if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
682 goto nla_put_failure;
683 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
684 goto nla_put_failure;
688 if (priv->dir < IP_CT_DIR_MAX &&
689 nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
690 goto nla_put_failure;
702 static struct nft_expr_type nft_ct_type;
703 static const struct nft_expr_ops nft_ct_get_ops = {
704 .type = &nft_ct_type,
705 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
706 .eval = nft_ct_get_eval,
707 .init = nft_ct_get_init,
708 .destroy = nft_ct_get_destroy,
709 .dump = nft_ct_get_dump,
712 static const struct nft_expr_ops nft_ct_set_ops = {
713 .type = &nft_ct_type,
714 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
715 .eval = nft_ct_set_eval,
716 .init = nft_ct_set_init,
717 .destroy = nft_ct_set_destroy,
718 .dump = nft_ct_set_dump,
721 #ifdef CONFIG_NF_CONNTRACK_ZONES
722 static const struct nft_expr_ops nft_ct_set_zone_ops = {
723 .type = &nft_ct_type,
724 .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
725 .eval = nft_ct_set_zone_eval,
726 .init = nft_ct_set_init,
727 .destroy = nft_ct_set_destroy,
728 .dump = nft_ct_set_dump,
732 static const struct nft_expr_ops *
733 nft_ct_select_ops(const struct nft_ctx *ctx,
734 const struct nlattr * const tb[])
736 if (tb[NFTA_CT_KEY] == NULL)
737 return ERR_PTR(-EINVAL);
739 if (tb[NFTA_CT_DREG] && tb[NFTA_CT_SREG])
740 return ERR_PTR(-EINVAL);
742 if (tb[NFTA_CT_DREG])
743 return &nft_ct_get_ops;
745 if (tb[NFTA_CT_SREG]) {
746 #ifdef CONFIG_NF_CONNTRACK_ZONES
747 if (nla_get_be32(tb[NFTA_CT_KEY]) == htonl(NFT_CT_ZONE))
748 return &nft_ct_set_zone_ops;
750 return &nft_ct_set_ops;
753 return ERR_PTR(-EINVAL);
756 static struct nft_expr_type nft_ct_type __read_mostly = {
758 .select_ops = nft_ct_select_ops,
759 .policy = nft_ct_policy,
760 .maxattr = NFTA_CT_MAX,
761 .owner = THIS_MODULE,
764 static void nft_notrack_eval(const struct nft_expr *expr,
765 struct nft_regs *regs,
766 const struct nft_pktinfo *pkt)
768 struct sk_buff *skb = pkt->skb;
769 enum ip_conntrack_info ctinfo;
772 ct = nf_ct_get(pkt->skb, &ctinfo);
773 /* Previously seen (loopback or untracked)? Ignore. */
774 if (ct || ctinfo == IP_CT_UNTRACKED)
777 nf_ct_set(skb, ct, IP_CT_UNTRACKED);
780 static struct nft_expr_type nft_notrack_type;
781 static const struct nft_expr_ops nft_notrack_ops = {
782 .type = &nft_notrack_type,
783 .size = NFT_EXPR_SIZE(0),
784 .eval = nft_notrack_eval,
787 static struct nft_expr_type nft_notrack_type __read_mostly = {
789 .ops = &nft_notrack_ops,
790 .owner = THIS_MODULE,
793 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
795 nft_ct_timeout_parse_policy(void *timeouts,
796 const struct nf_conntrack_l4proto *l4proto,
797 struct net *net, const struct nlattr *attr)
802 tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb),
808 ret = nla_parse_nested_deprecated(tb,
809 l4proto->ctnl_timeout.nlattr_max,
811 l4proto->ctnl_timeout.nla_policy,
816 ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeouts);
823 struct nft_ct_timeout_obj {
824 struct nf_ct_timeout *timeout;
828 static void nft_ct_timeout_obj_eval(struct nft_object *obj,
829 struct nft_regs *regs,
830 const struct nft_pktinfo *pkt)
832 const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
833 struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
834 struct nf_conn_timeout *timeout;
835 const unsigned int *values;
837 if (priv->l4proto != pkt->tprot)
840 if (!ct || nf_ct_is_template(ct) || nf_ct_is_confirmed(ct))
843 timeout = nf_ct_timeout_find(ct);
845 timeout = nf_ct_timeout_ext_add(ct, priv->timeout, GFP_ATOMIC);
847 regs->verdict.code = NF_DROP;
852 rcu_assign_pointer(timeout->timeout, priv->timeout);
854 /* adjust the timeout as per 'new' state. ct is unconfirmed,
855 * so the current timestamp must not be added.
857 values = nf_ct_timeout_data(timeout);
859 nf_ct_refresh(ct, pkt->skb, values[0]);
862 static int nft_ct_timeout_obj_init(const struct nft_ctx *ctx,
863 const struct nlattr * const tb[],
864 struct nft_object *obj)
866 struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
867 const struct nf_conntrack_l4proto *l4proto;
868 struct nf_ct_timeout *timeout;
869 int l3num = ctx->family;
873 if (!tb[NFTA_CT_TIMEOUT_L4PROTO] ||
874 !tb[NFTA_CT_TIMEOUT_DATA])
877 if (tb[NFTA_CT_TIMEOUT_L3PROTO])
878 l3num = ntohs(nla_get_be16(tb[NFTA_CT_TIMEOUT_L3PROTO]));
880 l4num = nla_get_u8(tb[NFTA_CT_TIMEOUT_L4PROTO]);
881 priv->l4proto = l4num;
883 l4proto = nf_ct_l4proto_find(l4num);
885 if (l4proto->l4proto != l4num) {
890 timeout = kzalloc(sizeof(struct nf_ct_timeout) +
891 l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
892 if (timeout == NULL) {
897 ret = nft_ct_timeout_parse_policy(&timeout->data, l4proto, ctx->net,
898 tb[NFTA_CT_TIMEOUT_DATA]);
900 goto err_free_timeout;
902 timeout->l3num = l3num;
903 timeout->l4proto = l4proto;
905 ret = nf_ct_netns_get(ctx->net, ctx->family);
907 goto err_free_timeout;
909 priv->timeout = timeout;
918 static void nft_ct_timeout_obj_destroy(const struct nft_ctx *ctx,
919 struct nft_object *obj)
921 struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
922 struct nf_ct_timeout *timeout = priv->timeout;
924 nf_ct_untimeout(ctx->net, timeout);
925 nf_ct_netns_put(ctx->net, ctx->family);
926 kfree(priv->timeout);
929 static int nft_ct_timeout_obj_dump(struct sk_buff *skb,
930 struct nft_object *obj, bool reset)
932 const struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
933 const struct nf_ct_timeout *timeout = priv->timeout;
934 struct nlattr *nest_params;
937 if (nla_put_u8(skb, NFTA_CT_TIMEOUT_L4PROTO, timeout->l4proto->l4proto) ||
938 nla_put_be16(skb, NFTA_CT_TIMEOUT_L3PROTO, htons(timeout->l3num)))
941 nest_params = nla_nest_start(skb, NFTA_CT_TIMEOUT_DATA);
945 ret = timeout->l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->data);
948 nla_nest_end(skb, nest_params);
952 static const struct nla_policy nft_ct_timeout_policy[NFTA_CT_TIMEOUT_MAX + 1] = {
953 [NFTA_CT_TIMEOUT_L3PROTO] = {.type = NLA_U16 },
954 [NFTA_CT_TIMEOUT_L4PROTO] = {.type = NLA_U8 },
955 [NFTA_CT_TIMEOUT_DATA] = {.type = NLA_NESTED },
958 static struct nft_object_type nft_ct_timeout_obj_type;
960 static const struct nft_object_ops nft_ct_timeout_obj_ops = {
961 .type = &nft_ct_timeout_obj_type,
962 .size = sizeof(struct nft_ct_timeout_obj),
963 .eval = nft_ct_timeout_obj_eval,
964 .init = nft_ct_timeout_obj_init,
965 .destroy = nft_ct_timeout_obj_destroy,
966 .dump = nft_ct_timeout_obj_dump,
969 static struct nft_object_type nft_ct_timeout_obj_type __read_mostly = {
970 .type = NFT_OBJECT_CT_TIMEOUT,
971 .ops = &nft_ct_timeout_obj_ops,
972 .maxattr = NFTA_CT_TIMEOUT_MAX,
973 .policy = nft_ct_timeout_policy,
974 .owner = THIS_MODULE,
976 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
978 static int nft_ct_helper_obj_init(const struct nft_ctx *ctx,
979 const struct nlattr * const tb[],
980 struct nft_object *obj)
982 struct nft_ct_helper_obj *priv = nft_obj_data(obj);
983 struct nf_conntrack_helper *help4, *help6;
984 char name[NF_CT_HELPER_NAME_LEN];
985 int family = ctx->family;
988 if (!tb[NFTA_CT_HELPER_NAME] || !tb[NFTA_CT_HELPER_L4PROTO])
991 priv->l4proto = nla_get_u8(tb[NFTA_CT_HELPER_L4PROTO]);
995 nla_strlcpy(name, tb[NFTA_CT_HELPER_NAME], sizeof(name));
997 if (tb[NFTA_CT_HELPER_L3PROTO])
998 family = ntohs(nla_get_be16(tb[NFTA_CT_HELPER_L3PROTO]));
1005 if (ctx->family == NFPROTO_IPV6)
1008 help4 = nf_conntrack_helper_try_module_get(name, family,
1012 if (ctx->family == NFPROTO_IPV4)
1015 help6 = nf_conntrack_helper_try_module_get(name, family,
1018 case NFPROTO_NETDEV: /* fallthrough */
1019 case NFPROTO_BRIDGE: /* same */
1021 help4 = nf_conntrack_helper_try_module_get(name, NFPROTO_IPV4,
1023 help6 = nf_conntrack_helper_try_module_get(name, NFPROTO_IPV6,
1027 return -EAFNOSUPPORT;
1030 /* && is intentional; only error if INET found neither ipv4 or ipv6 */
1031 if (!help4 && !help6)
1034 priv->helper4 = help4;
1035 priv->helper6 = help6;
1037 err = nf_ct_netns_get(ctx->net, ctx->family);
1039 goto err_put_helper;
1045 nf_conntrack_helper_put(priv->helper4);
1047 nf_conntrack_helper_put(priv->helper6);
1051 static void nft_ct_helper_obj_destroy(const struct nft_ctx *ctx,
1052 struct nft_object *obj)
1054 struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1057 nf_conntrack_helper_put(priv->helper4);
1059 nf_conntrack_helper_put(priv->helper6);
1061 nf_ct_netns_put(ctx->net, ctx->family);
1064 static void nft_ct_helper_obj_eval(struct nft_object *obj,
1065 struct nft_regs *regs,
1066 const struct nft_pktinfo *pkt)
1068 const struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1069 struct nf_conn *ct = (struct nf_conn *)skb_nfct(pkt->skb);
1070 struct nf_conntrack_helper *to_assign = NULL;
1071 struct nf_conn_help *help;
1074 nf_ct_is_confirmed(ct) ||
1075 nf_ct_is_template(ct) ||
1076 priv->l4proto != nf_ct_protonum(ct))
1079 switch (nf_ct_l3num(ct)) {
1081 to_assign = priv->helper4;
1084 to_assign = priv->helper6;
1094 if (test_bit(IPS_HELPER_BIT, &ct->status))
1097 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
1099 rcu_assign_pointer(help->helper, to_assign);
1100 set_bit(IPS_HELPER_BIT, &ct->status);
1104 static int nft_ct_helper_obj_dump(struct sk_buff *skb,
1105 struct nft_object *obj, bool reset)
1107 const struct nft_ct_helper_obj *priv = nft_obj_data(obj);
1108 const struct nf_conntrack_helper *helper;
1111 if (priv->helper4 && priv->helper6) {
1112 family = NFPROTO_INET;
1113 helper = priv->helper4;
1114 } else if (priv->helper6) {
1115 family = NFPROTO_IPV6;
1116 helper = priv->helper6;
1118 family = NFPROTO_IPV4;
1119 helper = priv->helper4;
1122 if (nla_put_string(skb, NFTA_CT_HELPER_NAME, helper->name))
1125 if (nla_put_u8(skb, NFTA_CT_HELPER_L4PROTO, priv->l4proto))
1128 if (nla_put_be16(skb, NFTA_CT_HELPER_L3PROTO, htons(family)))
1134 static const struct nla_policy nft_ct_helper_policy[NFTA_CT_HELPER_MAX + 1] = {
1135 [NFTA_CT_HELPER_NAME] = { .type = NLA_STRING,
1136 .len = NF_CT_HELPER_NAME_LEN - 1 },
1137 [NFTA_CT_HELPER_L3PROTO] = { .type = NLA_U16 },
1138 [NFTA_CT_HELPER_L4PROTO] = { .type = NLA_U8 },
1141 static struct nft_object_type nft_ct_helper_obj_type;
1142 static const struct nft_object_ops nft_ct_helper_obj_ops = {
1143 .type = &nft_ct_helper_obj_type,
1144 .size = sizeof(struct nft_ct_helper_obj),
1145 .eval = nft_ct_helper_obj_eval,
1146 .init = nft_ct_helper_obj_init,
1147 .destroy = nft_ct_helper_obj_destroy,
1148 .dump = nft_ct_helper_obj_dump,
1151 static struct nft_object_type nft_ct_helper_obj_type __read_mostly = {
1152 .type = NFT_OBJECT_CT_HELPER,
1153 .ops = &nft_ct_helper_obj_ops,
1154 .maxattr = NFTA_CT_HELPER_MAX,
1155 .policy = nft_ct_helper_policy,
1156 .owner = THIS_MODULE,
1159 static int __init nft_ct_module_init(void)
1163 BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > NFT_REG_SIZE);
1165 err = nft_register_expr(&nft_ct_type);
1169 err = nft_register_expr(&nft_notrack_type);
1173 err = nft_register_obj(&nft_ct_helper_obj_type);
1176 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1177 err = nft_register_obj(&nft_ct_timeout_obj_type);
1183 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1185 nft_unregister_obj(&nft_ct_helper_obj_type);
1188 nft_unregister_expr(&nft_notrack_type);
1190 nft_unregister_expr(&nft_ct_type);
1194 static void __exit nft_ct_module_exit(void)
1196 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1197 nft_unregister_obj(&nft_ct_timeout_obj_type);
1199 nft_unregister_obj(&nft_ct_helper_obj_type);
1200 nft_unregister_expr(&nft_notrack_type);
1201 nft_unregister_expr(&nft_ct_type);
1204 module_init(nft_ct_module_init);
1205 module_exit(nft_ct_module_exit);
1207 MODULE_LICENSE("GPL");
1208 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
1209 MODULE_ALIAS_NFT_EXPR("ct");
1210 MODULE_ALIAS_NFT_EXPR("notrack");
1211 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER);
1212 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT);