whiterose

linux unikernel
Log | Files | Refs | README | LICENSE | git clone https://git.ne02ptzero.me/git/whiterose

nfnetlink_cttimeout.c (15865B)


      1 /*
      2  * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
      3  * (C) 2012 by Vyatta Inc. <http://www.vyatta.com>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License version 2 as
      7  * published by the Free Software Foundation (or any later at your option).
      8  */
      9 #include <linux/init.h>
     10 #include <linux/module.h>
     11 #include <linux/kernel.h>
     12 #include <linux/rculist.h>
     13 #include <linux/rculist_nulls.h>
     14 #include <linux/types.h>
     15 #include <linux/timer.h>
     16 #include <linux/security.h>
     17 #include <linux/skbuff.h>
     18 #include <linux/errno.h>
     19 #include <linux/netlink.h>
     20 #include <linux/spinlock.h>
     21 #include <linux/interrupt.h>
     22 #include <linux/slab.h>
     23 
     24 #include <linux/netfilter.h>
     25 #include <net/netlink.h>
     26 #include <net/sock.h>
     27 #include <net/netfilter/nf_conntrack.h>
     28 #include <net/netfilter/nf_conntrack_core.h>
     29 #include <net/netfilter/nf_conntrack_l4proto.h>
     30 #include <net/netfilter/nf_conntrack_tuple.h>
     31 #include <net/netfilter/nf_conntrack_timeout.h>
     32 
     33 #include <linux/netfilter/nfnetlink.h>
     34 #include <linux/netfilter/nfnetlink_cttimeout.h>
     35 
     36 MODULE_LICENSE("GPL");
     37 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
     38 MODULE_DESCRIPTION("cttimeout: Extended Netfilter Connection Tracking timeout tuning");
     39 
     40 static const struct nla_policy cttimeout_nla_policy[CTA_TIMEOUT_MAX+1] = {
     41 	[CTA_TIMEOUT_NAME]	= { .type = NLA_NUL_STRING,
     42 				    .len  = CTNL_TIMEOUT_NAME_MAX - 1},
     43 	[CTA_TIMEOUT_L3PROTO]	= { .type = NLA_U16 },
     44 	[CTA_TIMEOUT_L4PROTO]	= { .type = NLA_U8 },
     45 	[CTA_TIMEOUT_DATA]	= { .type = NLA_NESTED },
     46 };
     47 
     48 static int
     49 ctnl_timeout_parse_policy(void *timeout,
     50 			  const struct nf_conntrack_l4proto *l4proto,
     51 			  struct net *net, const struct nlattr *attr)
     52 {
     53 	struct nlattr **tb;
     54 	int ret = 0;
     55 
     56 	tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb),
     57 		     GFP_KERNEL);
     58 
     59 	if (!tb)
     60 		return -ENOMEM;
     61 
     62 	ret = nla_parse_nested(tb, l4proto->ctnl_timeout.nlattr_max, attr,
     63 			       l4proto->ctnl_timeout.nla_policy, 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 | NLA_F_NESTED);
    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 | NLA_F_NESTED);
    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);