aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_gre.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-30 03:13:03 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-07-30 03:13:03 -0400
commitfcb06702f023a0e7b1e6ebf9746f34b610ca0508 (patch)
treedb022324c4978dd9af059be38822d23455a45f55 /net/ipv4/ip_gre.c
parent5e31fc0815a4e2c72b1b495fe7a0d8f9bfb9e4b4 (diff)
parent9dbf5f55f8d35ff9aedc75267f4e4042aaf89755 (diff)
Merge remote-tracking branch 'wireless/master' into mac80211
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r--net/ipv4/ip_gre.c25
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));