Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <jesse@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jesse Gross and committed by
David S. Miller
b8693877 b8f8be3f

+10 -7
+1 -1
include/net/geneve.h
··· 90 90 struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, 91 91 __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, 92 92 __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, 93 - bool xnet); 93 + bool csum, bool xnet); 94 94 #endif /*ifdef CONFIG_INET */ 95 95 96 96 #endif /*ifdef__NET_GENEVE_H */
+3 -3
net/ipv4/geneve.c
··· 107 107 struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, 108 108 __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, 109 109 __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, 110 - bool xnet) 110 + bool csum, bool xnet) 111 111 { 112 112 struct genevehdr *gnvh; 113 113 int min_headroom; 114 114 int err; 115 115 116 - skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); 116 + skb = udp_tunnel_handle_offloads(skb, csum); 117 117 if (IS_ERR(skb)) 118 118 return PTR_ERR(skb); 119 119 ··· 138 138 139 139 return udp_tunnel_xmit_skb(rt, skb, src, dst, 140 140 tos, ttl, df, src_port, dst_port, xnet, 141 - gs->sock->sk->sk_no_check_tx); 141 + !csum); 142 142 } 143 143 EXPORT_SYMBOL_GPL(geneve_xmit_skb); 144 144
+1 -1
net/openvswitch/vport-geneve.c
··· 212 212 tun_key->ipv4_dst, tun_key->ipv4_tos, 213 213 tun_key->ipv4_ttl, df, sport, dport, 214 214 tun_key->tun_flags, vni, opts_len, opts, 215 - false); 215 + !!(tun_key->tun_flags & TUNNEL_CSUM), false); 216 216 if (err < 0) 217 217 ip_rt_put(rt); 218 218 return err;
+5 -2
net/openvswitch/vport-vxlan.c
··· 74 74 __be64 key; 75 75 __be16 flags; 76 76 77 - flags = TUNNEL_KEY; 77 + flags = TUNNEL_KEY | (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0); 78 78 vxlan_port = vxlan_vport(vport); 79 79 if (vxlan_port->exts & VXLAN_F_GBP) 80 80 flags |= TUNNEL_VXLAN_OPT; ··· 230 230 __be16 src_port; 231 231 __be16 df; 232 232 int err; 233 + u32 vxflags; 233 234 234 235 if (unlikely(!OVS_CB(skb)->egress_tun_info)) { 235 236 err = -EINVAL; ··· 252 251 src_port = udp_flow_src_port(net, skb, 0, 0, true); 253 252 md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8); 254 253 md.gbp = vxlan_ext_gbp(skb); 254 + vxflags = vxlan_port->exts | 255 + (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0); 255 256 256 257 err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst, 257 258 tun_key->ipv4_tos, tun_key->ipv4_ttl, df, 258 259 src_port, dst_port, 259 - &md, false, vxlan_port->exts); 260 + &md, false, vxflags); 260 261 if (err < 0) 261 262 ip_rt_put(rt); 262 263 return err;