diff options
Diffstat (limited to 'net/ipv6/reassembly.c')
| -rw-r--r-- | net/ipv6/reassembly.c | 23 | 
1 files changed, 8 insertions, 15 deletions
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index da5bd0ed83d..4d98549a686 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -208,18 +208,17 @@ static void ip6_frag_expire(unsigned long data)  	fq_kill(fq);  	net = container_of(fq->q.net, struct net, ipv6.frags); -	dev = dev_get_by_index(net, fq->iif); +	rcu_read_lock(); +	dev = dev_get_by_index_rcu(net, fq->iif);  	if (!dev) -		goto out; +		goto out_rcu_unlock; -	rcu_read_lock();  	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);  	IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); -	rcu_read_unlock();  	/* Don't send error if the first segment did not arrive. */  	if (!(fq->q.last_in & INET_FRAG_FIRST_IN) || !fq->q.fragments) -		goto out; +		goto out_rcu_unlock;  	/*  	   But use as source device on which LAST ARRIVED @@ -228,9 +227,9 @@ static void ip6_frag_expire(unsigned long data)  	 */  	fq->q.fragments->dev = dev;  	icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); +out_rcu_unlock: +	rcu_read_unlock();  out: -	if (dev) -		dev_put(dev);  	spin_unlock(&fq->q.lock);  	fq_put(fq);  } @@ -636,7 +635,6 @@ static const struct inet6_protocol frag_protocol =  #ifdef CONFIG_SYSCTL  static struct ctl_table ip6_frags_ns_ctl_table[] = {  	{ -		.ctl_name	= NET_IPV6_IP6FRAG_HIGH_THRESH,  		.procname	= "ip6frag_high_thresh",  		.data		= &init_net.ipv6.frags.high_thresh,  		.maxlen		= sizeof(int), @@ -644,7 +642,6 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {  		.proc_handler	= proc_dointvec  	},  	{ -		.ctl_name	= NET_IPV6_IP6FRAG_LOW_THRESH,  		.procname	= "ip6frag_low_thresh",  		.data		= &init_net.ipv6.frags.low_thresh,  		.maxlen		= sizeof(int), @@ -652,26 +649,22 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {  		.proc_handler	= proc_dointvec  	},  	{ -		.ctl_name	= NET_IPV6_IP6FRAG_TIME,  		.procname	= "ip6frag_time",  		.data		= &init_net.ipv6.frags.timeout,  		.maxlen		= sizeof(int),  		.mode		= 0644,  		.proc_handler	= proc_dointvec_jiffies, -		.strategy	= sysctl_jiffies,  	},  	{ }  };  static struct ctl_table ip6_frags_ctl_table[] = {  	{ -		.ctl_name	= NET_IPV6_IP6FRAG_SECRET_INTERVAL,  		.procname	= "ip6frag_secret_interval",  		.data		= &ip6_frags.secret_interval,  		.maxlen		= sizeof(int),  		.mode		= 0644,  		.proc_handler	= proc_dointvec_jiffies, -		.strategy	= sysctl_jiffies  	},  	{ }  }; @@ -682,7 +675,7 @@ static int ip6_frags_ns_sysctl_register(struct net *net)  	struct ctl_table_header *hdr;  	table = ip6_frags_ns_ctl_table; -	if (net != &init_net) { +	if (!net_eq(net, &init_net)) {  		table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL);  		if (table == NULL)  			goto err_alloc; @@ -700,7 +693,7 @@ static int ip6_frags_ns_sysctl_register(struct net *net)  	return 0;  err_reg: -	if (net != &init_net) +	if (!net_eq(net, &init_net))  		kfree(table);  err_alloc:  	return -ENOMEM;  |