1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
4 * (C) 2012 by Vyatta Inc. <http://www.vyatta.com>
7 #include <linux/types.h>
8 #include <linux/netfilter.h>
9 #include <linux/skbuff.h>
10 #include <linux/vmalloc.h>
11 #include <linux/stddef.h>
12 #include <linux/err.h>
13 #include <linux/percpu.h>
14 #include <linux/kernel.h>
15 #include <linux/netdevice.h>
16 #include <linux/slab.h>
17 #include <linux/export.h>
19 #include <net/netfilter/nf_conntrack.h>
20 #include <net/netfilter/nf_conntrack_core.h>
21 #include <net/netfilter/nf_conntrack_extend.h>
22 #include <net/netfilter/nf_conntrack_l4proto.h>
23 #include <net/netfilter/nf_conntrack_timeout.h>
25 const struct nf_ct_timeout_hooks __rcu
*nf_ct_timeout_hook __read_mostly
;
26 EXPORT_SYMBOL_GPL(nf_ct_timeout_hook
);
28 static int untimeout(struct nf_conn
*ct
, void *timeout
)
30 struct nf_conn_timeout
*timeout_ext
= nf_ct_timeout_find(ct
);
33 const struct nf_ct_timeout
*t
;
35 t
= rcu_access_pointer(timeout_ext
->timeout
);
37 if (!timeout
|| t
== timeout
)
38 RCU_INIT_POINTER(timeout_ext
->timeout
, NULL
);
41 /* We are not intended to delete this conntrack. */
45 void nf_ct_untimeout(struct net
*net
, struct nf_ct_timeout
*timeout
)
47 struct nf_ct_iter_data iter_data
= {
52 nf_ct_iterate_cleanup_net(untimeout
, &iter_data
);
54 EXPORT_SYMBOL_GPL(nf_ct_untimeout
);
56 static void __nf_ct_timeout_put(struct nf_ct_timeout
*timeout
)
58 const struct nf_ct_timeout_hooks
*h
= rcu_dereference(nf_ct_timeout_hook
);
61 h
->timeout_put(timeout
);
64 int nf_ct_set_timeout(struct net
*net
, struct nf_conn
*ct
,
65 u8 l3num
, u8 l4num
, const char *timeout_name
)
67 const struct nf_ct_timeout_hooks
*h
;
68 struct nf_ct_timeout
*timeout
;
69 struct nf_conn_timeout
*timeout_ext
;
70 const char *errmsg
= NULL
;
74 h
= rcu_dereference(nf_ct_timeout_hook
);
77 errmsg
= "Timeout policy base is empty";
81 timeout
= h
->timeout_find_get(net
, timeout_name
);
84 pr_info_ratelimited("No such timeout policy \"%s\"\n",
89 if (timeout
->l3num
!= l3num
) {
91 pr_info_ratelimited("Timeout policy `%s' can only be used by "
92 "L%d protocol number %d\n",
93 timeout_name
, 3, timeout
->l3num
);
96 /* Make sure the timeout policy matches any existing protocol tracker,
97 * otherwise default to generic.
99 if (timeout
->l4proto
->l4proto
!= l4num
) {
101 pr_info_ratelimited("Timeout policy `%s' can only be used by "
102 "L%d protocol number %d\n",
103 timeout_name
, 4, timeout
->l4proto
->l4proto
);
104 goto err_put_timeout
;
106 timeout_ext
= nf_ct_timeout_ext_add(ct
, timeout
, GFP_ATOMIC
);
109 goto err_put_timeout
;
116 __nf_ct_timeout_put(timeout
);
120 pr_info_ratelimited("%s\n", errmsg
);
123 EXPORT_SYMBOL_GPL(nf_ct_set_timeout
);
125 void nf_ct_destroy_timeout(struct nf_conn
*ct
)
127 struct nf_conn_timeout
*timeout_ext
;
128 const struct nf_ct_timeout_hooks
*h
;
131 h
= rcu_dereference(nf_ct_timeout_hook
);
134 timeout_ext
= nf_ct_timeout_find(ct
);
136 struct nf_ct_timeout
*t
;
138 t
= rcu_dereference(timeout_ext
->timeout
);
141 RCU_INIT_POINTER(timeout_ext
->timeout
, NULL
);
146 EXPORT_SYMBOL_GPL(nf_ct_destroy_timeout
);