types: Add big-endian 128-bit types and helpers.
authorJoe Stringer <joestringer@nicira.com>
Wed, 23 Sep 2015 06:24:11 +0000 (23:24 -0700)
committerJoe Stringer <joestringer@nicira.com>
Tue, 13 Oct 2015 22:34:14 +0000 (15:34 -0700)
These types will be used by the following patches to ensure a consistent
wire format for 128-bit connection tracking labels. Common functions for
comparison, endian translation, etc. are provided.

Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
include/openvswitch/types.h
lib/byte-order.h
lib/meta-flow.h
lib/util.h

index c138b9c..64d9012 100644 (file)
@@ -84,10 +84,24 @@ typedef struct {
 typedef union {
     uint32_t u32[4];
     struct {
+#ifdef WORDS_BIGENDIAN
+        uint64_t hi, lo;
+#else
         uint64_t lo, hi;
+#endif
     } u64;
 } ovs_u128;
 
+typedef union {
+    ovs_be32 be32[4];
+    struct {
+        ovs_be64 hi, lo;
+    } be64;
+} ovs_be128;
+
+#define OVS_U128_MAX (ovs_u128) { .u64 = { UINT64_MAX, UINT64_MAX } }
+#define OVS_BE128_MAX (ovs_be128) { .be64 = { OVS_BE64_MAX, OVS_BE64_MAX } }
+
 /* A 64-bit value, in network byte order, that is only aligned on a 32-bit
  * boundary. */
 typedef struct {
index 544f46f..3f60698 100644 (file)
@@ -42,6 +42,20 @@ ovs_be64 htonll(uint64_t);
 uint64_t ntohll(ovs_be64);
 #endif
 
+static inline void
+hton128(const ovs_u128 *src, ovs_be128 *dst)
+{
+    dst->be64.hi = htonll(src->u64.hi);
+    dst->be64.lo = htonll(src->u64.lo);
+}
+
+static inline void
+ntoh128(const ovs_be128 *src, ovs_u128 *dst)
+{
+    dst->u64.hi = ntohll(src->be64.hi);
+    dst->u64.lo = ntohll(src->be64.lo);
+}
+
 static inline uint32_t
 uint32_byteswap(uint32_t crc) {
     return (((crc & 0x000000ff) << 24) |
index 920093f..cb441ce 100644 (file)
@@ -1742,6 +1742,7 @@ union mf_value {
     uint8_t tun_metadata[128];
     struct in6_addr ipv6;
     struct eth_addr mac;
+    ovs_be128 be128;
     ovs_be64 be64;
     ovs_be32 be32;
     ovs_be16 be16;
index 4186d49..340ef65 100644 (file)
@@ -563,6 +563,36 @@ ovs_u128_equals(const ovs_u128 *a, const ovs_u128 *b)
     return (a->u64.hi == b->u64.hi) && (a->u64.lo == b->u64.lo);
 }
 
+/* Returns true if 'val' is 0. */
+static inline bool
+ovs_u128_is_zero(const ovs_u128 *val)
+{
+    return !(val->u64.hi || val->u64.lo);
+}
+
+/* Returns true if 'val' is all ones. */
+static inline bool
+ovs_u128_is_ones(const ovs_u128 *val)
+{
+    ovs_u128 ones = OVS_U128_MAX;
+
+    return ovs_u128_equals(val, &ones);
+}
+
+/* Returns non-zero if the parameters have equal value. */
+static inline int
+ovs_be128_equals(const ovs_be128 *a, const ovs_be128 *b)
+{
+    return (a->be64.hi == b->be64.hi) && (a->be64.lo == b->be64.lo);
+}
+
+/* Returns true if 'val' is 0. */
+static inline bool
+ovs_be128_is_zero(const ovs_be128 *val)
+{
+    return !(val->be64.hi || val->be64.lo);
+}
+
 void xsleep(unsigned int seconds);
 
 #ifdef _WIN32