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