diff options
Diffstat (limited to 'net/ipv4/ipip.c')
| -rw-r--r-- | net/ipv4/ipip.c | 32 | 
1 files changed, 17 insertions, 15 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index 08ccd344de7a..ae40ed1ba560 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c  | |||
| @@ -438,25 +438,27 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 438 | goto tx_error; | 438 | goto tx_error; | 
| 439 | } | 439 | } | 
| 440 | 440 | ||
| 441 | if (tiph->frag_off) | 441 | df |= old_iph->frag_off & htons(IP_DF); | 
| 442 | |||
| 443 | if (df) { | ||
| 442 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); | 444 | mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); | 
| 443 | else | ||
| 444 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | ||
| 445 | 445 | ||
| 446 | if (mtu < 68) { | 446 | if (mtu < 68) { | 
| 447 | stats->collisions++; | 447 | stats->collisions++; | 
| 448 | ip_rt_put(rt); | 448 | ip_rt_put(rt); | 
| 449 | goto tx_error; | 449 | goto tx_error; | 
| 450 | } | 450 | } | 
| 451 | if (skb_dst(skb)) | ||
| 452 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
| 453 | 451 | ||
| 454 | df |= (old_iph->frag_off&htons(IP_DF)); | 452 | if (skb_dst(skb)) | 
| 453 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); | ||
| 455 | 454 | ||
| 456 | if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { | 455 | if ((old_iph->frag_off & htons(IP_DF)) && | 
| 457 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); | 456 | mtu < ntohs(old_iph->tot_len)) { | 
| 458 | ip_rt_put(rt); | 457 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 
| 459 | goto tx_error; | 458 | htonl(mtu)); | 
| 459 | ip_rt_put(rt); | ||
| 460 | goto tx_error; | ||
| 461 | } | ||
| 460 | } | 462 | } | 
| 461 | 463 | ||
| 462 | if (tunnel->err_count > 0) { | 464 | if (tunnel->err_count > 0) { | 
