datapath: Properly calculate checksum when updating TOS field.
authorJustin Pettit <jpettit@nicira.com>
Mon, 7 Nov 2011 07:37:21 +0000 (23:37 -0800)
committerJustin Pettit <jpettit@nicira.com>
Wed, 9 Nov 2011 06:37:11 +0000 (22:37 -0800)
When updating the IP TOS field, the checksum was not properly calculated
on little endian systems.  This commit fixes the issue.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
datapath/actions.c
datapath/linux/compat/include/net/checksum.h

index b5b92ba8f5b5389882bc6a9d143feb74df71ef85..afd17914024bbba91575edf9bf047ec2f486d4e9 100644 (file)
@@ -158,8 +158,7 @@ static void set_ip_tos(struct sk_buff *skb, struct iphdr *nh, u8 new_tos)
        /* Set the DSCP bits and preserve the ECN bits. */
        old = nh->tos;
        new = new_tos | (nh->tos & INET_ECN_MASK);
-       csum_replace4(&nh->check, (__force __be32)old,
-                                 (__force __be32)new);
+       csum_replace2(&nh->check, htons(old), htons(new));
        nh->tos = new;
 }
 
index 73f2f5992dbeb93713a8098324e1ff48f937eda8..ee64f24d570e27a59cdf6bdc39375d54972992a6 100644 (file)
@@ -25,6 +25,11 @@ static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
 
        *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum_unfold(*sum)));
 }
+
+static inline void csum_replace2(__sum16 *sum, __be16 from, __be16 to)
+{
+       csum_replace4(sum, (__force __be32)from, (__force __be32)to);
+}
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)