diff options
author | Ben Pfaff <blp@ovn.org> | 2016-05-26 16:53:52 -0700 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-06-03 13:18:19 -0700 |
commit | 3d75c66007c88f886864df02b86afaa3a440088a (patch) | |
tree | cd2f61f31dcb08d9363338e413cccc2f145b0bc3 /lib | |
parent | 117d72495467efaa3eb7e7e4f7d110cd1223b967 (diff) | |
download | openvswitch-3d75c66007c88f886864df02b86afaa3a440088a.tar.gz |
netdev-native-tnl: Fix treatment of GRE key on big-endian systems.
The GRE implementation used bitwise shifts to convert an ovs_be32 to an
ovs_be64 (with zero extension), but on big-endian systems these conversions
are no-ops. This fixes the problem.
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Aaron Conole <aconole@redhat.com>
Acked-by: Gerhard Stenzel <gstenzel@linux.vnet.ibm.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/byte-order.h | 31 | ||||
-rw-r--r-- | lib/netdev-native-tnl.c | 5 |
2 files changed, 32 insertions, 4 deletions
diff --git a/lib/byte-order.h b/lib/byte-order.h index 0437d4e45..e864658f9 100644 --- a/lib/byte-order.h +++ b/lib/byte-order.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, 2011, 2013 Nicira, Inc. + * Copyright (c) 2008, 2010, 2011, 2013, 2016 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -110,4 +110,33 @@ uint32_byteswap(uint32_t crc) { (OVS_FORCE ovs_be32)((uint32_t)(B1) | (B2) << 16) #endif +/* These functions zero-extend big-endian values to longer ones, + * or truncate long big-endian value to shorter ones. */ +#ifndef __CHECKER__ +#if WORDS_BIGENDIAN +static inline ovs_be32 be16_to_be32(ovs_be16 x) { return x; } +static inline ovs_be64 be16_to_be64(ovs_be16 x) { return x; } +static inline ovs_be64 be32_to_be64(ovs_be32 x) { return x; } +static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x; } +static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x; } +static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x; } +#else /* !WORDS_BIGENDIAN */ +static inline ovs_be32 be16_to_be32(ovs_be16 x) { return (ovs_be32) x << 16; } +static inline ovs_be64 be16_to_be64(ovs_be16 x) { return (ovs_be64) x << 48; } +static inline ovs_be64 be32_to_be64(ovs_be32 x) { return (ovs_be64) x << 32; } +static inline ovs_be32 be64_to_be32(ovs_be64 x) { return x >> 32; } +static inline ovs_be16 be64_to_be16(ovs_be64 x) { return x >> 48; } +static inline ovs_be16 be32_to_be16(ovs_be32 x) { return x >> 16; } +#endif /* !WORDS_BIGENDIAN */ +#else /* __CHECKER__ */ +/* Making sparse happy with these functions also makes them unreadable, so + * don't bother to show it their implementations. */ +ovs_be32 be16_to_be32(ovs_be16); +ovs_be64 be16_to_be64(ovs_be16); +ovs_be64 be32_to_be64(ovs_be32); +ovs_be32 be64_to_be32(ovs_be64); +ovs_be16 be64_to_be16(ovs_be64); +ovs_be16 be32_to_be16(ovs_be32); +#endif + #endif /* byte-order.h */ diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c index 086496f7f..15975ade9 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -373,7 +373,7 @@ parse_gre_header(struct dp_packet *packet, } if (greh->flags & htons(GRE_KEY)) { - tnl->tun_id = (OVS_FORCE ovs_be64) ((OVS_FORCE uint64_t)(get_16aligned_be32(options)) << 32); + tnl->tun_id = be32_to_be64(get_16aligned_be32(options)); tnl->flags |= FLOW_TNL_F_KEY; options++; } @@ -457,8 +457,7 @@ netdev_gre_build_header(const struct netdev *netdev, if (tnl_cfg->out_key_present) { greh->flags |= htons(GRE_KEY); - put_16aligned_be32(options, (OVS_FORCE ovs_be32) - ((OVS_FORCE uint64_t) params->flow->tunnel.tun_id >> 32)); + put_16aligned_be32(options, be64_to_be32(params->flow->tunnel.tun_id)); options++; } |