From: Pravin B Shelar Date: Tue, 26 Jul 2016 00:49:53 +0000 (-0700) Subject: datapath: compat: fix udp checksum calculation X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=c77d947191b0ad86aa590f9327677bd2492e44e8 datapath: compat: fix udp checksum calculation 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 Acked-by: Jesse Gross --- diff --git a/acinclude.m4 b/acinclude.m4 index 5f38539c1..3f31e5f0e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -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]) diff --git a/datapath/linux/compat/include/net/udp.h b/datapath/linux/compat/include/net/udp.h index fa49fa573..266e70a34 100644 --- a/datapath/linux/compat/include/net/udp.h +++ b/datapath/linux/compat/include/net/udp.h @@ -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); diff --git a/datapath/linux/compat/udp.c b/datapath/linux/compat/udp.c index f0362b64d..4cd22fa6d 100644 --- a/datapath/linux/compat/udp.c +++ b/datapath/linux/compat/udp.c @@ -1,6 +1,6 @@ #include -#ifndef HAVE_UDP_SET_CSUM +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) #include @@ -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; diff --git a/datapath/linux/compat/udp_tunnel.c b/datapath/linux/compat/udp_tunnel.c index 9265c8a99..9cf728630 100644 --- a/datapath/linux/compat/udp_tunnel.c +++ b/datapath/linux/compat/udp_tunnel.c @@ -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;