diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-07-30 03:13:03 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-30 03:13:03 -0400 |
commit | fcb06702f023a0e7b1e6ebf9746f34b610ca0508 (patch) | |
tree | db022324c4978dd9af059be38822d23455a45f55 /net/ipv4/ip_gre.c | |
parent | 5e31fc0815a4e2c72b1b495fe7a0d8f9bfb9e4b4 (diff) | |
parent | 9dbf5f55f8d35ff9aedc75267f4e4042aaf89755 (diff) |
Merge remote-tracking branch 'wireless/master' into mac80211
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f49047b79609..b062a98574f2 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -516,9 +516,6 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
516 | case ICMP_PORT_UNREACH: | 516 | case ICMP_PORT_UNREACH: |
517 | /* Impossible event. */ | 517 | /* Impossible event. */ |
518 | return; | 518 | return; |
519 | case ICMP_FRAG_NEEDED: | ||
520 | /* Soft state for pmtu is maintained by IP core. */ | ||
521 | return; | ||
522 | default: | 519 | default: |
523 | /* All others are translated to HOST_UNREACH. | 520 | /* All others are translated to HOST_UNREACH. |
524 | rfc2003 contains "deep thoughts" about NET_UNREACH, | 521 | rfc2003 contains "deep thoughts" about NET_UNREACH, |
@@ -531,6 +528,9 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
531 | if (code != ICMP_EXC_TTL) | 528 | if (code != ICMP_EXC_TTL) |
532 | return; | 529 | return; |
533 | break; | 530 | break; |
531 | |||
532 | case ICMP_REDIRECT: | ||
533 | break; | ||
534 | } | 534 | } |
535 | 535 | ||
536 | rcu_read_lock(); | 536 | rcu_read_lock(); |
@@ -538,7 +538,20 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
538 | flags & GRE_KEY ? | 538 | flags & GRE_KEY ? |
539 | *(((__be32 *)p) + (grehlen / 4) - 1) : 0, | 539 | *(((__be32 *)p) + (grehlen / 4) - 1) : 0, |
540 | p[1]); | 540 | p[1]); |
541 | if (t == NULL || t->parms.iph.daddr == 0 || | 541 | if (t == NULL) |
542 | goto out; | ||
543 | |||
544 | if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { | ||
545 | ipv4_update_pmtu(skb, dev_net(skb->dev), info, | ||
546 | t->parms.link, 0, IPPROTO_GRE, 0); | ||
547 | goto out; | ||
548 | } | ||
549 | if (type == ICMP_REDIRECT) { | ||
550 | ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0, | ||
551 | IPPROTO_GRE, 0); | ||
552 | goto out; | ||
553 | } | ||
554 | if (t->parms.iph.daddr == 0 || | ||
542 | ipv4_is_multicast(t->parms.iph.daddr)) | 555 | ipv4_is_multicast(t->parms.iph.daddr)) |
543 | goto out; | 556 | goto out; |
544 | 557 | ||
@@ -753,7 +766,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
753 | 766 | ||
754 | if (skb->protocol == htons(ETH_P_IP)) { | 767 | if (skb->protocol == htons(ETH_P_IP)) { |
755 | rt = skb_rtable(skb); | 768 | rt = skb_rtable(skb); |
756 | dst = rt->rt_gateway; | 769 | dst = rt_nexthop(rt, old_iph->daddr); |
757 | } | 770 | } |
758 | #if IS_ENABLED(CONFIG_IPV6) | 771 | #if IS_ENABLED(CONFIG_IPV6) |
759 | else if (skb->protocol == htons(ETH_P_IPV6)) { | 772 | else if (skb->protocol == htons(ETH_P_IPV6)) { |
@@ -820,7 +833,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
820 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | 833 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
821 | 834 | ||
822 | if (skb_dst(skb)) | 835 | if (skb_dst(skb)) |
823 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | 836 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); |
824 | 837 | ||
825 | if (skb->protocol == htons(ETH_P_IP)) { | 838 | if (skb->protocol == htons(ETH_P_IP)) { |
826 | df |= (old_iph->frag_off&htons(IP_DF)); | 839 | df |= (old_iph->frag_off&htons(IP_DF)); |