diff options
Diffstat (limited to 'net/ipv6/reassembly.c')
-rw-r--r-- | net/ipv6/reassembly.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index da5bd0ed83df..45efc39753e2 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -208,18 +208,17 @@ static void ip6_frag_expire(unsigned long data) | |||
208 | fq_kill(fq); | 208 | fq_kill(fq); |
209 | 209 | ||
210 | net = container_of(fq->q.net, struct net, ipv6.frags); | 210 | net = container_of(fq->q.net, struct net, ipv6.frags); |
211 | dev = dev_get_by_index(net, fq->iif); | 211 | rcu_read_lock(); |
212 | dev = dev_get_by_index_rcu(net, fq->iif); | ||
212 | if (!dev) | 213 | if (!dev) |
213 | goto out; | 214 | goto out_rcu_unlock; |
214 | 215 | ||
215 | rcu_read_lock(); | ||
216 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); | 216 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); |
217 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); | 217 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); |
218 | rcu_read_unlock(); | ||
219 | 218 | ||
220 | /* Don't send error if the first segment did not arrive. */ | 219 | /* Don't send error if the first segment did not arrive. */ |
221 | if (!(fq->q.last_in & INET_FRAG_FIRST_IN) || !fq->q.fragments) | 220 | if (!(fq->q.last_in & INET_FRAG_FIRST_IN) || !fq->q.fragments) |
222 | goto out; | 221 | goto out_rcu_unlock; |
223 | 222 | ||
224 | /* | 223 | /* |
225 | But use as source device on which LAST ARRIVED | 224 | But use as source device on which LAST ARRIVED |
@@ -228,9 +227,9 @@ static void ip6_frag_expire(unsigned long data) | |||
228 | */ | 227 | */ |
229 | fq->q.fragments->dev = dev; | 228 | fq->q.fragments->dev = dev; |
230 | icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); | 229 | icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); |
230 | out_rcu_unlock: | ||
231 | rcu_read_unlock(); | ||
231 | out: | 232 | out: |
232 | if (dev) | ||
233 | dev_put(dev); | ||
234 | spin_unlock(&fq->q.lock); | 233 | spin_unlock(&fq->q.lock); |
235 | fq_put(fq); | 234 | fq_put(fq); |
236 | } | 235 | } |
@@ -682,7 +681,7 @@ static int ip6_frags_ns_sysctl_register(struct net *net) | |||
682 | struct ctl_table_header *hdr; | 681 | struct ctl_table_header *hdr; |
683 | 682 | ||
684 | table = ip6_frags_ns_ctl_table; | 683 | table = ip6_frags_ns_ctl_table; |
685 | if (net != &init_net) { | 684 | if (!net_eq(net, &init_net)) { |
686 | table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL); | 685 | table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL); |
687 | if (table == NULL) | 686 | if (table == NULL) |
688 | goto err_alloc; | 687 | goto err_alloc; |
@@ -700,7 +699,7 @@ static int ip6_frags_ns_sysctl_register(struct net *net) | |||
700 | return 0; | 699 | return 0; |
701 | 700 | ||
702 | err_reg: | 701 | err_reg: |
703 | if (net != &init_net) | 702 | if (!net_eq(net, &init_net)) |
704 | kfree(table); | 703 | kfree(table); |
705 | err_alloc: | 704 | err_alloc: |
706 | return -ENOMEM; | 705 | return -ENOMEM; |