Upstream commit:
    openvswitch: Add support for checksums on UDP tunnels.

    Currently, it isn't possible to request checksums on the outer UDP
    header of tunnels - the TUNNEL_CSUM flag is ignored. This adds
    support for requesting that UDP checksums be computed on transmit
    and properly reported if they are present on receive.

    Signed-off-by: Jesse Gross <je...@nicira.com>
    Signed-off-by: David S. Miller <da...@davemloft.net>

Upstream: b8693877 ("openvswitch: Add support for checksums on UDP tunnels.")
Signed-off-by: Jesse Gross <je...@nicira.com>
---
 datapath/linux/compat/include/net/vxlan.h | 4 ++++
 datapath/linux/compat/vxlan.c             | 5 +++--
 datapath/vport-vxlan.c                    | 7 +++++--
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/datapath/linux/compat/include/net/vxlan.h 
b/datapath/linux/compat/include/net/vxlan.h
index 198a1e3..7511c2e 100644
--- a/datapath/linux/compat/include/net/vxlan.h
+++ b/datapath/linux/compat/include/net/vxlan.h
@@ -79,6 +79,10 @@ struct vxlanhdr_gbp {
 #define VXLAN_F_GBP                    0x800
 #endif
 
+#ifndef VXLAN_F_UDP_CSUM
+#define VXLAN_F_UDP_CSUM                0x40
+#endif
+
 #ifndef VXLAN_F_RCV_FLAGS
 #define VXLAN_F_RCV_FLAGS                      VXLAN_F_GBP
 #endif
diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
index ad5e4b4..7556dc5 100644
--- a/datapath/linux/compat/vxlan.c
+++ b/datapath/linux/compat/vxlan.c
@@ -190,8 +190,9 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
        struct vxlanhdr *vxh;
        int min_headroom;
        int err;
+       bool udp_sum = !!(vxflags & VXLAN_F_UDP_CSUM);
 
-       skb = udp_tunnel_handle_offloads(skb, false, true);
+       skb = udp_tunnel_handle_offloads(skb, udp_sum, true);
        if (IS_ERR(skb))
                return PTR_ERR(skb);
 
@@ -223,7 +224,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
 
        return udp_tunnel_xmit_skb(rt, skb, src, dst, tos,
                                   ttl, df, src_port, dst_port, xnet,
-                                  true);
+                                  !udp_sum);
 }
 
 static void rcu_free_vs(struct rcu_head *rcu)
diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c
index 7fcb88a..c25cc58 100644
--- a/datapath/vport-vxlan.c
+++ b/datapath/vport-vxlan.c
@@ -72,7 +72,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff 
*skb,
        __be64 key;
        __be16 flags;
 
-       flags = TUNNEL_KEY;
+       flags = TUNNEL_KEY | (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0);
        vxlan_port = vxlan_vport(vport);
        if (vxlan_port->exts & VXLAN_F_GBP && md->gbp)
                flags |= TUNNEL_VXLAN_OPT;
@@ -228,6 +228,7 @@ static int vxlan_tnl_send(struct vport *vport, struct 
sk_buff *skb)
        __be32 saddr;
        __be16 df;
        int err;
+       u32 vxflags;
 
        if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
                err = -EINVAL;
@@ -253,13 +254,15 @@ static int vxlan_tnl_send(struct vport *vport, struct 
sk_buff *skb)
        src_port = udp_flow_src_port(net, skb, 0, 0, true);
        md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8);
        md.gbp = vxlan_ext_gbp(skb);
+       vxflags = vxlan_port->exts |
+                     (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0);
 
        err = vxlan_xmit_skb(vxlan_port->vs, rt, skb,
                             saddr, tun_key->ipv4_dst,
                             tun_key->ipv4_tos,
                             tun_key->ipv4_ttl, df,
                             src_port, dst_port,
-                            &md, false, vxlan_port->exts);
+                            &md, false, vxflags);
        if (err < 0)
                ip_rt_put(rt);
        return err;
-- 
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to