diff options
| author | Jesse Gross <jesse@nicira.com> | 2010-12-06 18:03:37 -0800 |
|---|---|---|
| committer | Jesse Gross <jesse@nicira.com> | 2010-12-09 17:43:36 -0800 |
| commit | e7d737d175dfe53436b356445ecb154541d2afff (patch) | |
| tree | bf13c9127526ab579027bc46d93f3751063593c2 /datapath/checksum.h | |
| parent | 2986c21ea17a4f31ce153dea12d1f39d05ae5996 (diff) | |
| download | openvswitch-e7d737d175dfe53436b356445ecb154541d2afff.tar.gz | |
datapath: Try to avoid custom checksum update function.
Our update_csum() function was exactly the same as
inet_proto_csum_replace4() with the one exception that it uses our
checksum status fields on older kernels that need it. Unfortunately,
we can't completely move the code to the compat directory because it
relies on fields in OVS CB but we can at least exile it to checksum.h.
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath/checksum.h')
| -rw-r--r-- | datapath/checksum.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/datapath/checksum.h b/datapath/checksum.h index bf931798a..7d653961e 100644 --- a/datapath/checksum.h +++ b/datapath/checksum.h @@ -12,6 +12,8 @@ #include <linux/skbuff.h> #include <linux/version.h> +#include <net/checksum.h> + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) || \ (defined(CONFIG_XEN) && defined(HAVE_PROTO_DATA_VALID)) #define NEED_CSUM_NORMALIZE @@ -100,4 +102,27 @@ static inline void set_skb_csum_pointers(struct sk_buff *skb, u16 csum_start, #endif } +#if defined(NEED_CSUM_NORMALIZE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) +/* This is really compatibility code that belongs in the compat directory. + * However, it needs access to our normalized checksum values, so put it here. + */ +#define inet_proto_csum_replace4 rpl_inet_proto_csum_replace4 +static inline void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, + __be32 from, __be32 to, + int pseudohdr) +{ + __be32 diff[] = { ~from, to }; + + if (get_ip_summed(skb) != OVS_CSUM_PARTIAL) { + *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), + ~csum_unfold(*sum))); + if (get_ip_summed(skb) == OVS_CSUM_COMPLETE && pseudohdr) + skb->csum = ~csum_partial((char *)diff, sizeof(diff), + ~skb->csum); + } else if (pseudohdr) + *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff), + csum_unfold(*sum))); +} +#endif + #endif /* checksum.h */ |
