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 <b...@ovn.org> --- lib/byte-order.h | 31 ++++++++++++++++++++++++++++++- 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 0437d4e..e864658 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 e144679..dd7e85f 100644 --- a/lib/netdev-native-tnl.c +++ b/lib/netdev-native-tnl.c @@ -387,7 +387,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++; } @@ -471,8 +471,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++; } -- 2.1.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev