cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nfnetlink_cttimeout.c (16780B)


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