aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipip.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r--net/ipv4/ipip.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 76ab50b0d6ef..0c4556529228 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -341,7 +341,8 @@ out:
341 int code = skb->h.icmph->code; 341 int code = skb->h.icmph->code;
342 int rel_type = 0; 342 int rel_type = 0;
343 int rel_code = 0; 343 int rel_code = 0;
344 int rel_info = 0; 344 __be32 rel_info = 0;
345 __u32 n = 0;
345 struct sk_buff *skb2; 346 struct sk_buff *skb2;
346 struct flowi fl; 347 struct flowi fl;
347 struct rtable *rt; 348 struct rtable *rt;
@@ -354,14 +355,15 @@ out:
354 default: 355 default:
355 return 0; 356 return 0;
356 case ICMP_PARAMETERPROB: 357 case ICMP_PARAMETERPROB:
357 if (skb->h.icmph->un.gateway < hlen) 358 n = ntohl(skb->h.icmph->un.gateway) >> 24;
359 if (n < hlen)
358 return 0; 360 return 0;
359 361
360 /* So... This guy found something strange INSIDE encapsulated 362 /* So... This guy found something strange INSIDE encapsulated
361 packet. Well, he is fool, but what can we do ? 363 packet. Well, he is fool, but what can we do ?
362 */ 364 */
363 rel_type = ICMP_PARAMETERPROB; 365 rel_type = ICMP_PARAMETERPROB;
364 rel_info = skb->h.icmph->un.gateway - hlen; 366 rel_info = htonl((n - hlen) << 24);
365 break; 367 break;
366 368
367 case ICMP_DEST_UNREACH: 369 case ICMP_DEST_UNREACH:
@@ -372,13 +374,14 @@ out:
372 return 0; 374 return 0;
373 case ICMP_FRAG_NEEDED: 375 case ICMP_FRAG_NEEDED:
374 /* And it is the only really necessary thing :-) */ 376 /* And it is the only really necessary thing :-) */
375 rel_info = ntohs(skb->h.icmph->un.frag.mtu); 377 n = ntohs(skb->h.icmph->un.frag.mtu);
376 if (rel_info < hlen+68) 378 if (n < hlen+68)
377 return 0; 379 return 0;
378 rel_info -= hlen; 380 n -= hlen;
379 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ 381 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */
380 if (rel_info > ntohs(eiph->tot_len)) 382 if (n > ntohs(eiph->tot_len))
381 return 0; 383 return 0;
384 rel_info = htonl(n);
382 break; 385 break;
383 default: 386 default:
384 /* All others are translated to HOST_UNREACH. 387 /* All others are translated to HOST_UNREACH.
@@ -440,12 +443,11 @@ out:
440 443
441 /* change mtu on this route */ 444 /* change mtu on this route */
442 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { 445 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
443 if (rel_info > dst_mtu(skb2->dst)) { 446 if (n > dst_mtu(skb2->dst)) {
444 kfree_skb(skb2); 447 kfree_skb(skb2);
445 return 0; 448 return 0;
446 } 449 }
447 skb2->dst->ops->update_pmtu(skb2->dst, rel_info); 450 skb2->dst->ops->update_pmtu(skb2->dst, n);
448 rel_info = htonl(rel_info);
449 } else if (type == ICMP_TIME_EXCEEDED) { 451 } else if (type == ICMP_TIME_EXCEEDED) {
450 struct ip_tunnel *t = netdev_priv(skb2->dev); 452 struct ip_tunnel *t = netdev_priv(skb2->dev);
451 if (t->parms.iph.ttl) { 453 if (t->parms.iph.ttl) {