瀏覽代碼

Merge branch 'geneve-vxlan-mtu'

Stefano Brivio says:

====================
geneve, vxlan: Don't set exceptions if skb->len < mtu

This series fixes the exception abuse described in 2/2, and 1/2
is just a preparatory change to make 2/2 less ugly.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 6 年之前
父節點
當前提交
dc6d0f0b43
共有 3 個文件被更改,包括 15 次插入21 次删除
  1. 3 11
      drivers/net/geneve.c
  2. 2 10
      drivers/net/vxlan.c
  3. 10 0
      include/net/dst.h

+ 3 - 11
drivers/net/geneve.c

@@ -830,12 +830,8 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
 	if (IS_ERR(rt))
 	if (IS_ERR(rt))
 		return PTR_ERR(rt);
 		return PTR_ERR(rt);
 
 
-	if (skb_dst(skb)) {
-		int mtu = dst_mtu(&rt->dst) - GENEVE_IPV4_HLEN -
-			  info->options_len;
-
-		skb_dst_update_pmtu(skb, mtu);
-	}
+	skb_tunnel_check_pmtu(skb, &rt->dst,
+			      GENEVE_IPV4_HLEN + info->options_len);
 
 
 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
 	if (geneve->collect_md) {
 	if (geneve->collect_md) {
@@ -876,11 +872,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
 	if (IS_ERR(dst))
 	if (IS_ERR(dst))
 		return PTR_ERR(dst);
 		return PTR_ERR(dst);
 
 
-	if (skb_dst(skb)) {
-		int mtu = dst_mtu(dst) - GENEVE_IPV6_HLEN - info->options_len;
-
-		skb_dst_update_pmtu(skb, mtu);
-	}
+	skb_tunnel_check_pmtu(skb, dst, GENEVE_IPV6_HLEN + info->options_len);
 
 
 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
 	if (geneve->collect_md) {
 	if (geneve->collect_md) {

+ 2 - 10
drivers/net/vxlan.c

@@ -2194,11 +2194,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 		}
 		}
 
 
 		ndst = &rt->dst;
 		ndst = &rt->dst;
-		if (skb_dst(skb)) {
-			int mtu = dst_mtu(ndst) - VXLAN_HEADROOM;
-
-			skb_dst_update_pmtu(skb, mtu);
-		}
+		skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM);
 
 
 		tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
 		tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
 		ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
 		ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
@@ -2235,11 +2231,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 				goto out_unlock;
 				goto out_unlock;
 		}
 		}
 
 
-		if (skb_dst(skb)) {
-			int mtu = dst_mtu(ndst) - VXLAN6_HEADROOM;
-
-			skb_dst_update_pmtu(skb, mtu);
-		}
+		skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM);
 
 
 		tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
 		tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
 		ttl = ttl ? : ip6_dst_hoplimit(ndst);
 		ttl = ttl ? : ip6_dst_hoplimit(ndst);

+ 10 - 0
include/net/dst.h

@@ -527,4 +527,14 @@ static inline void skb_dst_update_pmtu(struct sk_buff *skb, u32 mtu)
 		dst->ops->update_pmtu(dst, NULL, skb, mtu);
 		dst->ops->update_pmtu(dst, NULL, skb, mtu);
 }
 }
 
 
+static inline void skb_tunnel_check_pmtu(struct sk_buff *skb,
+					 struct dst_entry *encap_dst,
+					 int headroom)
+{
+	u32 encap_mtu = dst_mtu(encap_dst);
+
+	if (skb->len > encap_mtu - headroom)
+		skb_dst_update_pmtu(skb, encap_mtu - headroom);
+}
+
 #endif /* _NET_DST_H */
 #endif /* _NET_DST_H */