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
);
185 tuple
= &ct
->tuplehash
[priv
->dir
].tuple
;
188 memcpy(dest
, tuple
->src
.u3
.all
,
189 nf_ct_l3num(ct
) == NFPROTO_IPV4
? 4 : 16);
192 memcpy(dest
, tuple
->dst
.u3
.all
,
193 nf_ct_l3num(ct
) == NFPROTO_IPV4
? 4 : 16);
195 case NFT_CT_PROTO_SRC
:
196 nft_reg_store16(dest
, (__force u16
)tuple
->src
.u
.all
);
198 case NFT_CT_PROTO_DST
:
199 nft_reg_store16(dest
, (__force u16
)tuple
->dst
.u
.all
);
202 if (nf_ct_l3num(ct
) != NFPROTO_IPV4
)
204 *dest
= tuple
->src
.u3
.ip
;
207 if (nf_ct_l3num(ct
) != NFPROTO_IPV4
)
209 *dest
= tuple
->dst
.u3
.ip
;
212 if (nf_ct_l3num(ct
) != NFPROTO_IPV6
)
214 memcpy(dest
, tuple
->src
.u3
.ip6
, sizeof(struct in6_addr
));
217 if (nf_ct_l3num(ct
) != NFPROTO_IPV6
)
219 memcpy(dest
, tuple
->dst
.u3
.ip6
, sizeof(struct in6_addr
));
226 regs
->verdict
.code
= NFT_BREAK
;
229 #ifdef CONFIG_NF_CONNTRACK_ZONES
230 static void nft_ct_set_zone_eval(const struct nft_expr
*expr
,
231 struct nft_regs
*regs
,
232 const struct nft_pktinfo
*pkt
)
234 struct nf_conntrack_zone zone
= { .dir
= NF_CT_DEFAULT_ZONE_DIR
};
235 const struct nft_ct
*priv
= nft_expr_priv(expr
);
236 struct sk_buff
*skb
= pkt
->skb
;
237 enum ip_conntrack_info ctinfo
;
238 u16 value
= nft_reg_load16(®s
->data
[priv
->sreg
]);
241 ct
= nf_ct_get(skb
, &ctinfo
);
242 if (ct
) /* already tracked */
248 case IP_CT_DIR_ORIGINAL
:
249 zone
.dir
= NF_CT_ZONE_DIR_ORIG
;
251 case IP_CT_DIR_REPLY
:
252 zone
.dir
= NF_CT_ZONE_DIR_REPL
;
258 ct
= this_cpu_read(nft_ct_pcpu_template
);
260 if (likely(atomic_read(&ct
->ct_general
.use
) == 1)) {
261 nf_ct_zone_add(ct
, &zone
);
263 /* previous skb got queued to userspace */
264 ct
= nf_ct_tmpl_alloc(nft_net(pkt
), &zone
, GFP_ATOMIC
);
266 regs
->verdict
.code
= NF_DROP
;
271 atomic_inc(&ct
->ct_general
.use
);
272 nf_ct_set(skb
, ct
, IP_CT_NEW
);
276 static void nft_ct_set_eval(const struct nft_expr
*expr
,
277 struct nft_regs
*regs
,
278 const struct nft_pktinfo
*pkt
)
280 const struct nft_ct
*priv
= nft_expr_priv(expr
);
281 struct sk_buff
*skb
= pkt
->skb
;
282 #ifdef CONFIG_NF_CONNTRACK_MARK
283 u32 value
= regs
->data
[priv
->sreg
];
285 enum ip_conntrack_info ctinfo
;
288 ct
= nf_ct_get(skb
, &ctinfo
);
289 if (ct
== NULL
|| nf_ct_is_template(ct
))
293 #ifdef CONFIG_NF_CONNTRACK_MARK
295 if (ct
->mark
!= value
) {
297 nf_conntrack_event_cache(IPCT_MARK
, ct
);
301 #ifdef CONFIG_NF_CONNTRACK_LABELS
303 nf_connlabels_replace(ct
,
304 ®s
->data
[priv
->sreg
],
305 ®s
->data
[priv
->sreg
],
306 NF_CT_LABELS_MAX_SIZE
/ sizeof(u32
));
309 #ifdef CONFIG_NF_CONNTRACK_EVENTS
310 case NFT_CT_EVENTMASK
: {
311 struct nf_conntrack_ecache
*e
= nf_ct_ecache_find(ct
);
312 u32 ctmask
= regs
->data
[priv
->sreg
];
315 if (e
->ctmask
!= ctmask
)
320 if (ctmask
&& !nf_ct_is_confirmed(ct
))
321 nf_ct_ecache_ext_add(ct
, ctmask
, 0, GFP_ATOMIC
);
330 static const struct nla_policy nft_ct_policy
[NFTA_CT_MAX
+ 1] = {
331 [NFTA_CT_DREG
] = { .type
= NLA_U32
},
332 [NFTA_CT_KEY
] = { .type
= NLA_U32
},
333 [NFTA_CT_DIRECTION
] = { .type
= NLA_U8
},
334 [NFTA_CT_SREG
] = { .type
= NLA_U32
},
337 #ifdef CONFIG_NF_CONNTRACK_ZONES
338 static void nft_ct_tmpl_put_pcpu(void)
343 for_each_possible_cpu(cpu
) {
344 ct
= per_cpu(nft_ct_pcpu_template
, cpu
);
348 per_cpu(nft_ct_pcpu_template
, cpu
) = NULL
;
352 static bool nft_ct_tmpl_alloc_pcpu(void)
354 struct nf_conntrack_zone zone
= { .id
= 0 };
358 if (nft_ct_pcpu_template_refcnt
)
361 for_each_possible_cpu(cpu
) {
362 tmp
= nf_ct_tmpl_alloc(&init_net
, &zone
, GFP_KERNEL
);
364 nft_ct_tmpl_put_pcpu();
368 atomic_set(&tmp
->ct_general
.use
, 1);
369 per_cpu(nft_ct_pcpu_template
, cpu
) = tmp
;
376 static int nft_ct_get_init(const struct nft_ctx
*ctx
,
377 const struct nft_expr
*expr
,
378 const struct nlattr
* const tb
[])
380 struct nft_ct
*priv
= nft_expr_priv(expr
);
384 priv
->key
= ntohl(nla_get_be32(tb
[NFTA_CT_KEY
]));
385 priv
->dir
= IP_CT_DIR_MAX
;
387 case NFT_CT_DIRECTION
:
388 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
394 #ifdef CONFIG_NF_CONNTRACK_MARK
397 #ifdef CONFIG_NF_CONNTRACK_SECMARK
400 case NFT_CT_EXPIRATION
:
401 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
405 #ifdef CONFIG_NF_CONNTRACK_LABELS
407 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
409 len
= NF_CT_LABELS_MAX_SIZE
;
413 if (tb
[NFTA_CT_DIRECTION
] != NULL
)
415 len
= NF_CT_HELPER_NAME_LEN
;
418 case NFT_CT_L3PROTOCOL
:
419 case NFT_CT_PROTOCOL
:
420 /* For compatibility, do not report error if NFTA_CT_DIRECTION
421 * attribute is specified.
427 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
430 switch (ctx
->family
) {
432 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
,
437 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
,
441 return -EAFNOSUPPORT
;
446 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
449 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
, src
.u3
.ip
);
453 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
456 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
, src
.u3
.ip6
);
458 case NFT_CT_PROTO_SRC
:
459 case NFT_CT_PROTO_DST
:
460 if (tb
[NFTA_CT_DIRECTION
] == NULL
)
462 len
= FIELD_SIZEOF(struct nf_conntrack_tuple
, src
.u
.all
);
469 #ifdef CONFIG_NF_CONNTRACK_ZONES
478 if (tb
[NFTA_CT_DIRECTION
] != NULL
) {
479 priv
->dir
= nla_get_u8(tb
[NFTA_CT_DIRECTION
]);
481 case IP_CT_DIR_ORIGINAL
:
482 case IP_CT_DIR_REPLY
:
489 priv
->dreg
= nft_parse_register(tb
[NFTA_CT_DREG
]);
490 err
= nft_validate_register_store(ctx
, priv
->dreg
, NULL
,
491 NFT_DATA_VALUE
, len
);
495 err
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
499 if (priv
->key
== NFT_CT_BYTES
||
500 priv
->key
== NFT_CT_PKTS
||
501 priv
->key
== NFT_CT_AVGPKT
)
502 nf_ct_set_acct(ctx
->net
, true);
507 static void __nft_ct_set_destroy(const struct nft_ctx
*ctx
, struct nft_ct
*priv
)
510 #ifdef CONFIG_NF_CONNTRACK_LABELS
512 nf_connlabels_put(ctx
->net
);
515 #ifdef CONFIG_NF_CONNTRACK_ZONES
517 if (--nft_ct_pcpu_template_refcnt
== 0)
518 nft_ct_tmpl_put_pcpu();
525 static int nft_ct_set_init(const struct nft_ctx
*ctx
,
526 const struct nft_expr
*expr
,
527 const struct nlattr
* const tb
[])
529 struct nft_ct
*priv
= nft_expr_priv(expr
);
533 priv
->dir
= IP_CT_DIR_MAX
;
534 priv
->key
= ntohl(nla_get_be32(tb
[NFTA_CT_KEY
]));
536 #ifdef CONFIG_NF_CONNTRACK_MARK
538 if (tb
[NFTA_CT_DIRECTION
])
540 len
= FIELD_SIZEOF(struct nf_conn
, mark
);
543 #ifdef CONFIG_NF_CONNTRACK_LABELS
545 if (tb
[NFTA_CT_DIRECTION
])
547 len
= NF_CT_LABELS_MAX_SIZE
;
548 err
= nf_connlabels_get(ctx
->net
, (len
* BITS_PER_BYTE
) - 1);
553 #ifdef CONFIG_NF_CONNTRACK_ZONES
555 if (!nft_ct_tmpl_alloc_pcpu())
557 nft_ct_pcpu_template_refcnt
++;
561 #ifdef CONFIG_NF_CONNTRACK_EVENTS
562 case NFT_CT_EVENTMASK
:
563 if (tb
[NFTA_CT_DIRECTION
])
572 if (tb
[NFTA_CT_DIRECTION
]) {
573 priv
->dir
= nla_get_u8(tb
[NFTA_CT_DIRECTION
]);
575 case IP_CT_DIR_ORIGINAL
:
576 case IP_CT_DIR_REPLY
:
584 priv
->sreg
= nft_parse_register(tb
[NFTA_CT_SREG
]);
585 err
= nft_validate_register_load(priv
->sreg
, len
);
589 err
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
596 __nft_ct_set_destroy(ctx
, priv
);
600 static void nft_ct_get_destroy(const struct nft_ctx
*ctx
,
601 const struct nft_expr
*expr
)
603 nf_ct_netns_put(ctx
->net
, ctx
->family
);
606 static void nft_ct_set_destroy(const struct nft_ctx
*ctx
,
607 const struct nft_expr
*expr
)
609 struct nft_ct
*priv
= nft_expr_priv(expr
);
611 __nft_ct_set_destroy(ctx
, priv
);
612 nf_ct_netns_put(ctx
->net
, ctx
->family
);
615 static int nft_ct_get_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
)
617 const struct nft_ct
*priv
= nft_expr_priv(expr
);
619 if (nft_dump_register(skb
, NFTA_CT_DREG
, priv
->dreg
))
620 goto nla_put_failure
;
621 if (nla_put_be32(skb
, NFTA_CT_KEY
, htonl(priv
->key
)))
622 goto nla_put_failure
;
631 case NFT_CT_PROTO_SRC
:
632 case NFT_CT_PROTO_DST
:
633 if (nla_put_u8(skb
, NFTA_CT_DIRECTION
, priv
->dir
))
634 goto nla_put_failure
;
640 if (priv
->dir
< IP_CT_DIR_MAX
&&
641 nla_put_u8(skb
, NFTA_CT_DIRECTION
, priv
->dir
))
642 goto nla_put_failure
;
654 static int nft_ct_set_dump(struct sk_buff
*skb
, const struct nft_expr
*expr
)
656 const struct nft_ct
*priv
= nft_expr_priv(expr
);
658 if (nft_dump_register(skb
, NFTA_CT_SREG
, priv
->sreg
))
659 goto nla_put_failure
;
660 if (nla_put_be32(skb
, NFTA_CT_KEY
, htonl(priv
->key
)))
661 goto nla_put_failure
;
665 if (priv
->dir
< IP_CT_DIR_MAX
&&
666 nla_put_u8(skb
, NFTA_CT_DIRECTION
, priv
->dir
))
667 goto nla_put_failure
;
679 static struct nft_expr_type nft_ct_type
;
680 static const struct nft_expr_ops nft_ct_get_ops
= {
681 .type
= &nft_ct_type
,
682 .size
= NFT_EXPR_SIZE(sizeof(struct nft_ct
)),
683 .eval
= nft_ct_get_eval
,
684 .init
= nft_ct_get_init
,
685 .destroy
= nft_ct_get_destroy
,
686 .dump
= nft_ct_get_dump
,
689 static const struct nft_expr_ops nft_ct_set_ops
= {
690 .type
= &nft_ct_type
,
691 .size
= NFT_EXPR_SIZE(sizeof(struct nft_ct
)),
692 .eval
= nft_ct_set_eval
,
693 .init
= nft_ct_set_init
,
694 .destroy
= nft_ct_set_destroy
,
695 .dump
= nft_ct_set_dump
,
698 #ifdef CONFIG_NF_CONNTRACK_ZONES
699 static const struct nft_expr_ops nft_ct_set_zone_ops
= {
700 .type
= &nft_ct_type
,
701 .size
= NFT_EXPR_SIZE(sizeof(struct nft_ct
)),
702 .eval
= nft_ct_set_zone_eval
,
703 .init
= nft_ct_set_init
,
704 .destroy
= nft_ct_set_destroy
,
705 .dump
= nft_ct_set_dump
,
709 static const struct nft_expr_ops
*
710 nft_ct_select_ops(const struct nft_ctx
*ctx
,
711 const struct nlattr
* const tb
[])
713 if (tb
[NFTA_CT_KEY
] == NULL
)
714 return ERR_PTR(-EINVAL
);
716 if (tb
[NFTA_CT_DREG
] && tb
[NFTA_CT_SREG
])
717 return ERR_PTR(-EINVAL
);
719 if (tb
[NFTA_CT_DREG
])
720 return &nft_ct_get_ops
;
722 if (tb
[NFTA_CT_SREG
]) {
723 #ifdef CONFIG_NF_CONNTRACK_ZONES
724 if (nla_get_be32(tb
[NFTA_CT_KEY
]) == htonl(NFT_CT_ZONE
))
725 return &nft_ct_set_zone_ops
;
727 return &nft_ct_set_ops
;
730 return ERR_PTR(-EINVAL
);
733 static struct nft_expr_type nft_ct_type __read_mostly
= {
735 .select_ops
= nft_ct_select_ops
,
736 .policy
= nft_ct_policy
,
737 .maxattr
= NFTA_CT_MAX
,
738 .owner
= THIS_MODULE
,
741 static void nft_notrack_eval(const struct nft_expr
*expr
,
742 struct nft_regs
*regs
,
743 const struct nft_pktinfo
*pkt
)
745 struct sk_buff
*skb
= pkt
->skb
;
746 enum ip_conntrack_info ctinfo
;
749 ct
= nf_ct_get(pkt
->skb
, &ctinfo
);
750 /* Previously seen (loopback or untracked)? Ignore. */
751 if (ct
|| ctinfo
== IP_CT_UNTRACKED
)
754 nf_ct_set(skb
, ct
, IP_CT_UNTRACKED
);
757 static struct nft_expr_type nft_notrack_type
;
758 static const struct nft_expr_ops nft_notrack_ops
= {
759 .type
= &nft_notrack_type
,
760 .size
= NFT_EXPR_SIZE(0),
761 .eval
= nft_notrack_eval
,
764 static struct nft_expr_type nft_notrack_type __read_mostly
= {
766 .ops
= &nft_notrack_ops
,
767 .owner
= THIS_MODULE
,
770 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
772 nft_ct_timeout_parse_policy(void *timeouts
,
773 const struct nf_conntrack_l4proto
*l4proto
,
774 struct net
*net
, const struct nlattr
*attr
)
779 if (!l4proto
->ctnl_timeout
.nlattr_to_obj
)
782 tb
= kcalloc(l4proto
->ctnl_timeout
.nlattr_max
+ 1, sizeof(*tb
),
788 ret
= nla_parse_nested(tb
, l4proto
->ctnl_timeout
.nlattr_max
,
789 attr
, l4proto
->ctnl_timeout
.nla_policy
,
794 ret
= l4proto
->ctnl_timeout
.nlattr_to_obj(tb
, net
, timeouts
);
801 struct nft_ct_timeout_obj
{
802 struct nf_ct_timeout
*timeout
;
806 static void nft_ct_timeout_obj_eval(struct nft_object
*obj
,
807 struct nft_regs
*regs
,
808 const struct nft_pktinfo
*pkt
)
810 const struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
811 struct nf_conn
*ct
= (struct nf_conn
*)skb_nfct(pkt
->skb
);
812 struct nf_conn_timeout
*timeout
;
813 const unsigned int *values
;
815 if (priv
->l4proto
!= pkt
->tprot
)
818 if (!ct
|| nf_ct_is_template(ct
) || nf_ct_is_confirmed(ct
))
821 timeout
= nf_ct_timeout_find(ct
);
823 timeout
= nf_ct_timeout_ext_add(ct
, priv
->timeout
, GFP_ATOMIC
);
825 regs
->verdict
.code
= NF_DROP
;
830 rcu_assign_pointer(timeout
->timeout
, priv
->timeout
);
832 /* adjust the timeout as per 'new' state. ct is unconfirmed,
833 * so the current timestamp must not be added.
835 values
= nf_ct_timeout_data(timeout
);
837 nf_ct_refresh(ct
, pkt
->skb
, values
[0]);
840 static int nft_ct_timeout_obj_init(const struct nft_ctx
*ctx
,
841 const struct nlattr
* const tb
[],
842 struct nft_object
*obj
)
844 struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
845 const struct nf_conntrack_l4proto
*l4proto
;
846 struct nf_ct_timeout
*timeout
;
847 int l3num
= ctx
->family
;
851 if (!tb
[NFTA_CT_TIMEOUT_L4PROTO
] ||
852 !tb
[NFTA_CT_TIMEOUT_DATA
])
855 if (tb
[NFTA_CT_TIMEOUT_L3PROTO
])
856 l3num
= ntohs(nla_get_be16(tb
[NFTA_CT_TIMEOUT_L3PROTO
]));
858 l4num
= nla_get_u8(tb
[NFTA_CT_TIMEOUT_L4PROTO
]);
859 priv
->l4proto
= l4num
;
861 l4proto
= nf_ct_l4proto_find_get(l3num
, l4num
);
863 if (l4proto
->l4proto
!= l4num
) {
868 timeout
= kzalloc(sizeof(struct nf_ct_timeout
) +
869 l4proto
->ctnl_timeout
.obj_size
, GFP_KERNEL
);
870 if (timeout
== NULL
) {
875 ret
= nft_ct_timeout_parse_policy(&timeout
->data
, l4proto
, ctx
->net
,
876 tb
[NFTA_CT_TIMEOUT_DATA
]);
878 goto err_free_timeout
;
880 timeout
->l3num
= l3num
;
881 timeout
->l4proto
= l4proto
;
883 ret
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
885 goto err_free_timeout
;
887 priv
->timeout
= timeout
;
893 nf_ct_l4proto_put(l4proto
);
897 static void nft_ct_timeout_obj_destroy(const struct nft_ctx
*ctx
,
898 struct nft_object
*obj
)
900 struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
901 struct nf_ct_timeout
*timeout
= priv
->timeout
;
903 nf_ct_untimeout(ctx
->net
, timeout
);
904 nf_ct_l4proto_put(timeout
->l4proto
);
905 nf_ct_netns_put(ctx
->net
, ctx
->family
);
906 kfree(priv
->timeout
);
909 static int nft_ct_timeout_obj_dump(struct sk_buff
*skb
,
910 struct nft_object
*obj
, bool reset
)
912 const struct nft_ct_timeout_obj
*priv
= nft_obj_data(obj
);
913 const struct nf_ct_timeout
*timeout
= priv
->timeout
;
914 struct nlattr
*nest_params
;
917 if (nla_put_u8(skb
, NFTA_CT_TIMEOUT_L4PROTO
, timeout
->l4proto
->l4proto
) ||
918 nla_put_be16(skb
, NFTA_CT_TIMEOUT_L3PROTO
, htons(timeout
->l3num
)))
921 nest_params
= nla_nest_start(skb
, NFTA_CT_TIMEOUT_DATA
| NLA_F_NESTED
);
925 ret
= timeout
->l4proto
->ctnl_timeout
.obj_to_nlattr(skb
, &timeout
->data
);
928 nla_nest_end(skb
, nest_params
);
932 static const struct nla_policy nft_ct_timeout_policy
[NFTA_CT_TIMEOUT_MAX
+ 1] = {
933 [NFTA_CT_TIMEOUT_L3PROTO
] = {.type
= NLA_U16
},
934 [NFTA_CT_TIMEOUT_L4PROTO
] = {.type
= NLA_U8
},
935 [NFTA_CT_TIMEOUT_DATA
] = {.type
= NLA_NESTED
},
938 static struct nft_object_type nft_ct_timeout_obj_type
;
940 static const struct nft_object_ops nft_ct_timeout_obj_ops
= {
941 .type
= &nft_ct_timeout_obj_type
,
942 .size
= sizeof(struct nft_ct_timeout_obj
),
943 .eval
= nft_ct_timeout_obj_eval
,
944 .init
= nft_ct_timeout_obj_init
,
945 .destroy
= nft_ct_timeout_obj_destroy
,
946 .dump
= nft_ct_timeout_obj_dump
,
949 static struct nft_object_type nft_ct_timeout_obj_type __read_mostly
= {
950 .type
= NFT_OBJECT_CT_TIMEOUT
,
951 .ops
= &nft_ct_timeout_obj_ops
,
952 .maxattr
= NFTA_CT_TIMEOUT_MAX
,
953 .policy
= nft_ct_timeout_policy
,
954 .owner
= THIS_MODULE
,
956 #endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
958 static int nft_ct_helper_obj_init(const struct nft_ctx
*ctx
,
959 const struct nlattr
* const tb
[],
960 struct nft_object
*obj
)
962 struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
963 struct nf_conntrack_helper
*help4
, *help6
;
964 char name
[NF_CT_HELPER_NAME_LEN
];
965 int family
= ctx
->family
;
968 if (!tb
[NFTA_CT_HELPER_NAME
] || !tb
[NFTA_CT_HELPER_L4PROTO
])
971 priv
->l4proto
= nla_get_u8(tb
[NFTA_CT_HELPER_L4PROTO
]);
975 nla_strlcpy(name
, tb
[NFTA_CT_HELPER_NAME
], sizeof(name
));
977 if (tb
[NFTA_CT_HELPER_L3PROTO
])
978 family
= ntohs(nla_get_be16(tb
[NFTA_CT_HELPER_L3PROTO
]));
985 if (ctx
->family
== NFPROTO_IPV6
)
988 help4
= nf_conntrack_helper_try_module_get(name
, family
,
992 if (ctx
->family
== NFPROTO_IPV4
)
995 help6
= nf_conntrack_helper_try_module_get(name
, family
,
998 case NFPROTO_NETDEV
: /* fallthrough */
999 case NFPROTO_BRIDGE
: /* same */
1001 help4
= nf_conntrack_helper_try_module_get(name
, NFPROTO_IPV4
,
1003 help6
= nf_conntrack_helper_try_module_get(name
, NFPROTO_IPV6
,
1007 return -EAFNOSUPPORT
;
1010 /* && is intentional; only error if INET found neither ipv4 or ipv6 */
1011 if (!help4
&& !help6
)
1014 priv
->helper4
= help4
;
1015 priv
->helper6
= help6
;
1017 err
= nf_ct_netns_get(ctx
->net
, ctx
->family
);
1019 goto err_put_helper
;
1025 nf_conntrack_helper_put(priv
->helper4
);
1027 nf_conntrack_helper_put(priv
->helper6
);
1031 static void nft_ct_helper_obj_destroy(const struct nft_ctx
*ctx
,
1032 struct nft_object
*obj
)
1034 struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
1037 nf_conntrack_helper_put(priv
->helper4
);
1039 nf_conntrack_helper_put(priv
->helper6
);
1041 nf_ct_netns_put(ctx
->net
, ctx
->family
);
1044 static void nft_ct_helper_obj_eval(struct nft_object
*obj
,
1045 struct nft_regs
*regs
,
1046 const struct nft_pktinfo
*pkt
)
1048 const struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
1049 struct nf_conn
*ct
= (struct nf_conn
*)skb_nfct(pkt
->skb
);
1050 struct nf_conntrack_helper
*to_assign
= NULL
;
1051 struct nf_conn_help
*help
;
1054 nf_ct_is_confirmed(ct
) ||
1055 nf_ct_is_template(ct
) ||
1056 priv
->l4proto
!= nf_ct_protonum(ct
))
1059 switch (nf_ct_l3num(ct
)) {
1061 to_assign
= priv
->helper4
;
1064 to_assign
= priv
->helper6
;
1074 if (test_bit(IPS_HELPER_BIT
, &ct
->status
))
1077 help
= nf_ct_helper_ext_add(ct
, GFP_ATOMIC
);
1079 rcu_assign_pointer(help
->helper
, to_assign
);
1080 set_bit(IPS_HELPER_BIT
, &ct
->status
);
1084 static int nft_ct_helper_obj_dump(struct sk_buff
*skb
,
1085 struct nft_object
*obj
, bool reset
)
1087 const struct nft_ct_helper_obj
*priv
= nft_obj_data(obj
);
1088 const struct nf_conntrack_helper
*helper
;
1091 if (priv
->helper4
&& priv
->helper6
) {
1092 family
= NFPROTO_INET
;
1093 helper
= priv
->helper4
;
1094 } else if (priv
->helper6
) {
1095 family
= NFPROTO_IPV6
;
1096 helper
= priv
->helper6
;
1098 family
= NFPROTO_IPV4
;
1099 helper
= priv
->helper4
;
1102 if (nla_put_string(skb
, NFTA_CT_HELPER_NAME
, helper
->name
))
1105 if (nla_put_u8(skb
, NFTA_CT_HELPER_L4PROTO
, priv
->l4proto
))
1108 if (nla_put_be16(skb
, NFTA_CT_HELPER_L3PROTO
, htons(family
)))
1114 static const struct nla_policy nft_ct_helper_policy
[NFTA_CT_HELPER_MAX
+ 1] = {
1115 [NFTA_CT_HELPER_NAME
] = { .type
= NLA_STRING
,
1116 .len
= NF_CT_HELPER_NAME_LEN
- 1 },
1117 [NFTA_CT_HELPER_L3PROTO
] = { .type
= NLA_U16
},
1118 [NFTA_CT_HELPER_L4PROTO
] = { .type
= NLA_U8
},
1121 static struct nft_object_type nft_ct_helper_obj_type
;
1122 static const struct nft_object_ops nft_ct_helper_obj_ops
= {
1123 .type
= &nft_ct_helper_obj_type
,
1124 .size
= sizeof(struct nft_ct_helper_obj
),
1125 .eval
= nft_ct_helper_obj_eval
,
1126 .init
= nft_ct_helper_obj_init
,
1127 .destroy
= nft_ct_helper_obj_destroy
,
1128 .dump
= nft_ct_helper_obj_dump
,
1131 static struct nft_object_type nft_ct_helper_obj_type __read_mostly
= {
1132 .type
= NFT_OBJECT_CT_HELPER
,
1133 .ops
= &nft_ct_helper_obj_ops
,
1134 .maxattr
= NFTA_CT_HELPER_MAX
,
1135 .policy
= nft_ct_helper_policy
,
1136 .owner
= THIS_MODULE
,
1139 static int __init
nft_ct_module_init(void)
1143 BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE
> NFT_REG_SIZE
);
1145 err
= nft_register_expr(&nft_ct_type
);
1149 err
= nft_register_expr(&nft_notrack_type
);
1153 err
= nft_register_obj(&nft_ct_helper_obj_type
);
1156 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1157 err
= nft_register_obj(&nft_ct_timeout_obj_type
);
1163 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1165 nft_unregister_obj(&nft_ct_helper_obj_type
);
1168 nft_unregister_expr(&nft_notrack_type
);
1170 nft_unregister_expr(&nft_ct_type
);
1174 static void __exit
nft_ct_module_exit(void)
1176 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1177 nft_unregister_obj(&nft_ct_timeout_obj_type
);
1179 nft_unregister_obj(&nft_ct_helper_obj_type
);
1180 nft_unregister_expr(&nft_notrack_type
);
1181 nft_unregister_expr(&nft_ct_type
);
1184 module_init(nft_ct_module_init
);
1185 module_exit(nft_ct_module_exit
);
1187 MODULE_LICENSE("GPL");
1188 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
1189 MODULE_ALIAS_NFT_EXPR("ct");
1190 MODULE_ALIAS_NFT_EXPR("notrack");
1191 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER
);
1192 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT
);