1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
4 * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org>
6 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/netlink.h>
13 #include <linux/netfilter.h>
14 #include <linux/netfilter/nf_tables.h>
15 #include <net/netfilter/nf_tables.h>
16 #include <net/netfilter/nf_conntrack.h>
17 #include <net/netfilter/nf_conntrack_acct.h>
18 #include <net/netfilter/nf_conntrack_tuple.h>
19 #include <net/netfilter/nf_conntrack_helper.h>
20 #include <net/netfilter/nf_conntrack_ecache.h>
21 #include <net/netfilter/nf_conntrack_labels.h>
22 #include <net/netfilter/nf_conntrack_timeout.h>
23 #include <net/netfilter/nf_conntrack_l4proto.h>
26 enum nft_ct_keys key
:8;
27 enum ip_conntrack_dir dir
:8;
29 enum nft_registers dreg
:8;
30 enum nft_registers sreg
:8;
34 struct nft_ct_helper_obj
{
35 struct nf_conntrack_helper
*helper4
;
36 struct nf_conntrack_helper
*helper6
;
40 #ifdef CONFIG_NF_CONNTRACK_ZONES
41 static DEFINE_PER_CPU(struct nf_conn
*, nft_ct_pcpu_template
);
42 static unsigned int nft_ct_pcpu_template_refcnt __read_mostly
;
45 static u64
nft_ct_get_eval_counter(const struct nf_conn_counter
*c
,
47 enum ip_conntrack_dir d
)
49 if (d
< IP_CT_DIR_MAX
)
50 return k
== NFT_CT_BYTES
? atomic64_read(&c
[d
].bytes
) :
51 atomic64_read(&c
[d
].packets
);
53 return nft_ct_get_eval_counter(c
, k
, IP_CT_DIR_ORIGINAL
) +
54 nft_ct_get_eval_counter(c
, k
, IP_CT_DIR_REPLY
);
57 static void nft_ct_get_eval(const struct nft_expr
*expr
,
58 struct nft_regs
*regs
,
59 const struct nft_pktinfo
*pkt
)
61 const struct nft_ct
*priv
= nft_expr_priv(expr
);
62 u32
*dest
= ®s
->data
[priv
->dreg
];
63 enum ip_conntrack_info ctinfo
;
64 const struct nf_conn
*ct
;
65 const struct nf_conn_help
*help
;
66 const struct nf_conntrack_tuple
*tuple
;
67 const struct nf_conntrack_helper
*helper
;
70 ct
= nf_ct_get(pkt
->skb
, &ctinfo
);
75 state
= NF_CT_STATE_BIT(ctinfo
);
76 else if (ctinfo
== IP_CT_UNTRACKED
)
77 state
= NF_CT_STATE_UNTRACKED_BIT
;
79 state
= NF_CT_STATE_INVALID_BIT
;
90 case NFT_CT_DIRECTION
:
91 nft_reg_store8(dest
, CTINFO2DIR(ctinfo
));
96 #ifdef CONFIG_NF_CONNTRACK_MARK
101 #ifdef CONFIG_NF_CONNTRACK_SECMARK
106 case NFT_CT_EXPIRATION
:
107 *dest
= jiffies_to_msecs(nf_ct_expires(ct
));
110 if (ct
->master
== NULL
)
112 help
= nfct_help(ct
->master
);
115 helper
= rcu_dereference(help
->helper
);
118 strncpy((char *)dest
, helper
->name
, NF_CT_HELPER_NAME_LEN
);
120 #ifdef CONFIG_NF_CONNTRACK_LABELS
121 case NFT_CT_LABELS
: {
122 struct nf_conn_labels
*labels
= nf_ct_labels_find(ct
);
125 memcpy(dest
, labels
->bits
, NF_CT_LABELS_MAX_SIZE
);
127 memset(dest
, 0, NF_CT_LABELS_MAX_SIZE
);
131 case NFT_CT_BYTES
: /* fallthrough */
133 const struct nf_conn_acct
*acct
= nf_conn_acct_find(ct
);
137 count
= nft_ct_get_eval_counter(acct
->counter
,
138 priv
->key
, priv
->dir
);
139 memcpy(dest
, &count
, sizeof(count
));
142 case NFT_CT_AVGPKT
: {
143 const struct nf_conn_acct
*acct
= nf_conn_acct_find(ct
);
144 u64 avgcnt
= 0, bcnt
= 0, pcnt
= 0;
147 pcnt
= nft_ct_get_eval_counter(acct
->counter
,
148 NFT_CT_PKTS
, priv
->dir
);
149 bcnt
= nft_ct_get_eval_counter(acct
->counter
,
150 NFT_CT_BYTES
, priv
->dir
);
152 avgcnt
= div64_u64(bcnt
, pcnt
);
155 memcpy(dest
, &avgcnt
, sizeof(avgcnt
));
158 case NFT_CT_L3PROTOCOL
:
159 nft_reg_store8(dest
, nf_ct_l3num(ct
));
161 case NFT_CT_PROTOCOL
:
162 nft_reg_store8(dest
, nf_ct_protonum(ct
));
164 #ifdef CONFIG_NF_CONNTRACK_ZONES
166 const struct nf_conntrack_zone
*zone
= nf_ct_zone(ct
);
169 if (priv
->dir
< IP_CT_DIR_MAX
)
170 zoneid
= nf_ct_zone_id(zone
, priv
->dir
);
174 nft_reg_store16(dest
, zoneid
);
179 if (!nf_ct_is_confirmed(ct
))
181 *dest
= nf_ct_get_id(ct
);
187 tuple
= &ct
->tuplehash
[priv
->dir
].tuple
;
190 memcpy(dest
, tuple
->src
.u3
.all
,
191 nf_ct_l3num(ct
) == NFPROTO_IPV4
? 4 : 16);
194 memcpy(dest
, tuple
->dst
.u3
.all
,
195 nf_ct_l3num(ct
) == NFPROTO_IPV4
? 4 : 16);
197 case NFT_CT_PROTO_SRC
:
198 nft_reg_store16(dest
, (__force u16
)tuple
->src
.u
.all
);
200 case NFT_CT_PROTO_DST
:
201 nft_reg_store16(dest
, (__force u16
)tuple
->dst
.u
.all
);
204 if (nf_ct_l3num(ct
) != NFPROTO_IPV4
)
206 *dest
= tuple
->src
.u3
.ip
;
209 if (nf_ct_l3num(ct
) != NFPROTO_IPV4
)
211 *dest
= tuple
->dst
.u3
.ip
;
214 if (nf_ct_l3num(ct
) != NFPROTO_IPV6
)
216 memcpy(dest
, tuple
->src
.u3
.ip6
, sizeof(struct in6_addr
));
219 if (nf_ct_l3num(ct
) != NFPROTO_IPV6
)
221 memcpy(dest
, tuple
->dst
.u3
.ip6
, sizeof(struct in6_addr
));
228 regs
->verdict
.code
= NFT_BREAK
;
231 #ifdef CONFIG_NF_CONNTRACK_ZONES
232 static void nft_ct_set_zone_eval(const struct nft_expr
*expr
,
233 struct nft_regs
*regs
,
234 const struct nft_pktinfo
*pkt
)
236 struct nf_conntrack_zone zone
= { .dir
= NF_CT_DEFAULT_ZONE_DIR
};
237 const struct nft_ct
*priv
= nft_expr_priv(expr
);
238 struct sk_buff
*skb
= pkt
->skb
;
239 enum ip_conntrack_info ctinfo
;
240 u16 value
= nft_reg_load16(®s
->data
[priv
->sreg
]);
243 ct
= nf_ct_get(skb
, &ctinfo
);
244 if (ct
) /* already tracked */
250 case IP_CT_DIR_ORIGINAL
:
251 zone
.dir
= NF_CT_ZONE_DIR_ORIG
;
253 case IP_CT_DIR_REPLY
:
254 zone
.dir
= NF_CT_ZONE_DIR_REPL
;
260 ct
= this_cpu_read(nft_ct_pcpu_template
);
262 if (likely(atomic_read(&ct
->ct_general
.use
) == 1)) {
263 nf_ct_zone_add(ct
, &zone
);
265 /* previous skb got queued to userspace */
266 ct
= nf_ct_tmpl_alloc(nft_net(pkt
), &zone
, GFP_ATOMIC
);
268 regs
->verdict
.code
= NF_DROP
;
273 atomic_inc(&ct
->ct_general
.use
);
274 nf_ct_set(skb
, ct
, IP_CT_NEW
);
278 static void nft_ct_set_eval(const struct nft_expr
*expr
,
279 struct nft_regs
*regs
,
280 const struct nft_pktinfo
*pkt
)
282 const struct nft_ct
*priv
= nft_expr_priv(expr
);
283 struct sk_buff
*skb
= pkt
->skb
;
284 #if defined(CONFIG_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_SECMARK)
285 u32 value
= regs
->data
[priv
->sreg
];
287 enum ip_conntrack_info ctinfo
;
290 ct
= nf_ct_get(skb
, &ctinfo
);
291 if (ct
== NULL
|| nf_ct_is_template(ct
))
295 #ifdef CONFIG_NF_CONNTRACK_MARK
297 if (ct
->mark
!= value
) {
299 nf_conntrack_event_cache(IPCT_MARK
, ct
);
303 #ifdef CONFIG_NF_CONNTRACK_SECMARK
305 if (ct
->secmark
!= value
) {
307 nf_conntrack_event_cache(IPCT_SECMARK
, ct
);
311 #ifdef CONFIG_NF_CONNTRACK_LABELS
313 nf_connlabels_replace(ct
,
314 ®s
->data
[priv
->sreg
],
315 ®s
->data
[priv
->sreg
],
316 NF_CT_LABELS_MAX_SIZE
/ sizeof(u32
));
319 #ifdef CONFIG_NF_CONNTRACK_EVENTS
320 case NFT_CT_EVENTMASK
: {
321 struct nf_conntrack_ecache
*e
= nf_ct_ecache_find(ct
);
322 u32 ctmask
= regs
->data
[priv
->sreg
];
325 if (e
->ctmask
!= ctmask
)
330 if (ctmask
&& !nf_ct_is_confirmed(ct
))
331 nf_ct_ecache_ext_add(ct
, ctmask
, 0, GFP_ATOMIC
);
340 static const struct nla_policy nft_ct_policy
[NFTA_CT_MAX
+ 1] = {
341 [NFTA_CT_DREG
] = { .type
= NLA_U32
},
342 [NFTA_CT_KEY
] = { .type
= NLA_U32
},
343 [NFTA_CT_DIRECTION
] = { .type
= NLA_U8
},
344 [NFTA_CT_SREG
] = { .type
= NLA_U32
},
347 #ifdef CONFIG_NF_CONNTRACK_ZONES
348 static void nft_ct_tmpl_put_pcpu(void)
353 for_each_possible_cpu(cpu
) {
354 ct
= per_cpu(nft_ct_pcpu_template
, cpu
);
358 per_cpu(nft_ct_pcpu_template
, cpu
) = NULL
;
362 static bool nft_ct_tmpl_alloc_pcpu(void)
364 struct nf_conntrack_zone zone
= { .id
= 0 };
368 if (nft_ct_pcpu_template_refcnt
)
371 for_each_possible_cpu(cpu
) {
372 tmp
= nf_ct_tmpl_alloc(&init_net
, &zone
, GFP_KERNEL
);
374 nft_ct_tmpl_put_pcpu();
378 atomic_set(&tmp
->ct_general
.use
, 1);
379 per_cpu(nft_ct_pcpu_template
, cpu
) = tmp
;
386 static int nft_ct_get_init(const struct nft_ctx
*ctx
,
387 const struct nft_expr
*expr
,
388 const struct nlattr
* const tb
[])
390 struct nft_ct
*priv
= nft_expr_priv(expr
);
394 priv
->key
= ntohl(nla_get_be32(tb
[NFTA_CT_KEY
]));
395 priv
->dir
= IP_CT_DIR_MAX
;
397 case NFT_CT_DIRECTION
:
398 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
404 #ifdef CONFIG_NF_CONNTRACK_MARK
407 #ifdef CONFIG_NF_CONNTRACK_SECMARK
410 case NFT_CT_EXPIRATION
:
411 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
415 #ifdef CONFIG_NF_CONNTRACK_LABELS
417 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
419 len
= NF_CT_LABELS_MAX_SIZE
;
423 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
425 len
= NF_CT_HELPER_NAME_LEN
;
428 case NFT_CT_L3PROTOCOL
:
429 case NFT_CT_PROTOCOL
:
430 /* For compatibility, do not report error if NFTA_CT_DIRECTION
431 * attribute is specified.
437 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
440 switch (ctx
->family
) {
442 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
,
447 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
,
451 return -EAFNOSUPPORT
;
456 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
459 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
, src
.u3
.ip
);
463 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
466 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
, src
.u3
.ip6
);
468 case NFT_CT_PROTO_SRC
:
469 case NFT_CT_PROTO_DST
:
470 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
472 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
, src
.u
.all
);
479 #ifdef CONFIG_NF_CONNTRACK_ZONES
491 if (tb
[NFTA_CT_DIRECTION
] != NULL
) {
492 priv
->dir
= nla_get_u8(tb
[NFTA_CT_DIRECTION
]);
494 case IP_CT_DIR_ORIGINAL
:
495 case IP_CT_DIR_REPLY
:
502 priv
->dreg
= nft_parse_register(tb
[NFTA_CT_DREG
]);
503 err
= nft_validate_register_store(ctx
, priv
->dreg
, NULL
,
504 NFT_DATA_VALUE
, len
);
508 err
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
512 if (priv
->key
== NFT_CT_BYTES
||
513 priv
->key
== NFT_CT_PKTS
||
514 priv
->key
== NFT_CT_AVGPKT
)
515 nf_ct_set_acct(ctx
->net
, true);
520 static void __nft_ct_set_destroy(const struct nft_ctx
*ctx
, struct nft_ct
*priv
)
523 #ifdef CONFIG_NF_CONNTRACK_LABELS
525 nf_connlabels_put(ctx
->net
);
528 #ifdef CONFIG_NF_CONNTRACK_ZONES
530 if (--nft_ct_pcpu_template_refcnt
== 0)
531 nft_ct_tmpl_put_pcpu();
538 static int nft_ct_set_init(const struct nft_ctx
*ctx
,
539 const struct nft_expr
*expr
,
540 const struct nlattr
* const tb
[])
542 struct nft_ct
*priv
= nft_expr_priv(expr
);
546 priv
->dir
= IP_CT_DIR_MAX
;
547 priv
->key
= ntohl(nla_get_be32(tb
[NFTA_CT_KEY
]));
549 #ifdef CONFIG_NF_CONNTRACK_MARK
551 if (tb
[NFTA_CT_DIRECTION
])
553 len
= FIELD_SIZEOF(struct nf_conn
, mark
);
556 #ifdef CONFIG_NF_CONNTRACK_LABELS
558 if (tb
[NFTA_CT_DIRECTION
])
560 len
= NF_CT_LABELS_MAX_SIZE
;
561 err
= nf_connlabels_get(ctx
->net
, (len
* BITS_PER_BYTE
) - 1);
566 #ifdef CONFIG_NF_CONNTRACK_ZONES
568 if (!nft_ct_tmpl_alloc_pcpu())
570 nft_ct_pcpu_template_refcnt
++;
574 #ifdef CONFIG_NF_CONNTRACK_EVENTS
575 case NFT_CT_EVENTMASK
:
576 if (tb
[NFTA_CT_DIRECTION
])
581 #ifdef CONFIG_NF_CONNTRACK_SECMARK
583 if (tb
[NFTA_CT_DIRECTION
])
592 if (tb
[NFTA_CT_DIRECTION
]) {
593 priv
->dir
= nla_get_u8(tb
[NFTA_CT_DIRECTION
]);
595 case IP_CT_DIR_ORIGINAL
:
596 case IP_CT_DIR_REPLY
:
604 priv
->sreg
= nft_parse_register(tb
[NFTA_CT_SREG
]);
605 err
= nft_validate_register_load(priv
->sreg
, len
);
609 err
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
616 __nft_ct_set_destroy(ctx
, priv
);
620 static void nft_ct_get_destroy(const struct nft_ctx
*ctx
,
621 const struct nft_expr
*expr
)
623 nf_ct_netns_put(ctx
->net
, ctx
->family
);
626 static void nft_ct_set_destroy(const struct nft_ctx
*ctx
,
627 const struct nft_expr
*expr
)
629 struct nft_ct
*priv
= nft_expr_priv(expr
);
631 __nft_ct_set_destroy(ctx
, priv
);
632 nf_ct_netns_put(ctx
->net
, ctx
->family
);
635 static int nft_ct_get_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
)
637 const struct nft_ct
*priv
= nft_expr_priv(expr
);
639 if (nft_dump_register(skb
, NFTA_CT_DREG
, priv
->dreg
))
640 goto nla_put_failure
;
641 if (nla_put_be32(skb
, NFTA_CT_KEY
, htonl(priv
->key
)))
642 goto nla_put_failure
;
651 case NFT_CT_PROTO_SRC
:
652 case NFT_CT_PROTO_DST
:
653 if (nla_put_u8(skb
, NFTA_CT_DIRECTION
, priv
->dir
))
654 goto nla_put_failure
;
660 if (priv
->dir
< IP_CT_DIR_MAX
&&
661 nla_put_u8(skb
, NFTA_CT_DIRECTION
, priv
->dir
))
662 goto nla_put_failure
;
674 static int nft_ct_set_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
)
676 const struct nft_ct
*priv
= nft_expr_priv(expr
);
678 if (nft_dump_register(skb
, NFTA_CT_SREG
, priv
->sreg
))
679 goto nla_put_failure
;
680 if (nla_put_be32(skb
, NFTA_CT_KEY
, htonl(priv
->key
)))
681 goto nla_put_failure
;
685 if (priv
->dir
< IP_CT_DIR_MAX
&&
686 nla_put_u8(skb
, NFTA_CT_DIRECTION
, priv
->dir
))
687 goto nla_put_failure
;
699 static struct nft_expr_type nft_ct_type
;
700 static const struct nft_expr_ops nft_ct_get_ops
= {
701 .type
= &nft_ct_type
,
702 .size
= NFT_EXPR_SIZE(sizeof(struct nft_ct
)),
703 .eval
= nft_ct_get_eval
,
704 .init
= nft_ct_get_init
,
705 .destroy
= nft_ct_get_destroy
,
706 .dump
= nft_ct_get_dump
,
709 static const struct nft_expr_ops nft_ct_set_ops
= {
710 .type
= &nft_ct_type
,
711 .size
= NFT_EXPR_SIZE(sizeof(struct nft_ct
)),
712 .eval
= nft_ct_set_eval
,
713 .init
= nft_ct_set_init
,
714 .destroy
= nft_ct_set_destroy
,
715 .dump
= nft_ct_set_dump
,
718 #ifdef CONFIG_NF_CONNTRACK_ZONES
719 static const struct nft_expr_ops nft_ct_set_zone_ops
= {
720 .type
= &nft_ct_type
,
721 .size
= NFT_EXPR_SIZE(sizeof(struct nft_ct
)),
722 .eval
= nft_ct_set_zone_eval
,
723 .init
= nft_ct_set_init
,
724 .destroy
= nft_ct_set_destroy
,
725 .dump
= nft_ct_set_dump
,
729 static const struct nft_expr_ops
*
730 nft_ct_select_ops(const struct nft_ctx
*ctx
,
731 const struct nlattr
* const tb
[])
733 if (tb
[NFTA_CT_KEY
] == NULL
)
734 return ERR_PTR(-EINVAL
);
736 if (tb
[NFTA_CT_DREG
] && tb
[NFTA_CT_SREG
])
737 return ERR_PTR(-EINVAL
);
739 if (tb
[NFTA_CT_DREG
])
740 return &nft_ct_get_ops
;
742 if (tb
[NFTA_CT_SREG
]) {
743 #ifdef CONFIG_NF_CONNTRACK_ZONES
744 if (nla_get_be32(tb
[NFTA_CT_KEY
]) == htonl(NFT_CT_ZONE
))
745 return &nft_ct_set_zone_ops
;
747 return &nft_ct_set_ops
;
750 return ERR_PTR(-EINVAL
);
753 static struct nft_expr_type nft_ct_type __read_mostly
= {
755 .select_ops
= nft_ct_select_ops
,
756 .policy
= nft_ct_policy
,
757 .maxattr
= NFTA_CT_MAX
,
758 .owner
= THIS_MODULE
,
761 static void nft_notrack_eval(const struct nft_expr
*expr
,
762 struct nft_regs
*regs
,
763 const struct nft_pktinfo
*pkt
)
765 struct sk_buff
*skb
= pkt
->skb
;
766 enum ip_conntrack_info ctinfo
;
769 ct
= nf_ct_get(pkt
->skb
, &ctinfo
);
770 /* Previously seen (loopback or untracked)? Ignore. */
771 if (ct
|| ctinfo
== IP_CT_UNTRACKED
)
774 nf_ct_set(skb
, ct
, IP_CT_UNTRACKED
);
777 static struct nft_expr_type nft_notrack_type
;
778 static const struct nft_expr_ops nft_notrack_ops
= {
779 .type
= &nft_notrack_type
,
780 .size
= NFT_EXPR_SIZE(0),
781 .eval
= nft_notrack_eval
,
784 static struct nft_expr_type nft_notrack_type __read_mostly
= {
786 .ops
= &nft_notrack_ops
,
787 .owner
= THIS_MODULE
,
790 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
792 nft_ct_timeout_parse_policy(void *timeouts
,
793 const struct nf_conntrack_l4proto
*l4proto
,
794 struct net
*net
, const struct nlattr
*attr
)
799 tb
= kcalloc(l4proto
->ctnl_timeout
.nlattr_max
+ 1, sizeof(*tb
),
805 ret
= nla_parse_nested_deprecated(tb
,
806 l4proto
->ctnl_timeout
.nlattr_max
,
808 l4proto
->ctnl_timeout
.nla_policy
,
813 ret
= l4proto
->ctnl_timeout
.nlattr_to_obj(tb
, net
, timeouts
);
820 struct nft_ct_timeout_obj
{
821 struct nf_ct_timeout
*timeout
;
825 static void nft_ct_timeout_obj_eval(struct nft_object
*obj
,
826 struct nft_regs
*regs
,
827 const struct nft_pktinfo
*pkt
)
829 const struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
830 struct nf_conn
*ct
= (struct nf_conn
*)skb_nfct(pkt
->skb
);
831 struct nf_conn_timeout
*timeout
;
832 const unsigned int *values
;
834 if (priv
->l4proto
!= pkt
->tprot
)
837 if (!ct
|| nf_ct_is_template(ct
) || nf_ct_is_confirmed(ct
))
840 timeout
= nf_ct_timeout_find(ct
);
842 timeout
= nf_ct_timeout_ext_add(ct
, priv
->timeout
, GFP_ATOMIC
);
844 regs
->verdict
.code
= NF_DROP
;
849 rcu_assign_pointer(timeout
->timeout
, priv
->timeout
);
851 /* adjust the timeout as per 'new' state. ct is unconfirmed,
852 * so the current timestamp must not be added.
854 values
= nf_ct_timeout_data(timeout
);
856 nf_ct_refresh(ct
, pkt
->skb
, values
[0]);
859 static int nft_ct_timeout_obj_init(const struct nft_ctx
*ctx
,
860 const struct nlattr
* const tb
[],
861 struct nft_object
*obj
)
863 struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
864 const struct nf_conntrack_l4proto
*l4proto
;
865 struct nf_ct_timeout
*timeout
;
866 int l3num
= ctx
->family
;
870 if (!tb
[NFTA_CT_TIMEOUT_L4PROTO
] ||
871 !tb
[NFTA_CT_TIMEOUT_DATA
])
874 if (tb
[NFTA_CT_TIMEOUT_L3PROTO
])
875 l3num
= ntohs(nla_get_be16(tb
[NFTA_CT_TIMEOUT_L3PROTO
]));
877 l4num
= nla_get_u8(tb
[NFTA_CT_TIMEOUT_L4PROTO
]);
878 priv
->l4proto
= l4num
;
880 l4proto
= nf_ct_l4proto_find(l4num
);
882 if (l4proto
->l4proto
!= l4num
) {
887 timeout
= kzalloc(sizeof(struct nf_ct_timeout
) +
888 l4proto
->ctnl_timeout
.obj_size
, GFP_KERNEL
);
889 if (timeout
== NULL
) {
894 ret
= nft_ct_timeout_parse_policy(&timeout
->data
, l4proto
, ctx
->net
,
895 tb
[NFTA_CT_TIMEOUT_DATA
]);
897 goto err_free_timeout
;
899 timeout
->l3num
= l3num
;
900 timeout
->l4proto
= l4proto
;
902 ret
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
904 goto err_free_timeout
;
906 priv
->timeout
= timeout
;
915 static void nft_ct_timeout_obj_destroy(const struct nft_ctx
*ctx
,
916 struct nft_object
*obj
)
918 struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
919 struct nf_ct_timeout
*timeout
= priv
->timeout
;
921 nf_ct_untimeout(ctx
->net
, timeout
);
922 nf_ct_netns_put(ctx
->net
, ctx
->family
);
923 kfree(priv
->timeout
);
926 static int nft_ct_timeout_obj_dump(struct sk_buff
*skb
,
927 struct nft_object
*obj
, bool reset
)
929 const struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
930 const struct nf_ct_timeout
*timeout
= priv
->timeout
;
931 struct nlattr
*nest_params
;
934 if (nla_put_u8(skb
, NFTA_CT_TIMEOUT_L4PROTO
, timeout
->l4proto
->l4proto
) ||
935 nla_put_be16(skb
, NFTA_CT_TIMEOUT_L3PROTO
, htons(timeout
->l3num
)))
938 nest_params
= nla_nest_start(skb
, NFTA_CT_TIMEOUT_DATA
);
942 ret
= timeout
->l4proto
->ctnl_timeout
.obj_to_nlattr(skb
, &timeout
->data
);
945 nla_nest_end(skb
, nest_params
);
949 static const struct nla_policy nft_ct_timeout_policy
[NFTA_CT_TIMEOUT_MAX
+ 1] = {
950 [NFTA_CT_TIMEOUT_L3PROTO
] = {.type
= NLA_U16
},
951 [NFTA_CT_TIMEOUT_L4PROTO
] = {.type
= NLA_U8
},
952 [NFTA_CT_TIMEOUT_DATA
] = {.type
= NLA_NESTED
},
955 static struct nft_object_type nft_ct_timeout_obj_type
;
957 static const struct nft_object_ops nft_ct_timeout_obj_ops
= {
958 .type
= &nft_ct_timeout_obj_type
,
959 .size
= sizeof(struct nft_ct_timeout_obj
),
960 .eval
= nft_ct_timeout_obj_eval
,
961 .init
= nft_ct_timeout_obj_init
,
962 .destroy
= nft_ct_timeout_obj_destroy
,
963 .dump
= nft_ct_timeout_obj_dump
,
966 static struct nft_object_type nft_ct_timeout_obj_type __read_mostly
= {
967 .type
= NFT_OBJECT_CT_TIMEOUT
,
968 .ops
= &nft_ct_timeout_obj_ops
,
969 .maxattr
= NFTA_CT_TIMEOUT_MAX
,
970 .policy
= nft_ct_timeout_policy
,
971 .owner
= THIS_MODULE
,
973 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
975 static int nft_ct_helper_obj_init(const struct nft_ctx
*ctx
,
976 const struct nlattr
* const tb
[],
977 struct nft_object
*obj
)
979 struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
980 struct nf_conntrack_helper
*help4
, *help6
;
981 char name
[NF_CT_HELPER_NAME_LEN
];
982 int family
= ctx
->family
;
985 if (!tb
[NFTA_CT_HELPER_NAME
] || !tb
[NFTA_CT_HELPER_L4PROTO
])
988 priv
->l4proto
= nla_get_u8(tb
[NFTA_CT_HELPER_L4PROTO
]);
992 nla_strlcpy(name
, tb
[NFTA_CT_HELPER_NAME
], sizeof(name
));
994 if (tb
[NFTA_CT_HELPER_L3PROTO
])
995 family
= ntohs(nla_get_be16(tb
[NFTA_CT_HELPER_L3PROTO
]));
1002 if (ctx
->family
== NFPROTO_IPV6
)
1005 help4
= nf_conntrack_helper_try_module_get(name
, family
,
1009 if (ctx
->family
== NFPROTO_IPV4
)
1012 help6
= nf_conntrack_helper_try_module_get(name
, family
,
1015 case NFPROTO_NETDEV
: /* fallthrough */
1016 case NFPROTO_BRIDGE
: /* same */
1018 help4
= nf_conntrack_helper_try_module_get(name
, NFPROTO_IPV4
,
1020 help6
= nf_conntrack_helper_try_module_get(name
, NFPROTO_IPV6
,
1024 return -EAFNOSUPPORT
;
1027 /* && is intentional; only error if INET found neither ipv4 or ipv6 */
1028 if (!help4
&& !help6
)
1031 priv
->helper4
= help4
;
1032 priv
->helper6
= help6
;
1034 err
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
1036 goto err_put_helper
;
1042 nf_conntrack_helper_put(priv
->helper4
);
1044 nf_conntrack_helper_put(priv
->helper6
);
1048 static void nft_ct_helper_obj_destroy(const struct nft_ctx
*ctx
,
1049 struct nft_object
*obj
)
1051 struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
1054 nf_conntrack_helper_put(priv
->helper4
);
1056 nf_conntrack_helper_put(priv
->helper6
);
1058 nf_ct_netns_put(ctx
->net
, ctx
->family
);
1061 static void nft_ct_helper_obj_eval(struct nft_object
*obj
,
1062 struct nft_regs
*regs
,
1063 const struct nft_pktinfo
*pkt
)
1065 const struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
1066 struct nf_conn
*ct
= (struct nf_conn
*)skb_nfct(pkt
->skb
);
1067 struct nf_conntrack_helper
*to_assign
= NULL
;
1068 struct nf_conn_help
*help
;
1071 nf_ct_is_confirmed(ct
) ||
1072 nf_ct_is_template(ct
) ||
1073 priv
->l4proto
!= nf_ct_protonum(ct
))
1076 switch (nf_ct_l3num(ct
)) {
1078 to_assign
= priv
->helper4
;
1081 to_assign
= priv
->helper6
;
1091 if (test_bit(IPS_HELPER_BIT
, &ct
->status
))
1094 help
= nf_ct_helper_ext_add(ct
, GFP_ATOMIC
);
1096 rcu_assign_pointer(help
->helper
, to_assign
);
1097 set_bit(IPS_HELPER_BIT
, &ct
->status
);
1101 static int nft_ct_helper_obj_dump(struct sk_buff
*skb
,
1102 struct nft_object
*obj
, bool reset
)
1104 const struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
1105 const struct nf_conntrack_helper
*helper
;
1108 if (priv
->helper4
&& priv
->helper6
) {
1109 family
= NFPROTO_INET
;
1110 helper
= priv
->helper4
;
1111 } else if (priv
->helper6
) {
1112 family
= NFPROTO_IPV6
;
1113 helper
= priv
->helper6
;
1115 family
= NFPROTO_IPV4
;
1116 helper
= priv
->helper4
;
1119 if (nla_put_string(skb
, NFTA_CT_HELPER_NAME
, helper
->name
))
1122 if (nla_put_u8(skb
, NFTA_CT_HELPER_L4PROTO
, priv
->l4proto
))
1125 if (nla_put_be16(skb
, NFTA_CT_HELPER_L3PROTO
, htons(family
)))
1131 static const struct nla_policy nft_ct_helper_policy
[NFTA_CT_HELPER_MAX
+ 1] = {
1132 [NFTA_CT_HELPER_NAME
] = { .type
= NLA_STRING
,
1133 .len
= NF_CT_HELPER_NAME_LEN
- 1 },
1134 [NFTA_CT_HELPER_L3PROTO
] = { .type
= NLA_U16
},
1135 [NFTA_CT_HELPER_L4PROTO
] = { .type
= NLA_U8
},
1138 static struct nft_object_type nft_ct_helper_obj_type
;
1139 static const struct nft_object_ops nft_ct_helper_obj_ops
= {
1140 .type
= &nft_ct_helper_obj_type
,
1141 .size
= sizeof(struct nft_ct_helper_obj
),
1142 .eval
= nft_ct_helper_obj_eval
,
1143 .init
= nft_ct_helper_obj_init
,
1144 .destroy
= nft_ct_helper_obj_destroy
,
1145 .dump
= nft_ct_helper_obj_dump
,
1148 static struct nft_object_type nft_ct_helper_obj_type __read_mostly
= {
1149 .type
= NFT_OBJECT_CT_HELPER
,
1150 .ops
= &nft_ct_helper_obj_ops
,
1151 .maxattr
= NFTA_CT_HELPER_MAX
,
1152 .policy
= nft_ct_helper_policy
,
1153 .owner
= THIS_MODULE
,
1156 static int __init
nft_ct_module_init(void)
1160 BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE
> NFT_REG_SIZE
);
1162 err
= nft_register_expr(&nft_ct_type
);
1166 err
= nft_register_expr(&nft_notrack_type
);
1170 err
= nft_register_obj(&nft_ct_helper_obj_type
);
1173 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1174 err
= nft_register_obj(&nft_ct_timeout_obj_type
);
1180 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1182 nft_unregister_obj(&nft_ct_helper_obj_type
);
1185 nft_unregister_expr(&nft_notrack_type
);
1187 nft_unregister_expr(&nft_ct_type
);
1191 static void __exit
nft_ct_module_exit(void)
1193 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1194 nft_unregister_obj(&nft_ct_timeout_obj_type
);
1196 nft_unregister_obj(&nft_ct_helper_obj_type
);
1197 nft_unregister_expr(&nft_notrack_type
);
1198 nft_unregister_expr(&nft_ct_type
);
1201 module_init(nft_ct_module_init
);
1202 module_exit(nft_ct_module_exit
);
1204 MODULE_LICENSE("GPL");
1205 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
1206 MODULE_ALIAS_NFT_EXPR("ct");
1207 MODULE_ALIAS_NFT_EXPR("notrack");
1208 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER
);
1209 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT
);