|
@@ -637,6 +637,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|
struct iphdr *tiph = &tunnel->parms.iph;
|
|
struct iphdr *tiph = &tunnel->parms.iph;
|
|
struct ipv6hdr *iph6 = ipv6_hdr(skb);
|
|
struct ipv6hdr *iph6 = ipv6_hdr(skb);
|
|
u8 tos = tunnel->parms.iph.tos;
|
|
u8 tos = tunnel->parms.iph.tos;
|
|
|
|
+ __be16 df = tiph->frag_off;
|
|
struct rtable *rt; /* Route to the other host */
|
|
struct rtable *rt; /* Route to the other host */
|
|
struct net_device *tdev; /* Device to other host */
|
|
struct net_device *tdev; /* Device to other host */
|
|
struct iphdr *iph; /* Our new IP header */
|
|
struct iphdr *iph; /* Our new IP header */
|
|
@@ -726,25 +727,28 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|
goto tx_error;
|
|
goto tx_error;
|
|
}
|
|
}
|
|
|
|
|
|
- if (tiph->frag_off)
|
|
|
|
|
|
+ if (df) {
|
|
mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
|
|
mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
|
|
- else
|
|
|
|
- mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
|
|
|
|
|
|
|
|
- if (mtu < 68) {
|
|
|
|
- stats->collisions++;
|
|
|
|
- ip_rt_put(rt);
|
|
|
|
- goto tx_error;
|
|
|
|
- }
|
|
|
|
- if (mtu < IPV6_MIN_MTU)
|
|
|
|
- mtu = IPV6_MIN_MTU;
|
|
|
|
- if (tunnel->parms.iph.daddr && skb_dst(skb))
|
|
|
|
- skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
|
|
|
|
|
|
+ if (mtu < 68) {
|
|
|
|
+ stats->collisions++;
|
|
|
|
+ ip_rt_put(rt);
|
|
|
|
+ goto tx_error;
|
|
|
|
+ }
|
|
|
|
|
|
- if (skb->len > mtu) {
|
|
|
|
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
|
|
|
|
- ip_rt_put(rt);
|
|
|
|
- goto tx_error;
|
|
|
|
|
|
+ if (mtu < IPV6_MIN_MTU) {
|
|
|
|
+ mtu = IPV6_MIN_MTU;
|
|
|
|
+ df = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (tunnel->parms.iph.daddr && skb_dst(skb))
|
|
|
|
+ skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
|
|
|
|
+
|
|
|
|
+ if (skb->len > mtu) {
|
|
|
|
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
|
|
|
|
+ ip_rt_put(rt);
|
|
|
|
+ goto tx_error;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (tunnel->err_count > 0) {
|
|
if (tunnel->err_count > 0) {
|
|
@@ -792,11 +796,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|
iph = ip_hdr(skb);
|
|
iph = ip_hdr(skb);
|
|
iph->version = 4;
|
|
iph->version = 4;
|
|
iph->ihl = sizeof(struct iphdr)>>2;
|
|
iph->ihl = sizeof(struct iphdr)>>2;
|
|
- if (mtu > IPV6_MIN_MTU)
|
|
|
|
- iph->frag_off = tiph->frag_off;
|
|
|
|
- else
|
|
|
|
- iph->frag_off = 0;
|
|
|
|
-
|
|
|
|
|
|
+ iph->frag_off = df;
|
|
iph->protocol = IPPROTO_IPV6;
|
|
iph->protocol = IPPROTO_IPV6;
|
|
iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
|
|
iph->tos = INET_ECN_encapsulate(tos, ipv6_get_dsfield(iph6));
|
|
iph->daddr = rt->rt_dst;
|
|
iph->daddr = rt->rt_dst;
|