Add types and accessors for working with half-aligned 64-bit values.
authorBen Pfaff <blp@nicira.com>
Sat, 5 Feb 2011 21:14:47 +0000 (13:14 -0800)
committerBen Pfaff <blp@nicira.com>
Sat, 5 Feb 2011 21:14:47 +0000 (13:14 -0800)
Both OpenFlow and Netlink contain 64-bit fields that are only guaranteed
to be aligned on 32-bit boundaries.  This commit introduces types for
representing these fields and functions for working with them.  Followup
commits will make the OpenFlow and Netlink code use these types and
functions.

include/openvswitch/types.h
lib/unaligned.h

index fbd2997..9ddb857 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Nicira Networks.
+ * Copyright (c) 2010, 2011 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
 #ifndef OPENVSWITCH_TYPES_H
 #define OPENVSWITCH_TYPES_H 1
 
+#include <arpa/inet.h>
+#include <sys/types.h>
 #include <stdint.h>
 
 #ifdef __CHECKER__
 typedef uint16_t OVS_BITWISE ovs_be16;
 typedef uint32_t OVS_BITWISE ovs_be32;
 typedef uint64_t OVS_BITWISE ovs_be64;
+\f
+/* Netlink and OpenFlow both contain 64-bit values that are only guaranteed to
+ * be aligned on 32-bit boundaries.  These types help.
+ *
+ * lib/unaligned.h has helper functions for accessing these. */
+
+/* A 64-bit value, in host byte order, that is only aligned on a 32-bit
+ * boundary.  */
+typedef struct {
+#ifdef WORDS_BIGENDIAN
+       uint32_t hi, lo;
+#else
+       uint32_t lo, hi;
+#endif
+} ovs_32aligned_u64;
+
+/* A 64-bit value, in network byte order, that is only aligned on a 32-bit
+ * boundary. */
+typedef struct {
+       ovs_be32 hi, lo;
+} ovs_32aligned_be64;
 
 #endif /* openvswitch/types.h */
index ef08f4e..a44ee8b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Nicira Networks.
+ * Copyright (c) 2010, 2011 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -140,5 +140,44 @@ static inline void put_unaligned_u64(uint64_t *p_, uint64_t x_)
 #define put_unaligned_be32 put_unaligned_u32
 #define put_unaligned_be64 put_unaligned_u64
 #endif
+\f
+/* Returns the value in 'x'. */
+static inline uint64_t
+get_32aligned_u64(const ovs_32aligned_u64 *x)
+{
+       return ((uint64_t) x->hi << 32) | x->lo;
+}
+
+/* Stores 'value' in 'x'. */
+static inline void
+put_32aligned_u64(ovs_32aligned_u64 *x, uint64_t value)
+{
+       x->hi = value >> 32;
+       x->lo = value;
+}
+
+/* Returns the value of 'x'. */
+static inline ovs_be64
+get_32aligned_be64(const ovs_32aligned_be64 *x)
+{
+#ifdef WORDS_BIGENDIAN
+       return ((ovs_be64) x->hi << 32) | x->lo;
+#else
+       return ((ovs_be64) x->lo << 32) | x->hi;
+#endif
+}
+
+/* Stores network byte order 'value' into 'x'. */
+static inline void
+put_32aligned_be64(ovs_32aligned_be64 *x, ovs_be64 value)
+{
+#if WORDS_BIGENDIAN
+       x->hi = value >> 32;
+       x->lo = value;
+#else
+    x->hi = value;
+    x->lo = value >> 32;
+#endif
+}
 
 #endif /* unaligned.h */