[ovs-dev,PATCHv4,03/11] types: Add big-endian 128-bit types and helpers.
diff mbox

Message ID 1443820578-9287-4-git-send-email-joestringer@nicira.com
State Accepted
Headers show

Commit Message

Joe Stringer Oct. 2, 2015, 9:16 p.m. UTC
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>
---
v4: Reorder u128 elements rather than swapping in {ntoh,hton}128().
    Add OVS_*128_MAX constants
    Add is_ones() function.
---
 include/openvswitch/types.h | 14 ++++++++++++++
 lib/byte-order.h            | 14 ++++++++++++++
 lib/meta-flow.h             |  1 +
 lib/util.h                  | 30 ++++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+)

Comments

Ben Pfaff Oct. 5, 2015, 10:28 p.m. UTC | #1
On Fri, Oct 02, 2015 at 02:16:10PM -0700, Joe Stringer wrote:
> 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>
> ---
> v4: Reorder u128 elements rather than swapping in {ntoh,hton}128().
>     Add OVS_*128_MAX constants
>     Add is_ones() function.

Thanks!

Acked-by: Ben Pfaff <blp@nicira.com>

Patch
diff mbox

diff --git a/include/openvswitch/types.h b/include/openvswitch/types.h
index c138b9c..64d9012 100644
--- a/include/openvswitch/types.h
+++ b/include/openvswitch/types.h
@@ -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 {
diff --git a/lib/byte-order.h b/lib/byte-order.h
index 544f46f..3f60698 100644
--- a/lib/byte-order.h
+++ b/lib/byte-order.h
@@ -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) |
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 02272ef..f9379f9 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -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;
diff --git a/lib/util.h b/lib/util.h
index 4186d49..340ef65 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -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