diff options
| author | Jesse Gross <jesse@nicira.com> | 2015-01-28 19:32:46 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-01-29 02:04:15 -0500 |
| commit | b8693877ae016ac525d674d5d7a84ea0ea68ba60 (patch) | |
| tree | 7ab9067c1c28bc829336a8d95736303f69d0bdea /net | |
| parent | b8f8be3f043d6dba7d6c3426e4597d2ebf5a3547 (diff) | |
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>
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/geneve.c | 6 | ||||
| -rw-r--r-- | net/openvswitch/vport-geneve.c | 2 | ||||
| -rw-r--r-- | net/openvswitch/vport-vxlan.c | 7 |
3 files changed, 9 insertions, 6 deletions
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index 93e51199e44b..5a4828ba05ad 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
| @@ -107,13 +107,13 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
| 107 | struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, | 107 | struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, |
| 108 | __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, | 108 | __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, |
| 109 | __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, | 109 | __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, |
| 110 | bool xnet) | 110 | bool csum, bool xnet) |
| 111 | { | 111 | { |
| 112 | struct genevehdr *gnvh; | 112 | struct genevehdr *gnvh; |
| 113 | int min_headroom; | 113 | int min_headroom; |
| 114 | int err; | 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 | if (IS_ERR(skb)) | 117 | if (IS_ERR(skb)) |
| 118 | return PTR_ERR(skb); | 118 | return PTR_ERR(skb); |
| 119 | 119 | ||
| @@ -138,7 +138,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
| 138 | 138 | ||
| 139 | return udp_tunnel_xmit_skb(rt, skb, src, dst, | 139 | return udp_tunnel_xmit_skb(rt, skb, src, dst, |
| 140 | tos, ttl, df, src_port, dst_port, xnet, | 140 | tos, ttl, df, src_port, dst_port, xnet, |
| 141 | gs->sock->sk->sk_no_check_tx); | 141 | !csum); |
| 142 | } | 142 | } |
| 143 | EXPORT_SYMBOL_GPL(geneve_xmit_skb); | 143 | EXPORT_SYMBOL_GPL(geneve_xmit_skb); |
| 144 | 144 | ||
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c index 7ca3d454ff3b..bf02fd5808c9 100644 --- a/net/openvswitch/vport-geneve.c +++ b/net/openvswitch/vport-geneve.c | |||
| @@ -212,7 +212,7 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 212 | tun_key->ipv4_dst, tun_key->ipv4_tos, | 212 | tun_key->ipv4_dst, tun_key->ipv4_tos, |
| 213 | tun_key->ipv4_ttl, df, sport, dport, | 213 | tun_key->ipv4_ttl, df, sport, dport, |
| 214 | tun_key->tun_flags, vni, opts_len, opts, | 214 | tun_key->tun_flags, vni, opts_len, opts, |
| 215 | false); | 215 | !!(tun_key->tun_flags & TUNNEL_CSUM), false); |
| 216 | if (err < 0) | 216 | if (err < 0) |
| 217 | ip_rt_put(rt); | 217 | ip_rt_put(rt); |
| 218 | return err; | 218 | return err; |
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index 3cc983bf444a..ff07d4062d60 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c | |||
| @@ -74,7 +74,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, | |||
| 74 | __be64 key; | 74 | __be64 key; |
| 75 | __be16 flags; | 75 | __be16 flags; |
| 76 | 76 | ||
| 77 | flags = TUNNEL_KEY; | 77 | flags = TUNNEL_KEY | (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0); |
| 78 | vxlan_port = vxlan_vport(vport); | 78 | vxlan_port = vxlan_vport(vport); |
| 79 | if (vxlan_port->exts & VXLAN_F_GBP) | 79 | if (vxlan_port->exts & VXLAN_F_GBP) |
| 80 | flags |= TUNNEL_VXLAN_OPT; | 80 | flags |= TUNNEL_VXLAN_OPT; |
| @@ -230,6 +230,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 230 | __be16 src_port; | 230 | __be16 src_port; |
| 231 | __be16 df; | 231 | __be16 df; |
| 232 | int err; | 232 | int err; |
| 233 | u32 vxflags; | ||
| 233 | 234 | ||
| 234 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { | 235 | if (unlikely(!OVS_CB(skb)->egress_tun_info)) { |
| 235 | err = -EINVAL; | 236 | err = -EINVAL; |
| @@ -251,11 +252,13 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 251 | src_port = udp_flow_src_port(net, skb, 0, 0, true); | 252 | src_port = udp_flow_src_port(net, skb, 0, 0, true); |
| 252 | md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8); | 253 | md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8); |
| 253 | md.gbp = vxlan_ext_gbp(skb); | 254 | md.gbp = vxlan_ext_gbp(skb); |
| 255 | vxflags = vxlan_port->exts | | ||
| 256 | (tun_key->tun_flags & TUNNEL_CSUM ? VXLAN_F_UDP_CSUM : 0); | ||
| 254 | 257 | ||
| 255 | err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst, | 258 | err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst, |
| 256 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, | 259 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, |
| 257 | src_port, dst_port, | 260 | src_port, dst_port, |
| 258 | &md, false, vxlan_port->exts); | 261 | &md, false, vxflags); |
| 259 | if (err < 0) | 262 | if (err < 0) |
| 260 | ip_rt_put(rt); | 263 | ip_rt_put(rt); |
| 261 | return err; | 264 | return err; |
