]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
geneve: update skb dst pmtu on tx path
authorXin Long <lucien.xin@gmail.com>
Mon, 25 Dec 2017 06:43:58 +0000 (14:43 +0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 2 Jan 2018 17:34:59 +0000 (12:34 -0500)
Commit a93bf0ff4490 ("vxlan: update skb dst pmtu on tx path") has fixed
a performance issue caused by the change of lower dev's mtu for vxlan.

The same thing needs to be done for geneve as well.

Note that geneve cannot adjust it's mtu according to lower dev's mtu
when creating it. The performance is very low later when netperfing
over it without fixing the mtu manually. This patch could also avoid
this issue.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/geneve.c

index b718a02a6bb6055d7841619b42cb400d1eea0984..0a48b3073d3d3614483e9d8ae64f073a5b3d2ead 100644 (file)
@@ -825,6 +825,13 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        if (IS_ERR(rt))
                return PTR_ERR(rt);
 
+       if (skb_dst(skb)) {
+               int mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr) -
+                         GENEVE_BASE_HLEN - info->options_len - 14;
+
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
+       }
+
        sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
        if (geneve->collect_md) {
                tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
@@ -864,6 +871,13 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        if (IS_ERR(dst))
                return PTR_ERR(dst);
 
+       if (skb_dst(skb)) {
+               int mtu = dst_mtu(dst) - sizeof(struct ipv6hdr) -
+                         GENEVE_BASE_HLEN - info->options_len - 14;
+
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
+       }
+
        sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
        if (geneve->collect_md) {
                prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);