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