root/net/netfilter/nfnetlink_cttimeout.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ctnl_timeout_parse_policy
  2. cttimeout_new_timeout
  3. ctnl_timeout_fill_info
  4. ctnl_timeout_dump
  5. cttimeout_get_timeout
  6. ctnl_timeout_try_del
  7. cttimeout_del_timeout
  8. cttimeout_default_set
  9. cttimeout_default_fill_info
  10. cttimeout_default_get
  11. ctnl_timeout_find_get
  12. ctnl_timeout_put
  13. cttimeout_net_init
  14. cttimeout_net_exit
  15. cttimeout_init
  16. cttimeout_exit

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

/* [<][>][^][v][top][bottom][index][help] */