aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_gre.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r--net/ipv4/ip_gre.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index ab99bebdcdc8..f5fba051df3d 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/capability.h> 13#include <linux/capability.h>
14#include <linux/config.h>
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/types.h> 15#include <linux/types.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
@@ -394,7 +393,8 @@ out:
394 int code = skb->h.icmph->code; 393 int code = skb->h.icmph->code;
395 int rel_type = 0; 394 int rel_type = 0;
396 int rel_code = 0; 395 int rel_code = 0;
397 int rel_info = 0; 396 __be32 rel_info = 0;
397 __u32 n = 0;
398 u16 flags; 398 u16 flags;
399 int grehlen = (iph->ihl<<2) + 4; 399 int grehlen = (iph->ihl<<2) + 4;
400 struct sk_buff *skb2; 400 struct sk_buff *skb2;
@@ -423,14 +423,16 @@ out:
423 default: 423 default:
424 return; 424 return;
425 case ICMP_PARAMETERPROB: 425 case ICMP_PARAMETERPROB:
426 if (skb->h.icmph->un.gateway < (iph->ihl<<2)) 426 n = ntohl(skb->h.icmph->un.gateway) >> 24;
427 if (n < (iph->ihl<<2))
427 return; 428 return;
428 429
429 /* So... This guy found something strange INSIDE encapsulated 430 /* So... This guy found something strange INSIDE encapsulated
430 packet. Well, he is fool, but what can we do ? 431 packet. Well, he is fool, but what can we do ?
431 */ 432 */
432 rel_type = ICMP_PARAMETERPROB; 433 rel_type = ICMP_PARAMETERPROB;
433 rel_info = skb->h.icmph->un.gateway - grehlen; 434 n -= grehlen;
435 rel_info = htonl(n << 24);
434 break; 436 break;
435 437
436 case ICMP_DEST_UNREACH: 438 case ICMP_DEST_UNREACH:
@@ -441,13 +443,14 @@ out:
441 return; 443 return;
442 case ICMP_FRAG_NEEDED: 444 case ICMP_FRAG_NEEDED:
443 /* And it is the only really necessary thing :-) */ 445 /* And it is the only really necessary thing :-) */
444 rel_info = ntohs(skb->h.icmph->un.frag.mtu); 446 n = ntohs(skb->h.icmph->un.frag.mtu);
445 if (rel_info < grehlen+68) 447 if (n < grehlen+68)
446 return; 448 return;
447 rel_info -= grehlen; 449 n -= grehlen;
448 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ 450 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */
449 if (rel_info > ntohs(eiph->tot_len)) 451 if (n > ntohs(eiph->tot_len))
450 return; 452 return;
453 rel_info = htonl(n);
451 break; 454 break;
452 default: 455 default:
453 /* All others are translated to HOST_UNREACH. 456 /* All others are translated to HOST_UNREACH.
@@ -509,12 +512,11 @@ out:
509 512
510 /* change mtu on this route */ 513 /* change mtu on this route */
511 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { 514 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
512 if (rel_info > dst_mtu(skb2->dst)) { 515 if (n > dst_mtu(skb2->dst)) {
513 kfree_skb(skb2); 516 kfree_skb(skb2);
514 return; 517 return;
515 } 518 }
516 skb2->dst->ops->update_pmtu(skb2->dst, rel_info); 519 skb2->dst->ops->update_pmtu(skb2->dst, n);
517 rel_info = htonl(rel_info);
518 } else if (type == ICMP_TIME_EXCEEDED) { 520 } else if (type == ICMP_TIME_EXCEEDED) {
519 struct ip_tunnel *t = netdev_priv(skb2->dev); 521 struct ip_tunnel *t = netdev_priv(skb2->dev);
520 if (t->parms.iph.ttl) { 522 if (t->parms.iph.ttl) {
@@ -577,7 +579,7 @@ static int ipgre_rcv(struct sk_buff *skb)
577 579
578 if (flags&GRE_CSUM) { 580 if (flags&GRE_CSUM) {
579 switch (skb->ip_summed) { 581 switch (skb->ip_summed) {
580 case CHECKSUM_HW: 582 case CHECKSUM_COMPLETE:
581 csum = (u16)csum_fold(skb->csum); 583 csum = (u16)csum_fold(skb->csum);
582 if (!csum) 584 if (!csum)
583 break; 585 break;
@@ -585,7 +587,7 @@ static int ipgre_rcv(struct sk_buff *skb)
585 case CHECKSUM_NONE: 587 case CHECKSUM_NONE:
586 skb->csum = 0; 588 skb->csum = 0;
587 csum = __skb_checksum_complete(skb); 589 csum = __skb_checksum_complete(skb);
588 skb->ip_summed = CHECKSUM_HW; 590 skb->ip_summed = CHECKSUM_COMPLETE;
589 } 591 }
590 offset += 4; 592 offset += 4;
591 } 593 }
@@ -618,7 +620,6 @@ static int ipgre_rcv(struct sk_buff *skb)
618 skb->mac.raw = skb->nh.raw; 620 skb->mac.raw = skb->nh.raw;
619 skb->nh.raw = __pskb_pull(skb, offset); 621 skb->nh.raw = __pskb_pull(skb, offset);
620 skb_postpull_rcsum(skb, skb->h.raw, offset); 622 skb_postpull_rcsum(skb, skb->h.raw, offset);
621 memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
622 skb->pkt_type = PACKET_HOST; 623 skb->pkt_type = PACKET_HOST;
623#ifdef CONFIG_NET_IPGRE_BROADCAST 624#ifdef CONFIG_NET_IPGRE_BROADCAST
624 if (MULTICAST(iph->daddr)) { 625 if (MULTICAST(iph->daddr)) {