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                ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
 291                                      MSG_DONTWAIT);
 292                if (ret > 0)
 293                        ret = 0;
 294
 295                /* this avoids a loop in nfnetlink. */
 296                return ret == -EAGAIN ? -ENOBUFS : ret;
 297        }
 298        return ret;
 299}
 300
 301/* try to delete object, fail if it is still in use. */
 302static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout)
 303{
 304        int ret = 0;
 305
 306        /* We want to avoid races with ctnl_timeout_put. So only when the
 307         * current refcnt is 1, we decrease it to 0.
 308         */
 309        if (refcount_dec_if_one(&timeout->refcnt)) {
 310                /* We are protected by nfnl mutex. */
 311                list_del_rcu(&timeout->head);
 312                nf_ct_untimeout(net, &timeout->timeout);
 313                kfree_rcu(timeout, rcu_head);
 314        } else {
 315                ret = -EBUSY;
 316        }
 317        return ret;
 318}
 319
 320static int cttimeout_del_timeout(struct sk_buff *skb,
 321                                 const struct nfnl_info *info,
 322                                 const struct nlattr * const cda[])
 323{
 324        struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(info->net);
 325        struct ctnl_timeout *cur, *tmp;
 326        int ret = -ENOENT;
 327        char *name;
 328
 329        if (!cda[CTA_TIMEOUT_NAME]) {
 330                list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_list,
 331                                         head)
 332                        ctnl_timeout_try_del(info->net, cur);
 333
 334                return 0;
 335        }
 336        name = nla_data(cda[CTA_TIMEOUT_NAME]);
 337
 338        list_for_each_entry(cur, &pernet->nfct_timeout_list, head) {
 339                if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
 340                        continue;
 341
 342                ret = ctnl_timeout_try_del(info->net, cur);
 343                if (ret < 0)
 344                        return ret;
 345
 346                break;
 347        }
 348        return ret;
 349}
 350
 351static int cttimeout_default_set(struct sk_buff *skb,
 352                                 const struct nfnl_info *info,
 353                                 const struct nlattr * const cda[])
 354{
 355        const struct nf_conntrack_l4proto *l4proto;
 356        __u8 l4num;
 357        int ret;
 358
 359        if (!cda[CTA_TIMEOUT_L3PROTO] ||
 360            !cda[CTA_TIMEOUT_L4PROTO] ||
 361            !cda[CTA_TIMEOUT_DATA])
 362                return -EINVAL;
 363
 364        l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
 365        l4proto = nf_ct_l4proto_find(l4num);
 366
 367        /* This protocol is not supported, skip. */
 368        if (l4proto->l4proto != l4num) {
 369                ret = -EOPNOTSUPP;
 370                goto err;
 371        }
 372
 373        ret = ctnl_timeout_parse_policy(NULL, l4proto, info->net,
 374                                        cda[CTA_TIMEOUT_DATA]);
 375        if (ret < 0)
 376                goto err;
 377
 378        return 0;
 379err:
 380        return ret;
 381}
 382
 383static int
 384cttimeout_default_fill_info(struct net *net, struct sk_buff *skb, u32 portid,
 385                            u32 seq, u32 type, int event, u16 l3num,
 386                            const struct nf_conntrack_l4proto *l4proto,
 387                            const unsigned int *timeouts)
 388{
 389        struct nlmsghdr *nlh;
 390        unsigned int flags = portid ? NLM_F_MULTI : 0;
 391        struct nlattr *nest_parms;
 392        int ret;
 393
 394        event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_TIMEOUT, event);
 395        nlh = nfnl_msg_put(skb, portid, seq, event, flags, AF_UNSPEC,
 396                           NFNETLINK_V0, 0);
 397        if (!nlh)
 398                goto nlmsg_failure;
 399
 400        if (nla_put_be16(skb, CTA_TIMEOUT_L3PROTO, htons(l3num)) ||
 401            nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto))
 402                goto nla_put_failure;
 403
 404        nest_parms = nla_nest_start(skb, CTA_TIMEOUT_DATA);
 405        if (!nest_parms)
 406                goto nla_put_failure;
 407
 408        ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, timeouts);
 409        if (ret < 0)
 410                goto nla_put_failure;
 411
 412        nla_nest_end(skb, nest_parms);
 413
 414        nlmsg_end(skb, nlh);
 415        return skb->len;
 416
 417nlmsg_failure:
 418nla_put_failure:
 419        nlmsg_cancel(skb, nlh);
 420        return -1;
 421}
 422
 423static int cttimeout_default_get(struct sk_buff *skb,
 424                                 const struct nfnl_info *info,
 425                                 const struct nlattr * const cda[])
 426{
 427        const struct nf_conntrack_l4proto *l4proto;
 428        unsigned int *timeouts = NULL;
 429        struct sk_buff *skb2;
 430        int ret, err;
 431        __u16 l3num;
 432        __u8 l4num;
 433
 434        if (!cda[CTA_TIMEOUT_L3PROTO] || !cda[CTA_TIMEOUT_L4PROTO])
 435                return -EINVAL;
 436
 437        l3num = ntohs(nla_get_be16(cda[CTA_TIMEOUT_L3PROTO]));
 438        l4num = nla_get_u8(cda[CTA_TIMEOUT_L4PROTO]);
 439        l4proto = nf_ct_l4proto_find(l4num);
 440
 441        err = -EOPNOTSUPP;
 442        if (l4proto->l4proto != l4num)
 443                goto err;
 444
 445        switch (l4proto->l4proto) {
 446        case IPPROTO_ICMP:
 447                timeouts = &nf_icmp_pernet(info->net)->timeout;
 448                break;
 449        case IPPROTO_TCP:
 450                timeouts = nf_tcp_pernet(info->net)->timeouts;
 451                break;
 452        case IPPROTO_UDP:
 453        case IPPROTO_UDPLITE:
 454                timeouts = nf_udp_pernet(info->net)->timeouts;
 455                break;
 456        case IPPROTO_DCCP:
 457#ifdef CONFIG_NF_CT_PROTO_DCCP
 458                timeouts = nf_dccp_pernet(info->net)->dccp_timeout;
 459#endif
 460                break;
 461        case IPPROTO_ICMPV6:
 462                timeouts = &nf_icmpv6_pernet(info->net)->timeout;
 463                break;
 464        case IPPROTO_SCTP:
 465#ifdef CONFIG_NF_CT_PROTO_SCTP
 466                timeouts = nf_sctp_pernet(info->net)->timeouts;
 467#endif
 468                break;
 469        case IPPROTO_GRE:
 470#ifdef CONFIG_NF_CT_PROTO_GRE
 471                timeouts = nf_gre_pernet(info->net)->timeouts;
 472#endif
 473                break;
 474        case 255:
 475                timeouts = &nf_generic_pernet(info->net)->timeout;
 476                break;
 477        default:
 478                WARN_ONCE(1, "Missing timeouts for proto %d", l4proto->l4proto);
 479                break;
 480        }
 481
 482        if (!timeouts)
 483                goto err;
 484
 485        skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 486        if (skb2 == NULL) {
 487                err = -ENOMEM;
 488                goto err;
 489        }
 490
 491        ret = cttimeout_default_fill_info(info->net, skb2,
 492                                          NETLINK_CB(skb).portid,
 493                                          info->nlh->nlmsg_seq,
 494                                          NFNL_MSG_TYPE(info->nlh->nlmsg_type),
 495                                          IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
 496                                          l3num, l4proto, timeouts);
 497        if (ret <= 0) {
 498                kfree_skb(skb2);
 499                err = -ENOMEM;
 500                goto err;
 501        }
 502        ret = netlink_unicast(info->sk, skb2, NETLINK_CB(skb).portid,
 503                              MSG_DONTWAIT);
 504        if (ret > 0)
 505                ret = 0;
 506
 507        /* this avoids a loop in nfnetlink. */
 508        return ret == -EAGAIN ? -ENOBUFS : ret;
 509err:
 510        return err;
 511}
 512
 513static struct nf_ct_timeout *ctnl_timeout_find_get(struct net *net,
 514                                                   const char *name)
 515{
 516        struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(net);
 517        struct ctnl_timeout *timeout, *matching = NULL;
 518
 519        list_for_each_entry_rcu(timeout, &pernet->nfct_timeout_list, head) {
 520                if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
 521                        continue;
 522
 523                if (!try_module_get(THIS_MODULE))
 524                        goto err;
 525
 526                if (!refcount_inc_not_zero(&timeout->refcnt)) {
 527                        module_put(THIS_MODULE);
 528                        goto err;
 529                }
 530                matching = timeout;
 531                break;
 532        }
 533err:
 534        return matching ? &matching->timeout : NULL;
 535}
 536
 537static void ctnl_timeout_put(struct nf_ct_timeout *t)
 538{
 539        struct ctnl_timeout *timeout =
 540                container_of(t, struct ctnl_timeout, timeout);
 541
 542        if (refcount_dec_and_test(&timeout->refcnt))
 543                kfree_rcu(timeout, rcu_head);
 544
 545        module_put(THIS_MODULE);
 546}
 547
 548static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {
 549        [IPCTNL_MSG_TIMEOUT_NEW] = {
 550                .call           = cttimeout_new_timeout,
 551                .type           = NFNL_CB_MUTEX,
 552                .attr_count     = CTA_TIMEOUT_MAX,
 553                .policy         = cttimeout_nla_policy
 554        },
 555        [IPCTNL_MSG_TIMEOUT_GET] = {
 556                .call           = cttimeout_get_timeout,
 557                .type           = NFNL_CB_MUTEX,
 558                .attr_count     = CTA_TIMEOUT_MAX,
 559                .policy         = cttimeout_nla_policy
 560        },
 561        [IPCTNL_MSG_TIMEOUT_DELETE] = {
 562                .call           = cttimeout_del_timeout,
 563                .type           = NFNL_CB_MUTEX,
 564                .attr_count     = CTA_TIMEOUT_MAX,
 565                .policy         = cttimeout_nla_policy
 566        },
 567        [IPCTNL_MSG_TIMEOUT_DEFAULT_SET] = {
 568                .call           = cttimeout_default_set,
 569                .type           = NFNL_CB_MUTEX,
 570                .attr_count     = CTA_TIMEOUT_MAX,
 571                .policy         = cttimeout_nla_policy
 572        },
 573        [IPCTNL_MSG_TIMEOUT_DEFAULT_GET] = {
 574                .call           = cttimeout_default_get,
 575                .type           = NFNL_CB_MUTEX,
 576                .attr_count     = CTA_TIMEOUT_MAX,
 577                .policy         = cttimeout_nla_policy
 578        },
 579};
 580
 581static const struct nfnetlink_subsystem cttimeout_subsys = {
 582        .name                           = "conntrack_timeout",
 583        .subsys_id                      = NFNL_SUBSYS_CTNETLINK_TIMEOUT,
 584        .cb_count                       = IPCTNL_MSG_TIMEOUT_MAX,
 585        .cb                             = cttimeout_cb,
 586};
 587
 588MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_TIMEOUT);
 589
 590static int __net_init cttimeout_net_init(struct net *net)
 591{
 592        struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(net);
 593
 594        INIT_LIST_HEAD(&pernet->nfct_timeout_list);
 595
 596        return 0;
 597}
 598
 599static void __net_exit cttimeout_net_exit(struct net *net)
 600{
 601        struct nfct_timeout_pernet *pernet = nfct_timeout_pernet(net);
 602        struct ctnl_timeout *cur, *tmp;
 603
 604        nf_ct_unconfirmed_destroy(net);
 605        nf_ct_untimeout(net, NULL);
 606
 607        list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_list, head) {
 608                list_del_rcu(&cur->head);
 609
 610                if (refcount_dec_and_test(&cur->refcnt))
 611                        kfree_rcu(cur, rcu_head);
 612        }
 613}
 614
 615static struct pernet_operations cttimeout_ops = {
 616        .init   = cttimeout_net_init,
 617        .exit   = cttimeout_net_exit,
 618        .id     = &nfct_timeout_id,
 619        .size   = sizeof(struct nfct_timeout_pernet),
 620};
 621
 622static int __init cttimeout_init(void)
 623{
 624        int ret;
 625
 626        ret = register_pernet_subsys(&cttimeout_ops);
 627        if (ret < 0)
 628                return ret;
 629
 630        ret = nfnetlink_subsys_register(&cttimeout_subsys);
 631        if (ret < 0) {
 632                pr_err("cttimeout_init: cannot register cttimeout with "
 633                        "nfnetlink.\n");
 634                goto err_out;
 635        }
 636        RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, ctnl_timeout_find_get);
 637        RCU_INIT_POINTER(nf_ct_timeout_put_hook, ctnl_timeout_put);
 638        return 0;
 639
 640err_out:
 641        unregister_pernet_subsys(&cttimeout_ops);
 642        return ret;
 643}
 644
 645static void __exit cttimeout_exit(void)
 646{
 647        nfnetlink_subsys_unregister(&cttimeout_subsys);
 648
 649        unregister_pernet_subsys(&cttimeout_ops);
 650        RCU_INIT_POINTER(nf_ct_timeout_find_get_hook, NULL);
 651        RCU_INIT_POINTER(nf_ct_timeout_put_hook, NULL);
 652        synchronize_rcu();
 653}
 654
 655module_init(cttimeout_init);
 656module_exit(cttimeout_exit);
 657