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