[ovs-dev] [PATCH 2/5] netdev-native-tnl: Fix treatment of GRE key on big-endian systems.
Ben Pfaff
blp at ovn.org
Fri May 27 00:17:38 UTC 2016
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 at 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
More information about the dev
mailing list