aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/ip_vti.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 5cf10b777b7e..a917903d5e97 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -156,6 +156,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
156 struct dst_entry *dst = skb_dst(skb); 156 struct dst_entry *dst = skb_dst(skb);
157 struct net_device *tdev; /* Device to other host */ 157 struct net_device *tdev; /* Device to other host */
158 int err; 158 int err;
159 int mtu;
159 160
160 if (!dst) { 161 if (!dst) {
161 dev->stats.tx_carrier_errors++; 162 dev->stats.tx_carrier_errors++;
@@ -192,6 +193,23 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
192 tunnel->err_count = 0; 193 tunnel->err_count = 0;
193 } 194 }
194 195
196 mtu = dst_mtu(dst);
197 if (skb->len > mtu) {
198 skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
199 if (skb->protocol == htons(ETH_P_IP)) {
200 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
201 htonl(mtu));
202 } else {
203 if (mtu < IPV6_MIN_MTU)
204 mtu = IPV6_MIN_MTU;
205
206 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
207 }
208
209 dst_release(dst);
210 goto tx_error;
211 }
212
195 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev))); 213 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
196 skb_dst_set(skb, dst); 214 skb_dst_set(skb, dst);
197 skb->dev = skb_dst(skb)->dev; 215 skb->dev = skb_dst(skb)->dev;