VXLAN: Support outer IPv4 Tx checksums by default
authorAlexander Duyck <aduyck@mirantis.com>
Fri, 19 Feb 2016 19:26:31 +0000 (11:26 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Feb 2016 03:05:50 +0000 (22:05 -0500)
This change makes it so that if UDP CSUM is not specified we will default
to enabling it.  The main motivation behind this is the fact that with the
use of outer checksum we can greatly improve the performance for VXLAN
tunnels on devices that don't know how to parse tunnel headers.

Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
Acked-by: Tom Herbert <tom@herbertland.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/vxlan.c
include/net/vxlan.h

index c963897..2ddc642 100644 (file)
@@ -1957,13 +1957,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        goto drop;
                sk = vxlan->vn4_sock->sock->sk;
 
-               if (info) {
-                       if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT)
-                               df = htons(IP_DF);
-               } else {
-                       udp_sum = !!(flags & VXLAN_F_UDP_CSUM);
-               }
-
                rt = vxlan_get_route(vxlan, skb,
                                     rdst ? rdst->remote_ifindex : 0, tos,
                                     dst->sin.sin_addr.s_addr, &saddr,
@@ -1997,6 +1990,11 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        return;
                }
 
+               if (!info)
+                       udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM_TX);
+               else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT)
+                       df = htons(IP_DF);
+
                tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
                ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
                err = vxlan_build_skb(skb, &rt->dst, sizeof(struct iphdr),
@@ -2898,8 +2896,9 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
        if (data[IFLA_VXLAN_PORT])
                conf.dst_port = nla_get_be16(data[IFLA_VXLAN_PORT]);
 
-       if (data[IFLA_VXLAN_UDP_CSUM] && nla_get_u8(data[IFLA_VXLAN_UDP_CSUM]))
-               conf.flags |= VXLAN_F_UDP_CSUM;
+       if (data[IFLA_VXLAN_UDP_CSUM] &&
+           !nla_get_u8(data[IFLA_VXLAN_UDP_CSUM]))
+               conf.flags |= VXLAN_F_UDP_ZERO_CSUM_TX;
 
        if (data[IFLA_VXLAN_UDP_ZERO_CSUM6_TX] &&
            nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]))
@@ -3043,7 +3042,7 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
            nla_put_u32(skb, IFLA_VXLAN_LIMIT, vxlan->cfg.addrmax) ||
            nla_put_be16(skb, IFLA_VXLAN_PORT, vxlan->cfg.dst_port) ||
            nla_put_u8(skb, IFLA_VXLAN_UDP_CSUM,
-                       !!(vxlan->flags & VXLAN_F_UDP_CSUM)) ||
+                       !(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM_TX)) ||
            nla_put_u8(skb, IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
                        !!(vxlan->flags & VXLAN_F_UDP_ZERO_CSUM6_TX)) ||
            nla_put_u8(skb, IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
index 748083d..6eda4ed 100644 (file)
@@ -197,7 +197,7 @@ struct vxlan_dev {
 #define VXLAN_F_L2MISS                 0x08
 #define VXLAN_F_L3MISS                 0x10
 #define VXLAN_F_IPV6                   0x20
-#define VXLAN_F_UDP_CSUM               0x40
+#define VXLAN_F_UDP_ZERO_CSUM_TX       0x40
 #define VXLAN_F_UDP_ZERO_CSUM6_TX      0x80
 #define VXLAN_F_UDP_ZERO_CSUM6_RX      0x100
 #define VXLAN_F_REMCSUM_TX             0x200