aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Gross <jesse@nicira.com>2015-01-28 19:32:46 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-29 02:04:15 -0500
commitb8693877ae016ac525d674d5d7a84ea0ea68ba60 (patch)
tree7ab9067c1c28bc829336a8d95736303f69d0bdea
parentb8f8be3f043d6dba7d6c3426e4597d2ebf5a3547 (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>
-rw-r--r--include/net/geneve.h2
-rw-r--r--net/ipv4/geneve.c6
-rw-r--r--net/openvswitch/vport-geneve.c2
-rw-r--r--net/openvswitch/vport-vxlan.c7
4 files changed, 10 insertions, 7 deletions
diff --git a/include/net/geneve.h b/include/net/geneve.h
index 03aa2adb5bab..14fb8d3390b4 100644
--- a/include/net/geneve.h
+++ b/include/net/geneve.h
@@ -90,7 +90,7 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
90 struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, 90 struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos,
91 __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port, 91 __u8 ttl, __be16 df, __be16 src_port, __be16 dst_port,
92 __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt, 92 __be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
93 bool xnet); 93 bool csum, bool xnet);
94#endif /*ifdef CONFIG_INET */ 94#endif /*ifdef CONFIG_INET */
95 95
96#endif /*ifdef__NET_GENEVE_H */ 96#endif /*ifdef__NET_GENEVE_H */
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}
143EXPORT_SYMBOL_GPL(geneve_xmit_skb); 143EXPORT_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;