aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_vti.c
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2015-05-29 14:28:26 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-01 19:03:43 -0400
commitccd740cbc6e01b2a08baa341867063ed2887f4b9 (patch)
tree3a0e80328b82f33c3c853ef07e388a1a50c0e3b4 /net/ipv6/ip6_vti.c
parent18ec898ee54e03a9aab8b54db50cb2b36209d313 (diff)
vti6: Add pmtu handling to vti6_xmit.
We currently rely on the PMTU discovery of xfrm. However if a packet is localy sent, the PMTU mechanism of xfrm tries to to local socket notification what might not work for applications like ping that don't check for this. So add pmtu handling to vti6_xmit to report MTU changes immediately. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_vti.c')
-rw-r--r--net/ipv6/ip6_vti.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index ff3bd863fa03..0224c032dca5 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -435,6 +435,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
435 struct net_device *tdev; 435 struct net_device *tdev;
436 struct xfrm_state *x; 436 struct xfrm_state *x;
437 int err = -1; 437 int err = -1;
438 int mtu;
438 439
439 if (!dst) 440 if (!dst)
440 goto tx_err_link_failure; 441 goto tx_err_link_failure;
@@ -468,6 +469,19 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
468 skb_dst_set(skb, dst); 469 skb_dst_set(skb, dst);
469 skb->dev = skb_dst(skb)->dev; 470 skb->dev = skb_dst(skb)->dev;
470 471
472 mtu = dst_mtu(dst);
473 if (!skb->ignore_df && skb->len > mtu) {
474 skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu);
475
476 if (skb->protocol == htons(ETH_P_IPV6))
477 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
478 else
479 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
480 htonl(mtu));
481
482 return -EMSGSIZE;
483 }
484
471 err = dst_output(skb); 485 err = dst_output(skb);
472 if (net_xmit_eval(err) == 0) { 486 if (net_xmit_eval(err) == 0) {
473 struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); 487 struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);