diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/sit.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 2362a3397e91..b6e145a673ab 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -637,6 +637,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
637 | struct iphdr *tiph = &tunnel->parms.iph; | 637 | struct iphdr *tiph = &tunnel->parms.iph; |
638 | struct ipv6hdr *iph6 = ipv6_hdr(skb); | 638 | struct ipv6hdr *iph6 = ipv6_hdr(skb); |
639 | u8 tos = tunnel->parms.iph.tos; | 639 | u8 tos = tunnel->parms.iph.tos; |
640 | __be16 df = tiph->frag_off; | ||
640 | struct rtable *rt; /* Route to the other host */ | 641 | struct rtable *rt; /* Route to the other host */ |
641 | struct net_device *tdev; /* Device to other host */ | 642 | struct net_device *tdev; /* Device to other host */ |
642 | struct iphdr *iph; /* Our new IP header */ | 643 | struct iphdr *iph; /* Our new IP header */ |
@@ -726,25 +727,28 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
726 | goto tx_error; | 727 | goto tx_error; |
727 | } | 728 | } |
728 | 729 | ||
729 | if (tiph->frag_off) | 730 | if (df) { |
730 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); | 731 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); |
731 | else | ||
732 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | ||
733 | 732 | ||
734 | if (mtu < 68) { | 733 | if (mtu < 68) { |
735 | stats->collisions++; | 734 | stats->collisions++; |
736 | ip_rt_put(rt); | 735 | ip_rt_put(rt); |
737 | goto tx_error; | 736 | goto tx_error; |
738 | } | 737 | } |
739 | if (mtu < IPV6_MIN_MTU) | ||
740 | mtu = IPV6_MIN_MTU; | ||
741 | if (tunnel->parms.iph.daddr && skb_dst(skb)) | ||
742 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
743 | 738 | ||
744 | if (skb->len > mtu) { | 739 | if (mtu < IPV6_MIN_MTU) { |
745 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); | 740 | mtu = IPV6_MIN_MTU; |
746 | ip_rt_put(rt); | 741 | df = 0; |
747 | goto tx_error; | 742 | } |
743 | |||
744 | if (tunnel->parms.iph.daddr && skb_dst(skb)) | ||
745 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
746 | |||
747 | if (skb->len > mtu) { | ||
748 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev); | ||
749 | ip_rt_put(rt); | ||
750 | goto tx_error; | ||
751 | } | ||
748 | } | 752 | } |
749 | 753 | ||
750 | if (tunnel->err_count > 0) { | 754 | if (tunnel->err_count > 0) { |
@@ -792,11 +796,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
792 | iph = ip_hdr(skb); | 796 | iph = ip_hdr(skb); |
793 | iph->version = 4; | 797 | iph->version = 4; |
794 | iph->ihl = sizeof(struct iphdr)>>2; | 798 | iph->ihl = sizeof(struct iphdr)>>2; |
795 | if (mtu > IPV6_MIN_MTU) | 799 | iph->frag_off = df; |
796 | iph->frag_off = tiph->frag_off; | ||
797 | else | ||
798 | iph->frag_off = 0; | ||
799 | |||
800 | iph->protocol = IPPROTO_IPV6; | 800 | iph->protocol = IPPROTO_IPV6; |
801 | iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); | 801 | iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6)); |
802 | iph->daddr = rt->rt_dst; | 802 | iph->daddr = rt->rt_dst; |