From 2d5285e1dfab3d67dd20578b65afc2c4ef6065e9 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Sun, 6 Nov 2011 23:37:21 -0800 Subject: [PATCH] datapath: Properly calculate checksum when updating TOS field. 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 Acked-by: Jesse Gross --- datapath/actions.c | 3 +-- datapath/linux/compat/include/net/checksum.h | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/datapath/actions.c b/datapath/actions.c index b5b92ba8f..afd179140 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -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; } diff --git a/datapath/linux/compat/include/net/checksum.h b/datapath/linux/compat/include/net/checksum.h index 73f2f5992..ee64f24d5 100644 --- a/datapath/linux/compat/include/net/checksum.h +++ b/datapath/linux/compat/include/net/checksum.h @@ -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) -- 2.20.1