Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
0004  * (C) 2012 by Vyatta Inc. <http://www.vyatta.com>
0005  */
0006 #include <linux/init.h>
0007 #include <linux/module.h>
0008 #include <linux/kernel.h>
0009 #include <linux/rculist.h>
0010 #include <linux/rculist_nulls.h>
0011 #include <linux/types.h>
0012 #include <linux/timer.h>
0013 #include <linux/security.h>
0014 #include <linux/skbuff.h>
0015 #include <linux/errno.h>
0016 #include <linux/netlink.h>
0017 #include <linux/spinlock.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/slab.h>
0020 
0021 #include <linux/netfilter.h>
0022 #include <net/netlink.h>
0023 #include <net/netns/generic.h>
0024 #include <net/sock.h>
0025 #include <net/netfilter/nf_conntrack.h>
0026 #include <net/netfilter/nf_conntrack_core.h>
0027 #include <net/netfilter/nf_conntrack_l4proto.h>
0028 #include <net/netfilter/nf_conntrack_tuple.h>
0029 #include <net/netfilter/nf_conntrack_timeout.h>
0030 
0031 #include <linux/netfilter/nfnetlink.h>
0032 #include <linux/netfilter/nfnetlink_cttimeout.h>
0033 
0034 static unsigned int nfct_timeout_id __read_mostly;
0035 
0036 struct ctnl_timeout {
0037     struct list_head    head;
0038     struct list_head    free_head;
0039     struct rcu_head     rcu_head;
0040     refcount_t      refcnt;
0041     char            name[CTNL_TIMEOUT_NAME_MAX];
0042 
0043     /* must be at the end */
0044     struct nf_ct_timeout    timeout;
0045 };
0046 
0047 struct nfct_timeout_pernet {
0048     struct list_head    nfct_timeout_list;
0049     struct list_head    nfct_timeout_freelist;
0050 };
0051 
0052 MODULE_LICENSE("GPL");
0053 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
0054 MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tuning");
0055 
0056 static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
0057     [CTA_TIMEOUT_NAME]  = { .type = NLA_NUL_STRING,
0058                     .len  = CTNL_TIMEOUT_NAME_MAX - 1},
0059     [CTA_TIMEOUT_L3PROTO]   = { .type = NLA_U16 },
0060     [CTA_TIMEOUT_L4PROTO]   = { .type = NLA_U8 },
0061     [CTA_TIMEOUT_DATA]  = { .type = NLA_NESTED },
0062 };
0063 
0064 static struct nfct_timeout_pernet *nfct_timeout_pernet(struct net *net)
0065 {
0066     return net_generic(net, nfct_timeout_id);
0067 }
0068 
0069 static int
0070 ctnl_timeout_parse_policy(void *timeout,
0071               const struct nf_conntrack_l4proto *l4proto,
0072               struct net *net, const struct nlattr *attr)
0073 {
0074     struct nlattr **tb;
0075     int ret = 0;
0076 
0077     tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb),
0078              GFP_KERNEL);
0079 
0080     if (!tb)
0081         return -ENOMEM;
0082 
0083     ret = nla_parse_nested_deprecated(tb,
0084                       l4proto->ctnl_timeout.nlattr_max,
0085                       attr,
0086                       l4proto->ctnl_timeout.nla_policy,
0087                       NULL);
0088     if (ret < 0)
0089         goto err;
0090 
0091     ret = l4proto->ctnl_timeout.nlattr_to_obj(tb, net, timeout);
0092 
0093 err:
0094     kfree(tb);
0095     return ret;
0096 }
0097 
0098 static int cttimeout_new_timeout(struct sk_buff *skb,
0099                  const struct nfnl_info *info,
0100                  const struct nlattr * const cda[])
0101 {
0102     struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(info->net);
0103     __u16 l3num;
0104     __u8 l4num;
0105     const struct nf_conntrack_l4proto *l4proto;
0106     struct ctnl_timeout *timeout, *matching = NULL;
0107     char *name;
0108     int ret;
0109 
0110     if (!cda[CTA_TIMEOUT_NAME] ||
0111         !cda[CTA_TIMEOUT_L3PROTO] ||
0112         !cda[CTA_TIMEOUT_L4PROTO] ||
0113         !cda[CTA_TIMEOUT_DATA])
0114         return -EINVAL;
0115 
0116     name = nla_data(cda[CTA_TIMEOUT_NAME]);
0117     l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
0118     l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
0119 
0120     list_for_each_entry(timeout, &pernet->nfct_timeout_list, head) {
0121         if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
0122             continue;
0123 
0124         if (info->nlh->nlmsg_flags & NLM_F_EXCL)
0125             return -EEXIST;
0126 
0127         matching = timeout;
0128         break;
0129     }
0130 
0131     if (matching) {
0132         if (info->nlh->nlmsg_flags & NLM_F_REPLACE) {
0133             /* You cannot replace one timeout policy by another of
0134              * different kind, sorry.
0135              */
0136             if (matching->timeout.l3num != l3num ||
0137                 matching->timeout.l4proto->l4proto != l4num)
0138                 return -EINVAL;
0139 
0140             return ctnl_timeout_parse_policy(&matching->timeout.data,
0141                              matching->timeout.l4proto,
0142                              info->net,
0143                              cda[CTA_TIMEOUT_DATA]);
0144         }
0145 
0146         return -EBUSY;
0147     }
0148 
0149     l4proto = nf_ct_l4proto_find(l4num);
0150 
0151     /* This protocol is not supportted, skip. */
0152     if (l4proto->l4proto != l4num) {
0153         ret = -EOPNOTSUPP;
0154         goto err_proto_put;
0155     }
0156 
0157     timeout = kzalloc(sizeof(struct ctnl_timeout) +
0158               l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
0159     if (timeout == NULL) {
0160         ret = -ENOMEM;
0161         goto err_proto_put;
0162     }
0163 
0164     ret = ctnl_timeout_parse_policy(&timeout->timeout.data, l4proto,
0165                     info->net, cda[CTA_TIMEOUT_DATA]);
0166     if (ret < 0)
0167         goto err;
0168 
0169     strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
0170     timeout->timeout.l3num = l3num;
0171     timeout->timeout.l4proto = l4proto;
0172     refcount_set(&timeout->refcnt, 1);
0173     __module_get(THIS_MODULE);
0174     list_add_tail_rcu(&timeout->head, &pernet->nfct_timeout_list);
0175 
0176     return 0;
0177 err:
0178     kfree(timeout);
0179 err_proto_put:
0180     return ret;
0181 }
0182 
0183 static int
0184 ctnl_timeout_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
0185                int event, struct ctnl_timeout *timeout)
0186 {
0187     struct nlmsghdr *nlh;
0188     unsigned int flags = portid ? NLM_F_MULTI : 0;
0189     const struct nf_conntrack_l4proto *l4proto = timeout->timeout.l4proto;
0190     struct nlattr *nest_parms;
0191     int ret;
0192 
0193     event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event);
0194     nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
0195                NFNETLINK_V0, 0);
0196     if (!nlh)
0197         goto nlmsg_failure;
0198 
0199     if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) ||
0200         nla_put_be16(skb, CTA_TIMEOUT_L3PROTO,
0201              htons(timeout->timeout.l3num)) ||
0202         nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto) ||
0203         nla_put_be32(skb, CTA_TIMEOUT_USE,
0204              htonl(refcount_read(&timeout->refcnt))))
0205         goto nla_put_failure;
0206 
0207     nest_parms = nla_nest_start(skb, CTA_TIMEOUT_DATA);
0208     if (!nest_parms)
0209         goto nla_put_failure;
0210 
0211     ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->timeout.data);
0212     if (ret < 0)
0213         goto nla_put_failure;
0214 
0215     nla_nest_end(skb, nest_parms);
0216 
0217     nlmsg_end(skb, nlh);
0218     return skb->len;
0219 
0220 nlmsg_failure:
0221 nla_put_failure:
0222     nlmsg_cancel(skb, nlh);
0223     return -1;
0224 }
0225 
0226 static int
0227 ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb)
0228 {
0229     struct nfct_timeout_pernet *pernet;
0230     struct net *net = sock_net(skb->sk);
0231     struct ctnl_timeout *cur, *last;
0232 
0233     if (cb->args[2])
0234         return 0;
0235 
0236     last = (struct ctnl_timeout *)cb->args[1];
0237     if (cb->args[1])
0238         cb->args[1] = 0;
0239 
0240     rcu_read_lock();
0241     pernet = nfct_timeout_pernet(net);
0242     list_for_each_entry_rcu(cur, &pernet->nfct_timeout_list, head) {
0243         if (last) {
0244             if (cur != last)
0245                 continue;
0246 
0247             last = NULL;
0248         }
0249         if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid,
0250                        cb->nlh->nlmsg_seq,
0251                        NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
0252                        IPCTNL_MSG_TIMEOUT_NEW, cur) < 0) {
0253             cb->args[1] = (unsigned long)cur;
0254             break;
0255         }
0256     }
0257     if (!cb->args[1])
0258         cb->args[2] = 1;
0259     rcu_read_unlock();
0260     return skb->len;
0261 }
0262 
0263 static int cttimeout_get_timeout(struct sk_buff *skb,
0264                  const struct nfnl_info *info,
0265                  const struct nlattr * const cda[])
0266 {
0267     struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(info->net);
0268     int ret = -ENOENT;
0269     char *name;
0270     struct ctnl_timeout *cur;
0271 
0272     if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
0273         struct netlink_dump_control c = {
0274             .dump = ctnl_timeout_dump,
0275         };
0276         return netlink_dump_start(info->sk, skb, info->nlh, &c);
0277     }
0278 
0279     if (!cda[CTA_TIMEOUT_NAME])
0280         return -EINVAL;
0281     name = nla_data(cda[CTA_TIMEOUT_NAME]);
0282 
0283     list_for_each_entry(cur, &pernet->nfct_timeout_list, head) {
0284         struct sk_buff *skb2;
0285 
0286         if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
0287             continue;
0288 
0289         skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
0290         if (skb2 == NULL) {
0291             ret = -ENOMEM;
0292             break;
0293         }
0294 
0295         ret = ctnl_timeout_fill_info(skb2, NETLINK_CB(skb).portid,
0296                          info->nlh->nlmsg_seq,
0297                          NFNL_MSG_TYPE(info->nlh->nlmsg_type),
0298                          IPCTNL_MSG_TIMEOUT_NEW, cur);
0299         if (ret <= 0) {
0300             kfree_skb(skb2);
0301             break;
0302         }
0303 
0304         ret = nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
0305         break;
0306     }
0307 
0308     return ret;
0309 }
0310 
0311 /* try to delete object, fail if it is still in use. */
0312 static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout)
0313 {
0314     int ret = 0;
0315 
0316     /* We want to avoid races with ctnl_timeout_put. So only when the
0317      * current refcnt is 1, we decrease it to 0.
0318      */
0319     if (refcount_dec_if_one(&timeout->refcnt)) {
0320         /* We are protected by nfnl mutex. */
0321         list_del_rcu(&timeout->head);
0322         nf_ct_untimeout(net, &timeout->timeout);
0323         kfree_rcu(timeout, rcu_head);
0324     } else {
0325         ret = -EBUSY;
0326     }
0327     return ret;
0328 }
0329 
0330 static int cttimeout_del_timeout(struct sk_buff *skb,
0331                  const struct nfnl_info *info,
0332                  const struct nlattr * const cda[])
0333 {
0334     struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(info->net);
0335     struct ctnl_timeout *cur, *tmp;
0336     int ret = -ENOENT;
0337     char *name;
0338 
0339     if (!cda[CTA_TIMEOUT_NAME]) {
0340         list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_list,
0341                      head)
0342             ctnl_timeout_try_del(info->net, cur);
0343 
0344         return 0;
0345     }
0346     name = nla_data(cda[CTA_TIMEOUT_NAME]);
0347 
0348     list_for_each_entry(cur, &pernet->nfct_timeout_list, head) {
0349         if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
0350             continue;
0351 
0352         ret = ctnl_timeout_try_del(info->net, cur);
0353         if (ret < 0)
0354             return ret;
0355 
0356         break;
0357     }
0358     return ret;
0359 }
0360 
0361 static int cttimeout_default_set(struct sk_buff *skb,
0362                  const struct nfnl_info *info,
0363                  const struct nlattr * const cda[])
0364 {
0365     const struct nf_conntrack_l4proto *l4proto;
0366     __u8 l4num;
0367     int ret;
0368 
0369     if (!cda[CTA_TIMEOUT_L3PROTO] ||
0370         !cda[CTA_TIMEOUT_L4PROTO] ||
0371         !cda[CTA_TIMEOUT_DATA])
0372         return -EINVAL;
0373 
0374     l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
0375     l4proto = nf_ct_l4proto_find(l4num);
0376 
0377     /* This protocol is not supported, skip. */
0378     if (l4proto->l4proto != l4num) {
0379         ret = -EOPNOTSUPP;
0380         goto err;
0381     }
0382 
0383     ret = ctnl_timeout_parse_policy(NULL, l4proto, info->net,
0384                     cda[CTA_TIMEOUT_DATA]);
0385     if (ret < 0)
0386         goto err;
0387 
0388     return 0;
0389 err:
0390     return ret;
0391 }
0392 
0393 static int
0394 cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
0395                 u32 seq, u32 type, int event, u16 l3num,
0396                 const struct nf_conntrack_l4proto *l4proto,
0397                 const unsigned int *timeouts)
0398 {
0399     struct nlmsghdr *nlh;
0400     unsigned int flags = portid ? NLM_F_MULTI : 0;
0401     struct nlattr *nest_parms;
0402     int ret;
0403 
0404     event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event);
0405     nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
0406                NFNETLINK_V0, 0);
0407     if (!nlh)
0408         goto nlmsg_failure;
0409 
0410     if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l3num)) ||
0411         nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto))
0412         goto nla_put_failure;
0413 
0414     nest_parms = nla_nest_start(skb, CTA_TIMEOUT_DATA);
0415     if (!nest_parms)
0416         goto nla_put_failure;
0417 
0418     ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
0419     if (ret < 0)
0420         goto nla_put_failure;
0421 
0422     nla_nest_end(skb, nest_parms);
0423 
0424     nlmsg_end(skb, nlh);
0425     return skb->len;
0426 
0427 nlmsg_failure:
0428 nla_put_failure:
0429     nlmsg_cancel(skb, nlh);
0430     return -1;
0431 }
0432 
0433 static int cttimeout_default_get(struct sk_buff *skb,
0434                  const struct nfnl_info *info,
0435                  const struct nlattr * const cda[])
0436 {
0437     const struct nf_conntrack_l4proto *l4proto;
0438     unsigned int *timeouts = NULL;
0439     struct sk_buff *skb2;
0440     __u16 l3num;
0441     __u8 l4num;
0442     int ret;
0443 
0444     if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO])
0445         return -EINVAL;
0446 
0447     l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
0448     l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
0449     l4proto = nf_ct_l4proto_find(l4num);
0450 
0451     if (l4proto->l4proto != l4num)
0452         return -EOPNOTSUPP;
0453 
0454     switch (l4proto->l4proto) {
0455     case IPPROTO_ICMP:
0456         timeouts = &nf_icmp_pernet(info->net)->timeout;
0457         break;
0458     case IPPROTO_TCP:
0459         timeouts = nf_tcp_pernet(info->net)->timeouts;
0460         break;
0461     case IPPROTO_UDP:
0462     case IPPROTO_UDPLITE:
0463         timeouts = nf_udp_pernet(info->net)->timeouts;
0464         break;
0465     case IPPROTO_DCCP:
0466 #ifdef CONFIG_NF_CT_PROTO_DCCP
0467         timeouts = nf_dccp_pernet(info->net)->dccp_timeout;
0468 #endif
0469         break;
0470     case IPPROTO_ICMPV6:
0471         timeouts = &nf_icmpv6_pernet(info->net)->timeout;
0472         break;
0473     case IPPROTO_SCTP:
0474 #ifdef CONFIG_NF_CT_PROTO_SCTP
0475         timeouts = nf_sctp_pernet(info->net)->timeouts;
0476 #endif
0477         break;
0478     case IPPROTO_GRE:
0479 #ifdef CONFIG_NF_CT_PROTO_GRE
0480         timeouts = nf_gre_pernet(info->net)->timeouts;
0481 #endif
0482         break;
0483     case 255:
0484         timeouts = &nf_generic_pernet(info->net)->timeout;
0485         break;
0486     default:
0487         WARN_ONCE(1, "Missing timeouts for proto %d", l4proto->l4proto);
0488         break;
0489     }
0490 
0491     if (!timeouts)
0492         return -EOPNOTSUPP;
0493 
0494     skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
0495     if (!skb2)
0496         return -ENOMEM;
0497 
0498     ret = cttimeout_default_fill_info(info->net, skb2,
0499                       NETLINK_CB(skb).portid,
0500                       info->nlh->nlmsg_seq,
0501                       NFNL_MSG_TYPE(info->nlh->nlmsg_type),
0502                       IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
0503                       l3num, l4proto, timeouts);
0504     if (ret <= 0) {
0505         kfree_skb(skb2);
0506         return -ENOMEM;
0507     }
0508 
0509     return nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
0510 }
0511 
0512 static struct nf_ct_timeout *ctnl_timeout_find_get(struct net *net,
0513                            const char *name)
0514 {
0515     struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(net);
0516     struct ctnl_timeout *timeout, *matching = NULL;
0517 
0518     list_for_each_entry_rcu(timeout, &pernet->nfct_timeout_list, head) {
0519         if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
0520             continue;
0521 
0522         if (!refcount_inc_not_zero(&timeout->refcnt))
0523             goto err;
0524         matching = timeout;
0525         break;
0526     }
0527 err:
0528     return matching ? &matching->timeout : NULL;
0529 }
0530 
0531 static void ctnl_timeout_put(struct nf_ct_timeout *t)
0532 {
0533     struct ctnl_timeout *timeout =
0534         container_of(t, struct ctnl_timeout, timeout);
0535 
0536     if (refcount_dec_and_test(&timeout->refcnt)) {
0537         kfree_rcu(timeout, rcu_head);
0538         module_put(THIS_MODULE);
0539     }
0540 }
0541 
0542 static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {
0543     [IPCTNL_MSG_TIMEOUT_NEW] = {
0544         .call       = cttimeout_new_timeout,
0545         .type       = NFNL_CB_MUTEX,
0546         .attr_count = CTA_TIMEOUT_MAX,
0547         .policy     = cttimeout_nla_policy
0548     },
0549     [IPCTNL_MSG_TIMEOUT_GET] = {
0550         .call       = cttimeout_get_timeout,
0551         .type       = NFNL_CB_MUTEX,
0552         .attr_count = CTA_TIMEOUT_MAX,
0553         .policy     = cttimeout_nla_policy
0554     },
0555     [IPCTNL_MSG_TIMEOUT_DELETE] = {
0556         .call       = cttimeout_del_timeout,
0557         .type       = NFNL_CB_MUTEX,
0558         .attr_count = CTA_TIMEOUT_MAX,
0559         .policy     = cttimeout_nla_policy
0560     },
0561     [IPCTNL_MSG_TIMEOUT_DEFAULT_SET] = {
0562         .call       = cttimeout_default_set,
0563         .type       = NFNL_CB_MUTEX,
0564         .attr_count = CTA_TIMEOUT_MAX,
0565         .policy     = cttimeout_nla_policy
0566     },
0567     [IPCTNL_MSG_TIMEOUT_DEFAULT_GET] = {
0568         .call       = cttimeout_default_get,
0569         .type       = NFNL_CB_MUTEX,
0570         .attr_count = CTA_TIMEOUT_MAX,
0571         .policy     = cttimeout_nla_policy
0572     },
0573 };
0574 
0575 static const struct nfnetlink_subsystem cttimeout_subsys = {
0576     .name               = "conntrack_timeout",
0577     .subsys_id          = NFNL_SUBSYS_CTNETLINK_TIMEOUT,
0578     .cb_count           = IPCTNL_MSG_TIMEOUT_MAX,
0579     .cb             = cttimeout_cb,
0580 };
0581 
0582 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_TIMEOUT);
0583 
0584 static int __net_init cttimeout_net_init(struct net *net)
0585 {
0586     struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(net);
0587 
0588     INIT_LIST_HEAD(&pernet->nfct_timeout_list);
0589     INIT_LIST_HEAD(&pernet->nfct_timeout_freelist);
0590 
0591     return 0;
0592 }
0593 
0594 static void __net_exit cttimeout_net_pre_exit(struct net *net)
0595 {
0596     struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(net);
0597     struct ctnl_timeout *cur, *tmp;
0598 
0599     list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_list, head) {
0600         list_del_rcu(&cur->head);
0601         list_add(&cur->free_head, &pernet->nfct_timeout_freelist);
0602     }
0603 
0604     /* core calls synchronize_rcu() after this */
0605 }
0606 
0607 static void __net_exit cttimeout_net_exit(struct net *net)
0608 {
0609     struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(net);
0610     struct ctnl_timeout *cur, *tmp;
0611 
0612     if (list_empty(&pernet->nfct_timeout_freelist))
0613         return;
0614 
0615     nf_ct_untimeout(net, NULL);
0616 
0617     list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_freelist, free_head) {
0618         list_del(&cur->free_head);
0619 
0620         if (refcount_dec_and_test(&cur->refcnt))
0621             kfree_rcu(cur, rcu_head);
0622     }
0623 }
0624 
0625 static struct pernet_operations cttimeout_ops = {
0626     .init   = cttimeout_net_init,
0627     .pre_exit = cttimeout_net_pre_exit,
0628     .exit   = cttimeout_net_exit,
0629     .id     = &nfct_timeout_id,
0630     .size   = sizeof(struct nfct_timeout_pernet),
0631 };
0632 
0633 static const struct nf_ct_timeout_hooks hooks = {
0634     .timeout_find_get = ctnl_timeout_find_get,
0635     .timeout_put = ctnl_timeout_put,
0636 };
0637 
0638 static int __init cttimeout_init(void)
0639 {
0640     int ret;
0641 
0642     ret = register_pernet_subsys(&cttimeout_ops);
0643     if (ret < 0)
0644         return ret;
0645 
0646     ret = nfnetlink_subsys_register(&cttimeout_subsys);
0647     if (ret < 0) {
0648         pr_err("cttimeout_init: cannot register cttimeout with "
0649             "nfnetlink.\n");
0650         goto err_out;
0651     }
0652     RCU_INIT_POINTER(nf_ct_timeout_hook, &hooks);
0653     return 0;
0654 
0655 err_out:
0656     unregister_pernet_subsys(&cttimeout_ops);
0657     return ret;
0658 }
0659 
0660 static int untimeout(struct nf_conn *ct, void *timeout)
0661 {
0662     struct nf_conn_timeout *timeout_ext = nf_ct_timeout_find(ct);
0663 
0664     if (timeout_ext)
0665         RCU_INIT_POINTER(timeout_ext->timeout, NULL);
0666 
0667     return 0;
0668 }
0669 
0670 static void __exit cttimeout_exit(void)
0671 {
0672     nfnetlink_subsys_unregister(&cttimeout_subsys);
0673 
0674     unregister_pernet_subsys(&cttimeout_ops);
0675     RCU_INIT_POINTER(nf_ct_timeout_hook, NULL);
0676 
0677     nf_ct_iterate_destroy(untimeout, NULL);
0678 }
0679 
0680 module_init(cttimeout_init);
0681 module_exit(cttimeout_exit);