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