• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
4  * (C) 2012 by Vyatta Inc. <http://www.vyatta.com>
5  */
6 #include <linux/init.h>
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/rculist.h>
10 #include <linux/rculist_nulls.h>
11 #include <linux/types.h>
12 #include <linux/timer.h>
13 #include <linux/security.h>
14 #include <linux/skbuff.h>
15 #include <linux/errno.h>
16 #include <linux/netlink.h>
17 #include <linux/spinlock.h>
18 #include <linux/interrupt.h>
19 #include <linux/slab.h>
20 
21 #include <linux/netfilter.h>
22 #include <net/netlink.h>
23 #include <net/sock.h>
24 #include <net/netfilter/nf_conntrack.h>
25 #include <net/netfilter/nf_conntrack_core.h>
26 #include <net/netfilter/nf_conntrack_l4proto.h>
27 #include <net/netfilter/nf_conntrack_tuple.h>
28 #include <net/netfilter/nf_conntrack_timeout.h>
29 
30 #include <linux/netfilter/nfnetlink.h>
31 #include <linux/netfilter/nfnetlink_cttimeout.h>
32 
33 MODULE_LICENSE("GPL");
34 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
35 MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tuning");
36 
37 static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
38 	[CTA_TIMEOUT_NAME]	= { .type = NLA_NUL_STRING,
39 				    .len  = CTNL_TIMEOUT_NAME_MAX - 1},
40 	[CTA_TIMEOUT_L3PROTO]	= { .type = NLA_U16 },
41 	[CTA_TIMEOUT_L4PROTO]	= { .type = NLA_U8 },
42 	[CTA_TIMEOUT_DATA]	= { .type = NLA_NESTED },
43 };
44 
45 static int
ctnl_timeout_parse_policy(void * timeout,const struct nf_conntrack_l4proto * l4proto,struct net * net,const struct nlattr * attr)46 ctnl_timeout_parse_policy(void *timeout,
47 			  const struct nf_conntrack_l4proto *l4proto,
48 			  struct net *net, const struct nlattr *attr)
49 {
50 	struct nlattr **tb;
51 	int ret = 0;
52 
53 	tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb),
54 		     GFP_KERNEL);
55 
56 	if (!tb)
57 		return -ENOMEM;
58 
59 	ret = nla_parse_nested_deprecated(tb,
60 					  l4proto->ctnl_timeout.nlattr_max,
61 					  attr,
62 					  l4proto->ctnl_timeout.nla_policy,
63 					  NULL);
64 	if (ret < 0)
65 		goto err;
66 
67 	ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeout);
68 
69 err:
70 	kfree(tb);
71 	return ret;
72 }
73 
cttimeout_new_timeout(struct net * net,struct sock * ctnl,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const cda[],struct netlink_ext_ack * extack)74 static int cttimeout_new_timeout(struct net *net, struct sock *ctnl,
75 				 struct sk_buff *skb,
76 				 const struct nlmsghdr *nlh,
77 				 const struct nlattr * const cda[],
78 				 struct netlink_ext_ack *extack)
79 {
80 	__u16 l3num;
81 	__u8 l4num;
82 	const struct nf_conntrack_l4proto *l4proto;
83 	struct ctnl_timeout *timeout, *matching = NULL;
84 	char *name;
85 	int ret;
86 
87 	if (!cda[CTA_TIMEOUT_NAME] ||
88 	    !cda[CTA_TIMEOUT_L3PROTO] ||
89 	    !cda[CTA_TIMEOUT_L4PROTO] ||
90 	    !cda[CTA_TIMEOUT_DATA])
91 		return -EINVAL;
92 
93 	name = nla_data(cda[CTA_TIMEOUT_NAME]);
94 	l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
95 	l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
96 
97 	list_for_each_entry(timeout, &net->nfct_timeout_list, head) {
98 		if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
99 			continue;
100 
101 		if (nlh->nlmsg_flags & NLM_F_EXCL)
102 			return -EEXIST;
103 
104 		matching = timeout;
105 		break;
106 	}
107 
108 	if (matching) {
109 		if (nlh->nlmsg_flags & NLM_F_REPLACE) {
110 			/* You cannot replace one timeout policy by another of
111 			 * different kind, sorry.
112 			 */
113 			if (matching->timeout.l3num != l3num ||
114 			    matching->timeout.l4proto->l4proto != l4num)
115 				return -EINVAL;
116 
117 			return ctnl_timeout_parse_policy(&matching->timeout.data,
118 							 matching->timeout.l4proto,
119 							 net, cda[CTA_TIMEOUT_DATA]);
120 		}
121 
122 		return -EBUSY;
123 	}
124 
125 	l4proto = nf_ct_l4proto_find(l4num);
126 
127 	/* This protocol is not supportted, skip. */
128 	if (l4proto->l4proto != l4num) {
129 		ret = -EOPNOTSUPP;
130 		goto err_proto_put;
131 	}
132 
133 	timeout = kzalloc(sizeof(struct ctnl_timeout) +
134 			  l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
135 	if (timeout == NULL) {
136 		ret = -ENOMEM;
137 		goto err_proto_put;
138 	}
139 
140 	ret = ctnl_timeout_parse_policy(&timeout->timeout.data, l4proto, net,
141 					cda[CTA_TIMEOUT_DATA]);
142 	if (ret < 0)
143 		goto err;
144 
145 	strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
146 	timeout->timeout.l3num = l3num;
147 	timeout->timeout.l4proto = l4proto;
148 	refcount_set(&timeout->refcnt, 1);
149 	list_add_tail_rcu(&timeout->head, &net->nfct_timeout_list);
150 
151 	return 0;
152 err:
153 	kfree(timeout);
154 err_proto_put:
155 	return ret;
156 }
157 
158 static int
ctnl_timeout_fill_info(struct sk_buff * skb,u32 portid,u32 seq,u32 type,int event,struct ctnl_timeout * timeout)159 ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
160 		       int event, struct ctnl_timeout *timeout)
161 {
162 	struct nlmsghdr *nlh;
163 	unsigned int flags = portid ? NLM_F_MULTI : 0;
164 	const struct nf_conntrack_l4proto *l4proto = timeout->timeout.l4proto;
165 	struct nlattr *nest_parms;
166 	int ret;
167 
168 	event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event);
169 	nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
170 			   NFNETLINK_V0, 0);
171 	if (!nlh)
172 		goto nlmsg_failure;
173 
174 	if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) ||
175 	    nla_put_be16(skb, CTA_TIMEOUT_L3PROTO,
176 			 htons(timeout->timeout.l3num)) ||
177 	    nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto) ||
178 	    nla_put_be32(skb, CTA_TIMEOUT_USE,
179 			 htonl(refcount_read(&timeout->refcnt))))
180 		goto nla_put_failure;
181 
182 	nest_parms = nla_nest_start(skb, CTA_TIMEOUT_DATA);
183 	if (!nest_parms)
184 		goto nla_put_failure;
185 
186 	ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->timeout.data);
187 	if (ret < 0)
188 		goto nla_put_failure;
189 
190 	nla_nest_end(skb, nest_parms);
191 
192 	nlmsg_end(skb, nlh);
193 	return skb->len;
194 
195 nlmsg_failure:
196 nla_put_failure:
197 	nlmsg_cancel(skb, nlh);
198 	return -1;
199 }
200 
201 static int
ctnl_timeout_dump(struct sk_buff * skb,struct netlink_callback * cb)202 ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb)
203 {
204 	struct net *net = sock_net(skb->sk);
205 	struct ctnl_timeout *cur, *last;
206 
207 	if (cb->args[2])
208 		return 0;
209 
210 	last = (struct ctnl_timeout *)cb->args[1];
211 	if (cb->args[1])
212 		cb->args[1] = 0;
213 
214 	rcu_read_lock();
215 	list_for_each_entry_rcu(cur, &net->nfct_timeout_list, head) {
216 		if (last) {
217 			if (cur != last)
218 				continue;
219 
220 			last = NULL;
221 		}
222 		if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid,
223 					   cb->nlh->nlmsg_seq,
224 					   NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
225 					   IPCTNL_MSG_TIMEOUT_NEW, cur) < 0) {
226 			cb->args[1] = (unsigned long)cur;
227 			break;
228 		}
229 	}
230 	if (!cb->args[1])
231 		cb->args[2] = 1;
232 	rcu_read_unlock();
233 	return skb->len;
234 }
235 
cttimeout_get_timeout(struct net * net,struct sock * ctnl,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const cda[],struct netlink_ext_ack * extack)236 static int cttimeout_get_timeout(struct net *net, struct sock *ctnl,
237 				 struct sk_buff *skb,
238 				 const struct nlmsghdr *nlh,
239 				 const struct nlattr * const cda[],
240 				 struct netlink_ext_ack *extack)
241 {
242 	int ret = -ENOENT;
243 	char *name;
244 	struct ctnl_timeout *cur;
245 
246 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
247 		struct netlink_dump_control c = {
248 			.dump = ctnl_timeout_dump,
249 		};
250 		return netlink_dump_start(ctnl, skb, nlh, &c);
251 	}
252 
253 	if (!cda[CTA_TIMEOUT_NAME])
254 		return -EINVAL;
255 	name = nla_data(cda[CTA_TIMEOUT_NAME]);
256 
257 	list_for_each_entry(cur, &net->nfct_timeout_list, head) {
258 		struct sk_buff *skb2;
259 
260 		if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
261 			continue;
262 
263 		skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
264 		if (skb2 == NULL) {
265 			ret = -ENOMEM;
266 			break;
267 		}
268 
269 		ret = ctnl_timeout_fill_info(skb2, NETLINK_CB(skb).portid,
270 					     nlh->nlmsg_seq,
271 					     NFNL_MSG_TYPE(nlh->nlmsg_type),
272 					     IPCTNL_MSG_TIMEOUT_NEW, cur);
273 		if (ret <= 0) {
274 			kfree_skb(skb2);
275 			break;
276 		}
277 		ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid,
278 					MSG_DONTWAIT);
279 		if (ret > 0)
280 			ret = 0;
281 
282 		/* this avoids a loop in nfnetlink. */
283 		return ret == -EAGAIN ? -ENOBUFS : ret;
284 	}
285 	return ret;
286 }
287 
288 /* try to delete object, fail if it is still in use. */
ctnl_timeout_try_del(struct net * net,struct ctnl_timeout * timeout)289 static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout)
290 {
291 	int ret = 0;
292 
293 	/* We want to avoid races with ctnl_timeout_put. So only when the
294 	 * current refcnt is 1, we decrease it to 0.
295 	 */
296 	if (refcount_dec_if_one(&timeout->refcnt)) {
297 		/* We are protected by nfnl mutex. */
298 		list_del_rcu(&timeout->head);
299 		nf_ct_untimeout(net, &timeout->timeout);
300 		kfree_rcu(timeout, rcu_head);
301 	} else {
302 		ret = -EBUSY;
303 	}
304 	return ret;
305 }
306 
cttimeout_del_timeout(struct net * net,struct sock * ctnl,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const cda[],struct netlink_ext_ack * extack)307 static int cttimeout_del_timeout(struct net *net, struct sock *ctnl,
308 				 struct sk_buff *skb,
309 				 const struct nlmsghdr *nlh,
310 				 const struct nlattr * const cda[],
311 				 struct netlink_ext_ack *extack)
312 {
313 	struct ctnl_timeout *cur, *tmp;
314 	int ret = -ENOENT;
315 	char *name;
316 
317 	if (!cda[CTA_TIMEOUT_NAME]) {
318 		list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list,
319 					 head)
320 			ctnl_timeout_try_del(net, cur);
321 
322 		return 0;
323 	}
324 	name = nla_data(cda[CTA_TIMEOUT_NAME]);
325 
326 	list_for_each_entry(cur, &net->nfct_timeout_list, head) {
327 		if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
328 			continue;
329 
330 		ret = ctnl_timeout_try_del(net, cur);
331 		if (ret < 0)
332 			return ret;
333 
334 		break;
335 	}
336 	return ret;
337 }
338 
cttimeout_default_set(struct net * net,struct sock * ctnl,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const cda[],struct netlink_ext_ack * extack)339 static int cttimeout_default_set(struct net *net, struct sock *ctnl,
340 				 struct sk_buff *skb,
341 				 const struct nlmsghdr *nlh,
342 				 const struct nlattr * const cda[],
343 				 struct netlink_ext_ack *extack)
344 {
345 	const struct nf_conntrack_l4proto *l4proto;
346 	__u8 l4num;
347 	int ret;
348 
349 	if (!cda[CTA_TIMEOUT_L3PROTO] ||
350 	    !cda[CTA_TIMEOUT_L4PROTO] ||
351 	    !cda[CTA_TIMEOUT_DATA])
352 		return -EINVAL;
353 
354 	l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
355 	l4proto = nf_ct_l4proto_find(l4num);
356 
357 	/* This protocol is not supported, skip. */
358 	if (l4proto->l4proto != l4num) {
359 		ret = -EOPNOTSUPP;
360 		goto err;
361 	}
362 
363 	ret = ctnl_timeout_parse_policy(NULL, l4proto, net,
364 					cda[CTA_TIMEOUT_DATA]);
365 	if (ret < 0)
366 		goto err;
367 
368 	return 0;
369 err:
370 	return ret;
371 }
372 
373 static int
cttimeout_default_fill_info(struct net * net,struct sk_buff * skb,u32 portid,u32 seq,u32 type,int event,u16 l3num,const struct nf_conntrack_l4proto * l4proto,const unsigned int * timeouts)374 cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
375 			    u32 seq, u32 type, int event, u16 l3num,
376 			    const struct nf_conntrack_l4proto *l4proto,
377 			    const unsigned int *timeouts)
378 {
379 	struct nlmsghdr *nlh;
380 	unsigned int flags = portid ? NLM_F_MULTI : 0;
381 	struct nlattr *nest_parms;
382 	int ret;
383 
384 	event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event);
385 	nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
386 			   NFNETLINK_V0, 0);
387 	if (!nlh)
388 		goto nlmsg_failure;
389 
390 	if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l3num)) ||
391 	    nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto))
392 		goto nla_put_failure;
393 
394 	nest_parms = nla_nest_start(skb, CTA_TIMEOUT_DATA);
395 	if (!nest_parms)
396 		goto nla_put_failure;
397 
398 	ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
399 	if (ret < 0)
400 		goto nla_put_failure;
401 
402 	nla_nest_end(skb, nest_parms);
403 
404 	nlmsg_end(skb, nlh);
405 	return skb->len;
406 
407 nlmsg_failure:
408 nla_put_failure:
409 	nlmsg_cancel(skb, nlh);
410 	return -1;
411 }
412 
cttimeout_default_get(struct net * net,struct sock * ctnl,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const cda[],struct netlink_ext_ack * extack)413 static int cttimeout_default_get(struct net *net, struct sock *ctnl,
414 				 struct sk_buff *skb,
415 				 const struct nlmsghdr *nlh,
416 				 const struct nlattr * const cda[],
417 				 struct netlink_ext_ack *extack)
418 {
419 	const struct nf_conntrack_l4proto *l4proto;
420 	unsigned int *timeouts = NULL;
421 	struct sk_buff *skb2;
422 	int ret, err;
423 	__u16 l3num;
424 	__u8 l4num;
425 
426 	if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO])
427 		return -EINVAL;
428 
429 	l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
430 	l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
431 	l4proto = nf_ct_l4proto_find(l4num);
432 
433 	err = -EOPNOTSUPP;
434 	if (l4proto->l4proto != l4num)
435 		goto err;
436 
437 	switch (l4proto->l4proto) {
438 	case IPPROTO_ICMP:
439 		timeouts = &nf_icmp_pernet(net)->timeout;
440 		break;
441 	case IPPROTO_TCP:
442 		timeouts = nf_tcp_pernet(net)->timeouts;
443 		break;
444 	case IPPROTO_UDP: /* fallthrough */
445 	case IPPROTO_UDPLITE:
446 		timeouts = nf_udp_pernet(net)->timeouts;
447 		break;
448 	case IPPROTO_DCCP:
449 #ifdef CONFIG_NF_CT_PROTO_DCCP
450 		timeouts = nf_dccp_pernet(net)->dccp_timeout;
451 #endif
452 		break;
453 	case IPPROTO_ICMPV6:
454 		timeouts = &nf_icmpv6_pernet(net)->timeout;
455 		break;
456 	case IPPROTO_SCTP:
457 #ifdef CONFIG_NF_CT_PROTO_SCTP
458 		timeouts = nf_sctp_pernet(net)->timeouts;
459 #endif
460 		break;
461 	case IPPROTO_GRE:
462 #ifdef CONFIG_NF_CT_PROTO_GRE
463 		timeouts = nf_gre_pernet(net)->timeouts;
464 #endif
465 		break;
466 	case 255:
467 		timeouts = &nf_generic_pernet(net)->timeout;
468 		break;
469 	default:
470 		WARN_ONCE(1, "Missing timeouts for proto %d", l4proto->l4proto);
471 		break;
472 	}
473 
474 	if (!timeouts)
475 		goto err;
476 
477 	skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
478 	if (skb2 == NULL) {
479 		err = -ENOMEM;
480 		goto err;
481 	}
482 
483 	ret = cttimeout_default_fill_info(net, skb2, NETLINK_CB(skb).portid,
484 					  nlh->nlmsg_seq,
485 					  NFNL_MSG_TYPE(nlh->nlmsg_type),
486 					  IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
487 					  l3num, l4proto, timeouts);
488 	if (ret <= 0) {
489 		kfree_skb(skb2);
490 		err = -ENOMEM;
491 		goto err;
492 	}
493 	ret = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
494 	if (ret > 0)
495 		ret = 0;
496 
497 	/* this avoids a loop in nfnetlink. */
498 	return ret == -EAGAIN ? -ENOBUFS : ret;
499 err:
500 	return err;
501 }
502 
ctnl_timeout_find_get(struct net * net,const char * name)503 static struct nf_ct_timeout *ctnl_timeout_find_get(struct net *net,
504 						   const char *name)
505 {
506 	struct ctnl_timeout *timeout, *matching = NULL;
507 
508 	list_for_each_entry_rcu(timeout, &net->nfct_timeout_list, head) {
509 		if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
510 			continue;
511 
512 		if (!try_module_get(THIS_MODULE))
513 			goto err;
514 
515 		if (!refcount_inc_not_zero(&timeout->refcnt)) {
516 			module_put(THIS_MODULE);
517 			goto err;
518 		}
519 		matching = timeout;
520 		break;
521 	}
522 err:
523 	return matching ? &matching->timeout : NULL;
524 }
525 
ctnl_timeout_put(struct nf_ct_timeout * t)526 static void ctnl_timeout_put(struct nf_ct_timeout *t)
527 {
528 	struct ctnl_timeout *timeout =
529 		container_of(t, struct ctnl_timeout, timeout);
530 
531 	if (refcount_dec_and_test(&timeout->refcnt))
532 		kfree_rcu(timeout, rcu_head);
533 
534 	module_put(THIS_MODULE);
535 }
536 
537 static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {
538 	[IPCTNL_MSG_TIMEOUT_NEW]	= { .call = cttimeout_new_timeout,
539 					    .attr_count = CTA_TIMEOUT_MAX,
540 					    .policy = cttimeout_nla_policy },
541 	[IPCTNL_MSG_TIMEOUT_GET]	= { .call = cttimeout_get_timeout,
542 					    .attr_count = CTA_TIMEOUT_MAX,
543 					    .policy = cttimeout_nla_policy },
544 	[IPCTNL_MSG_TIMEOUT_DELETE]	= { .call = cttimeout_del_timeout,
545 					    .attr_count = CTA_TIMEOUT_MAX,
546 					    .policy = cttimeout_nla_policy },
547 	[IPCTNL_MSG_TIMEOUT_DEFAULT_SET]= { .call = cttimeout_default_set,
548 					    .attr_count = CTA_TIMEOUT_MAX,
549 					    .policy = cttimeout_nla_policy },
550 	[IPCTNL_MSG_TIMEOUT_DEFAULT_GET]= { .call = cttimeout_default_get,
551 					    .attr_count = CTA_TIMEOUT_MAX,
552 					    .policy = cttimeout_nla_policy },
553 };
554 
555 static const struct nfnetlink_subsystem cttimeout_subsys = {
556 	.name				= "conntrack_timeout",
557 	.subsys_id			= NFNL_SUBSYS_CTNETLINK_TIMEOUT,
558 	.cb_count			= IPCTNL_MSG_TIMEOUT_MAX,
559 	.cb				= cttimeout_cb,
560 };
561 
562 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_TIMEOUT);
563 
cttimeout_net_init(struct net * net)564 static int __net_init cttimeout_net_init(struct net *net)
565 {
566 	INIT_LIST_HEAD(&net->nfct_timeout_list);
567 
568 	return 0;
569 }
570 
cttimeout_net_exit(struct net * net)571 static void __net_exit cttimeout_net_exit(struct net *net)
572 {
573 	struct ctnl_timeout *cur, *tmp;
574 
575 	nf_ct_unconfirmed_destroy(net);
576 	nf_ct_untimeout(net, NULL);
577 
578 	list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list, head) {
579 		list_del_rcu(&cur->head);
580 
581 		if (refcount_dec_and_test(&cur->refcnt))
582 			kfree_rcu(cur, rcu_head);
583 	}
584 }
585 
586 static struct pernet_operations cttimeout_ops = {
587 	.init	= cttimeout_net_init,
588 	.exit	= cttimeout_net_exit,
589 };
590 
cttimeout_init(void)591 static int __init cttimeout_init(void)
592 {
593 	int ret;
594 
595 	ret = register_pernet_subsys(&cttimeout_ops);
596 	if (ret < 0)
597 		return ret;
598 
599 	ret = nfnetlink_subsys_register(&cttimeout_subsys);
600 	if (ret < 0) {
601 		pr_err("cttimeout_init: cannot register cttimeout with "
602 			"nfnetlink.\n");
603 		goto err_out;
604 	}
605 	RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, ctnl_timeout_find_get);
606 	RCU_INIT_POINTER(nf_ct_timeout_put_hook, ctnl_timeout_put);
607 	return 0;
608 
609 err_out:
610 	unregister_pernet_subsys(&cttimeout_ops);
611 	return ret;
612 }
613 
cttimeout_exit(void)614 static void __exit cttimeout_exit(void)
615 {
616 	nfnetlink_subsys_unregister(&cttimeout_subsys);
617 
618 	unregister_pernet_subsys(&cttimeout_ops);
619 	RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
620 	RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
621 	synchronize_rcu();
622 }
623 
624 module_init(cttimeout_init);
625 module_exit(cttimeout_exit);
626