aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipip.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r--net/ipv4/ipip.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index a2ca53da4372..c5b1f71c3cd8 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -446,25 +446,27 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
446 goto tx_error; 446 goto tx_error;
447 } 447 }
448 448
449 if (tiph->frag_off) 449 df |= old_iph->frag_off & htons(IP_DF);
450
451 if (df) {
450 mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr); 452 mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
451 else
452 mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
453 453
454 if (mtu < 68) { 454 if (mtu < 68) {
455 stats->collisions++; 455 stats->collisions++;
456 ip_rt_put(rt); 456 ip_rt_put(rt);
457 goto tx_error; 457 goto tx_error;
458 } 458 }
459 if (skb_dst(skb))
460 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
461 459
462 df |= (old_iph->frag_off&htons(IP_DF)); 460 if (skb_dst(skb))
461 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
463 462
464 if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { 463 if ((old_iph->frag_off & htons(IP_DF)) &&
465 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); 464 mtu < ntohs(old_iph->tot_len)) {
466 ip_rt_put(rt); 465 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
467 goto tx_error; 466 htonl(mtu));
467 ip_rt_put(rt);
468 goto tx_error;
469 }
468 } 470 }
469 471
470 if (tunnel->err_count > 0) { 472 if (tunnel->err_count > 0) {