Commit b8693877 authored by Jesse Gross's avatar Jesse Gross Committed by David S. Miller

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: default avatarJesse Gross <jesse@nicira.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b8f8be3f
...@@ -90,7 +90,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, ...@@ -90,7 +90,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos,
__u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
__be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
bool xnet); bool csum, bool xnet);
#endif /*ifdef CONFIG_INET */ #endif /*ifdef CONFIG_INET */
#endif /*ifdef__NET_GENEVE_H */ #endif /*ifdef__NET_GENEVE_H */
...@@ -107,13 +107,13 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, ...@@ -107,13 +107,13 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos,
__u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
__be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
bool xnet) bool csum, bool xnet)
{ {
struct genevehdr *gnvh; struct genevehdr *gnvh;
int min_headroom; int min_headroom;
int err; int err;
skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx); skb = udp_tunnel_handle_offloads(skb, csum);
if (IS_ERR(skb)) if (IS_ERR(skb))
return PTR_ERR(skb); return PTR_ERR(skb);
...@@ -138,7 +138,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, ...@@ -138,7 +138,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
return udp_tunnel_xmit_skb(rt, skb, src, dst, return udp_tunnel_xmit_skb(rt, skb, src, dst,
tos, ttl, df, src_port, dst_port, xnet, tos, ttl, df, src_port, dst_port, xnet,
gs->sock->sk->sk_no_check_tx); !csum);
} }
EXPORT_SYMBOL_GPL(geneve_xmit_skb); EXPORT_SYMBOL_GPL(geneve_xmit_skb);
......
...@@ -212,7 +212,7 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) ...@@ -212,7 +212,7 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb)
tun_key->ipv4_dst, tun_key->ipv4_tos, tun_key->ipv4_dst, tun_key->ipv4_tos,
tun_key->ipv4_ttl, df, sport, dport, tun_key->ipv4_ttl, df, sport, dport,
tun_key->tun_flags, vni, opts_len, opts, tun_key->tun_flags, vni, opts_len, opts,
false); !!(tun_key->tun_flags & TUNNEL_CSUM), false);
if (err < 0) if (err < 0)
ip_rt_put(rt); ip_rt_put(rt);
return err; return err;
......
...@@ -74,7 +74,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb, ...@@ -74,7 +74,7 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
__be64 key; __be64 key;
__be16 flags; __be16 flags;
flags = TUNNEL_KEY; flags = TUNNEL_KEY | (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0);
vxlan_port = vxlan_vport(vport); vxlan_port = vxlan_vport(vport);
if (vxlan_port->exts & VXLAN_F_GBP) if (vxlan_port->exts & VXLAN_F_GBP)
flags |= TUNNEL_VXLAN_OPT; flags |= TUNNEL_VXLAN_OPT;
...@@ -230,6 +230,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) ...@@ -230,6 +230,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
__be16 src_port; __be16 src_port;
__be16 df; __be16 df;
int err; int err;
u32 vxflags;
if (unlikely(!OVS_CB(skb)->egress_tun_info)) { if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
err = -EINVAL; err = -EINVAL;
...@@ -251,11 +252,13 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) ...@@ -251,11 +252,13 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
src_port = udp_flow_src_port(net, skb, 0, 0, true); src_port = udp_flow_src_port(net, skb, 0, 0, true);
md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8); md.vni = htonl(be64_to_cpu(tun_key->tun_id) << 8);
md.gbp = vxlan_ext_gbp(skb); 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(rt, skb, fl.saddr, tun_key->ipv4_dst, err = vxlan_xmit_skb(rt, skb, fl.saddr, tun_key->ipv4_dst,
tun_key->ipv4_tos, tun_key->ipv4_ttl, df, tun_key->ipv4_tos, tun_key->ipv4_ttl, df,
src_port, dst_port, src_port, dst_port,
&md, false, vxlan_port->exts); &md, false, vxflags);
if (err < 0) if (err < 0)
ip_rt_put(rt); ip_rt_put(rt);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment