Skip to content

Commit 717700d

Browse files
YiHungWeidavem330
authored andcommitted
netfilter: Export nf_ct_{set,destroy}_timeout()
This patch exports nf_ct_set_timeout() and nf_ct_destroy_timeout(). The two functions are derived from xt_ct_destroy_timeout() and xt_ct_set_timeout() in xt_CT.c, and moved to nf_conntrack_timeout.c without any functional change. It would be useful for other users (i.e. OVS) that utilizes the finer-grain conntrack timeout feature. CC: Pablo Neira Ayuso <[email protected]> CC: Pravin Shelar <[email protected]> Signed-off-by: Yi-Hung Wei <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c63d11b commit 717700d

File tree

3 files changed

+110
-87
lines changed

3 files changed

+110
-87
lines changed

include/net/netfilter/nf_conntrack_timeout.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ static inline unsigned int *nf_ct_timeout_lookup(const struct nf_conn *ct)
8888
int nf_conntrack_timeout_init(void);
8989
void nf_conntrack_timeout_fini(void);
9090
void nf_ct_untimeout(struct net *net, struct nf_ct_timeout *timeout);
91+
int nf_ct_set_timeout(struct net *net, struct nf_conn *ct, u8 l3num, u8 l4num,
92+
const char *timeout_name);
93+
void nf_ct_destroy_timeout(struct nf_conn *ct);
9194
#else
9295
static inline int nf_conntrack_timeout_init(void)
9396
{
@@ -98,6 +101,18 @@ static inline void nf_conntrack_timeout_fini(void)
98101
{
99102
return;
100103
}
104+
105+
static inline int nf_ct_set_timeout(struct net *net, struct nf_conn *ct,
106+
u8 l3num, u8 l4num,
107+
const char *timeout_name)
108+
{
109+
return -EOPNOTSUPP;
110+
}
111+
112+
static inline void nf_ct_destroy_timeout(struct nf_conn *ct)
113+
{
114+
return;
115+
}
101116
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
102117

103118
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT

net/netfilter/nf_conntrack_timeout.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,95 @@ void nf_ct_untimeout(struct net *net, struct nf_ct_timeout *timeout)
4848
}
4949
EXPORT_SYMBOL_GPL(nf_ct_untimeout);
5050

