diff options
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/reassembly.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 15e1456b3f18..b67a45fb93e9 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
| @@ -203,7 +203,7 @@ static inline void frag_free_queue(struct frag_queue *fq, int *work) | |||
| 203 | 203 | ||
| 204 | static inline struct frag_queue *frag_alloc_queue(void) | 204 | static inline struct frag_queue *frag_alloc_queue(void) |
| 205 | { | 205 | { |
| 206 | struct frag_queue *fq = kmalloc(sizeof(struct frag_queue), GFP_ATOMIC); | 206 | struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC); |
| 207 | 207 | ||
| 208 | if(!fq) | 208 | if(!fq) |
| 209 | return NULL; | 209 | return NULL; |
| @@ -288,6 +288,7 @@ static void ip6_evictor(void) | |||
| 288 | static void ip6_frag_expire(unsigned long data) | 288 | static void ip6_frag_expire(unsigned long data) |
| 289 | { | 289 | { |
| 290 | struct frag_queue *fq = (struct frag_queue *) data; | 290 | struct frag_queue *fq = (struct frag_queue *) data; |
| 291 | struct net_device *dev; | ||
| 291 | 292 | ||
| 292 | spin_lock(&fq->lock); | 293 | spin_lock(&fq->lock); |
| 293 | 294 | ||
| @@ -299,22 +300,22 @@ static void ip6_frag_expire(unsigned long data) | |||
| 299 | IP6_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT); | 300 | IP6_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT); |
| 300 | IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); | 301 | IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); |
| 301 | 302 | ||
| 302 | /* Send error only if the first segment arrived. */ | 303 | /* Don't send error if the first segment did not arrive. */ |
| 303 | if (fq->last_in&FIRST_IN && fq->fragments) { | 304 | if (!(fq->last_in&FIRST_IN) || !fq->fragments) |
| 304 | struct net_device *dev = dev_get_by_index(fq->iif); | 305 | goto out; |
| 305 | 306 | ||
| 306 | /* | 307 | dev = dev_get_by_index(fq->iif); |
| 307 | But use as source device on which LAST ARRIVED | 308 | if (!dev) |
| 308 | segment was received. And do not use fq->dev | 309 | goto out; |
| 309 | pointer directly, device might already disappeared. | 310 | |
| 310 | */ | 311 | /* |
| 311 | if (dev) { | 312 | But use as source device on which LAST ARRIVED |
| 312 | fq->fragments->dev = dev; | 313 | segment was received. And do not use fq->dev |
| 313 | icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, | 314 | pointer directly, device might already disappeared. |
| 314 | dev); | 315 | */ |
| 315 | dev_put(dev); | 316 | fq->fragments->dev = dev; |
| 316 | } | 317 | icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); |
| 317 | } | 318 | dev_put(dev); |
| 318 | out: | 319 | out: |
| 319 | spin_unlock(&fq->lock); | 320 | spin_unlock(&fq->lock); |
| 320 | fq_put(fq, NULL); | 321 | fq_put(fq, NULL); |
| @@ -368,8 +369,6 @@ ip6_frag_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr | |||
| 368 | if ((fq = frag_alloc_queue()) == NULL) | 369 | if ((fq = frag_alloc_queue()) == NULL) |
| 369 | goto oom; | 370 | goto oom; |
| 370 | 371 | ||
| 371 | memset(fq, 0, sizeof(struct frag_queue)); | ||
| 372 | |||
| 373 | fq->id = id; | 372 | fq->id = id; |
| 374 | ipv6_addr_copy(&fq->saddr, src); | 373 | ipv6_addr_copy(&fq->saddr, src); |
| 375 | ipv6_addr_copy(&fq->daddr, dst); | 374 | ipv6_addr_copy(&fq->daddr, dst); |
