datapath: compat: fix udp checksum calculation
authorPravin B Shelar <pshelar@ovn.org>
Tue, 26 Jul 2016 00:49:53 +0000 (17:49 -0700)
committerPravin B Shelar <pshelar@ovn.org>
Tue, 26 Jul 2016 23:55:27 +0000 (16:55 -0700)
In upstream linux kernel networking stack udp_set_csum() is called
with only udp header applied but in case of compat layer it can
be called with IP header. So following patch take the offset into
account.

Signed-off-by: Pravin B Shelar <pshelar@ovn.org>
Acked-by: Jesse Gross <jesse@kernel.org>
acinclude.m4
datapath/linux/compat/include/net/udp.h
datapath/linux/compat/udp.c
datapath/linux/compat/udp_tunnel.c

index 5f38539..3f31e5f 100644 (file)
@@ -639,7 +639,6 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
                   [OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [inet_get_local_port_range(net],
                                    [OVS_DEFINE([HAVE_UDP_FLOW_SRC_PORT])])])
   OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [udp_v4_check])
-  OVS_GREP_IFELSE([$KSRC/include/net/udp.h], [udp_set_csum])
   OVS_GREP_IFELSE([$KSRC/include/net/udp_tunnel.h], [udp_tunnel_gro_complete])
   OVS_FIND_FIELD_IFELSE([$KSRC/include/net/udp_tunnel.h], [udp_tunnel_sock_cfg],
                         [gro_receive])
index fa49fa5..266e70a 100644 (file)
@@ -54,7 +54,7 @@ static inline __sum16 udp_v4_check(int len, __be32 saddr,
 }
 #endif
 
-#ifndef HAVE_UDP_SET_CSUM
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
 #define udp_set_csum rpl_udp_set_csum
 void rpl_udp_set_csum(bool nocheck, struct sk_buff *skb,
                      __be32 saddr, __be32 daddr, int len);
index f0362b6..4cd22fa 100644 (file)
@@ -1,6 +1,6 @@
 #include <linux/version.h>
 
-#ifndef HAVE_UDP_SET_CSUM
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0)
 
 #include <net/udp.h>
 
@@ -26,12 +26,13 @@ void rpl_udp_set_csum(bool nocheck, struct sk_buff *skb,
                skb->csum_offset = offsetof(struct udphdr, check);
                uh->check = ~udp_v4_check(len, saddr, daddr, 0);
        } else {
+               int l4_offset = skb_transport_offset(skb);
                __wsum csum;
 
                BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
 
                uh->check = 0;
-               csum = skb_checksum(skb, 0, len, 0);
+               csum = skb_checksum(skb, l4_offset, len, 0);
                uh->check = udp_v4_check(len, saddr, daddr, csum);
                if (uh->check == 0)
                        uh->check = CSUM_MANGLED_0;
index 9265c8a..9cf7286 100644 (file)
@@ -203,12 +203,13 @@ static void udp6_set_csum(bool nocheck, struct sk_buff *skb,
                skb->csum_offset = offsetof(struct udphdr, check);
                uh->check = ~udp_v6_check(len, saddr, daddr, 0);
        } else {
+               int l4_offset = skb_transport_offset(skb);
                __wsum csum;
 
                BUG_ON(skb->ip_summed == CHECKSUM_PARTIAL);
 
                uh->check = 0;
-               csum = skb_checksum(skb, 0, len, 0);
+               csum = skb_checksum(skb, l4_offset, len, 0);
                uh->check = udp_v6_check(len, saddr, daddr, csum);
                if (uh->check == 0)
                        uh->check = CSUM_MANGLED_0;