51+
static void __nf_ct_timeout_put(struct nf_ct_timeout *timeout)
52+
{
53+
typeof(nf_ct_timeout_put_hook) timeout_put;
54+
55+
timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
56+
if (timeout_put)
57+
timeout_put(timeout);
58+
}
59+
60+
int nf_ct_set_timeout(struct net *net, struct nf_conn *ct,
61+
u8 l3num, u8 l4num, const char *timeout_name)
62+
{
63+
typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
64+
struct nf_ct_timeout *timeout;
65+
struct nf_conn_timeout *timeout_ext;
66+
const char *errmsg = NULL;
67+
int ret = 0;
68+
69+
rcu_read_lock();
70+
timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook);
71+
if (!timeout_find_get) {
72+
ret = -ENOENT;
73+
errmsg = "Timeout policy base is empty";
74+
goto out;
75+
}
76+
77+
timeout = timeout_find_get(net, timeout_name);
78+
if (!timeout) {
79+
ret = -ENOENT;
80+
pr_info_ratelimited("No such timeout policy \"%s\"\n",
81+
timeout_name);
82+
goto out;
83+
}
84+
85+
if (timeout->l3num != l3num) {
86+
ret = -EINVAL;
87+
pr_info_ratelimited("Timeout policy `%s' can only be used by "
88+
"L%d protocol number %d\n",
89+
timeout_name, 3, timeout->l3num);
90+
goto err_put_timeout;
91+
}
92+
/* Make sure the timeout policy matches any existing protocol tracker,
93+
* otherwise default to generic.
94+
*/
95+
if (timeout->l4proto->l4proto != l4num) {
96+
ret = -EINVAL;
97+
pr_info_ratelimited("Timeout policy `%s' can only be used by "
98+
"L%d protocol number %d\n",
99+
timeout_name, 4, timeout->l4proto->l4proto);
100+
goto err_put_timeout;
101+
}
102+
timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
103+
if (!timeout_ext) {
104+
ret = -ENOMEM;
105+
goto err_put_timeout;
106+
}
107+
108+
rcu_read_unlock();
109+
return ret;
110+
111+
err_put_timeout:
112+
__nf_ct_timeout_put(timeout);
113+
out:
114+
rcu_read_unlock();
115+
if (errmsg)
116+
pr_info_ratelimited("%s\n", errmsg);
117+
return ret;
118+
}
119+
EXPORT_SYMBOL_GPL(nf_ct_set_timeout);
120+
121+
void nf_ct_destroy_timeout(struct nf_conn *ct)
122+
{
123+
struct nf_conn_timeout *timeout_ext;
124+
typeof(nf_ct_timeout_put_hook) timeout_put;
125+
126+
rcu_read_lock();
127+
timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
128+
129+
if (timeout_put) {
130+
timeout_ext = nf_ct_timeout_find(ct);
131+
if (timeout_ext) {
132+
timeout_put(timeout_ext->timeout);
133+
RCU_INIT_POINTER(timeout_ext->timeout, NULL);
134+
}
135+
}
136+
rcu_read_unlock();
137+
}
138+
EXPORT_SYMBOL_GPL(nf_ct_destroy_timeout);
139+
51140
static const struct nf_ct_ext_type timeout_extend = {
52141
.len = sizeof(struct nf_conn_timeout),
53142
.align = __alignof__(struct nf_conn_timeout),

net/netfilter/xt_CT.c

Lines changed: 6 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -103,85 +103,24 @@ xt_ct_set_helper(struct nf_conn *ct, const char *helper_name,
103103
return 0;
104104
}
105105

106-
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
107-
static void __xt_ct_tg_timeout_put(struct nf_ct_timeout *timeout)
108-
{
109-
typeof(nf_ct_timeout_put_hook) timeout_put;
110-
111-
timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
112-
if (timeout_put)
113-
timeout_put(timeout);
114-
}
115-
#endif
116-
117106
static int
118107
xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par,
119108
const char *timeout_name)
120109
{
121110
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
122-
typeof(nf_ct_timeout_find_get_hook) timeout_find_get;
123111
const struct nf_conntrack_l4proto *l4proto;
124-
struct nf_ct_timeout *timeout;
125-
struct nf_conn_timeout *timeout_ext;
126-
const char *errmsg = NULL;
127-
int ret = 0;
128112
u8 proto;
129113

130-
rcu_read_lock();
131-
timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook);
132-
if (timeout_find_get == NULL) {
133-
ret = -ENOENT;
134-
errmsg = "Timeout policy base is empty";
135-
goto out;
136-
}
137-
138114
proto = xt_ct_find_proto(par);
139115
if (!proto) {
140-
ret = -EINVAL;
141-
errmsg = "You must specify a L4 protocol and not use inversions on it";
142-
goto out;
143-
}
144-
145-
timeout = timeout_find_get(par->net, timeout_name);
146-
if (timeout == NULL) {
147-
ret = -ENOENT;
148-
pr_info_ratelimited("No such timeout policy \"%s\"\n",
149-
timeout_name);
150-
goto out;
151-
}
152-
153-
if (timeout->l3num != par->family) {
154-
ret = -EINVAL;
155-
pr_info_ratelimited("Timeout policy `%s' can only be used by L%d protocol number %d\n",
156-
timeout_name, 3, timeout->l3num);
157-
goto err_put_timeout;
116+
pr_info_ratelimited("You must specify a L4 protocol and not "
117+
"use inversions on it");
118+
return -EINVAL;
158119
}
159-
/* Make sure the timeout policy matches any existing protocol tracker,
160-
* otherwise default to generic.
161-
*/
162120
l4proto = nf_ct_l4proto_find(proto);
163-
if (timeout->l4proto->l4proto != l4proto->l4proto) {
164-
ret = -EINVAL;
165-
pr_info_ratelimited("Timeout policy `%s' can only be used by L%d protocol number %d\n",
166-
timeout_name, 4, timeout->l4proto->l4proto);
167-
goto err_put_timeout;
168-
}
169-
timeout_ext = nf_ct_timeout_ext_add(ct, timeout, GFP_ATOMIC);
170-
if (!timeout_ext) {
171-
ret = -ENOMEM;
172-
goto err_put_timeout;
173-
}
121+
return nf_ct_set_timeout(par->net, ct, par->family, l4proto->l4proto,
122+
timeout_name);
174123

175-
rcu_read_unlock();
176-
return ret;
177-
178-
err_put_timeout:
179-
__xt_ct_tg_timeout_put(timeout);
180-
out:
181-
rcu_read_unlock();
182-
if (errmsg)
183-
pr_info_ratelimited("%s\n", errmsg);
184-
return ret;
185124
#else
186125
return -EOPNOTSUPP;
187126
#endif
@@ -328,26 +267,6 @@ static int xt_ct_tg_check_v2(const struct xt_tgchk_param *par)
328267
return xt_ct_tg_check(par, par->targinfo);
329268
}
330269

331-
static void xt_ct_destroy_timeout(struct nf_conn *ct)
332-
{
333-
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
334-
struct nf_conn_timeout *timeout_ext;
335-
typeof(nf_ct_timeout_put_hook) timeout_put;
336-
337-
rcu_read_lock();
338-
timeout_put = rcu_dereference(nf_ct_timeout_put_hook);
339-
340-
if (timeout_put) {
341-
timeout_ext = nf_ct_timeout_find(ct);
342-
if (timeout_ext) {
343-
timeout_put(timeout_ext->timeout);
344-
RCU_INIT_POINTER(timeout_ext->timeout, NULL);
345-
}
346-
}
347-
rcu_read_unlock();
348-
#endif
349-
}
350-
351270
static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par,
352271
struct xt_ct_target_info_v1 *info)
353272
{
@@ -361,7 +280,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par,
361280

362281
nf_ct_netns_put(par->net, par->family);
363282

364-
xt_ct_destroy_timeout(ct);
283+
nf_ct_destroy_timeout(ct);
365284
nf_ct_put(info->ct);
366285
}
367286
}

0 commit comments

Comments
 (0)