Signed-off-by: Joe Stringer <joestrin...@nicira.com>
---
 include/openvswitch/types.h |    7 ------
 lib/odp-util.c              |   50 +++++++++++++++++++++++++++++++++++--------
 lib/util.h                  |   17 +++++++++++++++
 tests/test-hash.c           |   10 ++++-----
 4 files changed, 62 insertions(+), 22 deletions(-)

diff --git a/include/openvswitch/types.h b/include/openvswitch/types.h
index 2afb7b7..629a3e5 100644
--- a/include/openvswitch/types.h
+++ b/include/openvswitch/types.h
@@ -88,13 +88,6 @@ typedef union {
     } u64;
 } ovs_u128;
 
-/* Returns non-zero if the parameters have equal value. */
-static inline int
-ovs_u128_equal(const ovs_u128 *a, const ovs_u128 *b)
-{
-    return (a->u64.hi == b->u64.hi) && (a->u64.lo == b->u64.lo);
-}
-
 /* A 64-bit value, in network byte order, that is only aligned on a 32-bit
  * boundary. */
 typedef struct {
diff --git a/lib/odp-util.c b/lib/odp-util.c
index b82edb7..147b1e7 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -57,6 +57,8 @@ static void format_odp_key_attr(const struct nlattr *a,
                                 const struct nlattr *ma,
                                 const struct hmap *portno_names, struct ds *ds,
                                 bool verbose);
+static void odp_format_u128(struct ds *ds, const ovs_u128 *value,
+                            const ovs_u128 *mask, bool verbose);
 
 /* Returns one the following for the action with the given OVS_ACTION_ATTR_*
  * 'type':
@@ -2063,28 +2065,46 @@ generate_all_wildcard_mask(struct ofpbuf *ofp, const 
struct nlattr *key)
     return ofp->base;
 }
 
+static int
+scan_u128(const char *s, ovs_u128 *key, ovs_u128 *mask)
+{
+    int n;
+
+    if (ovs_scan(s, U128_SCAN_FMT"%n", U128_SCAN_ARGS(key), &n)) {
+        int len = n;
+
+        if (mask) {
+            if (ovs_scan(s, "/"U128_SCAN_FMT"%n", U128_SCAN_ARGS(mask), &n)) {
+                len += n;
+            } else {
+                mask->u64.hi = mask->u64.lo = UINT64_MAX;
+            }
+        }
+
+        return len;
+    }
+
+    return 0;
+}
+
 int
 odp_ufid_from_string(const char *s_, ovs_u128 *ufid)
 {
     const char *s = s_;
 
     if (ovs_scan(s, "ufid:")) {
-        size_t n;
+        int n;
 
         s += 5;
         if (ovs_scan(s, "0x")) {
             s += 2;
         }
 
-        n = strspn(s, "0123456789abcdefABCDEF");
-        if (n != 32) {
+        n = scan_u128(s, ufid, NULL);
+        if (!n) {
             return -EINVAL;
         }
 
-        if (!ovs_scan(s, "%16"SCNx64"%16"SCNx64, &ufid->u64.hi,
-                      &ufid->u64.lo)) {
-            return -EINVAL;
-        }
         s += n;
         s += strspn(s, delimiters);
 
@@ -2094,11 +2114,23 @@ odp_ufid_from_string(const char *s_, ovs_u128 *ufid)
     return 0;
 }
 
+static void
+odp_format_u128(struct ds *ds, const ovs_u128 *value, const ovs_u128 *mask,
+                bool verbose)
+{
+    if (verbose || (mask && ovs_u128_nonzero(*mask))) {
+        ds_put_format(ds, U128_FMT, U128_ARGS(value));
+        if (mask && !is_all_ones(mask, sizeof(*mask))) {
+            ds_put_format(ds, "/"U128_FMT, U128_ARGS(mask));
+        }
+    }
+}
+
 void
 odp_format_ufid(const ovs_u128 *ufid, struct ds *ds)
 {
-    ds_put_format(ds, "ufid:%016"PRIx64"%016"PRIx64, ufid->u64.hi,
-                  ufid->u64.lo);
+    ds_put_format(ds, "ufid:");
+    odp_format_u128(ds, ufid, NULL, true);
 }
 
 /* Appends to 'ds' a string representation of the 'key_len' bytes of
diff --git a/lib/util.h b/lib/util.h
index 276edb5..34e47ab 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -550,6 +550,23 @@ uint64_t bitwise_get(const void *src, unsigned int src_len,
 
 void xsleep(unsigned int seconds);
 
+#define U128_FMT                 "%016"PRIx64"%016"PRIx64
+#define U128_ARGS(cl)            (cl)->u64.hi, (cl)->u64.lo
+#define U128_SCAN_FMT            "%016"SCNx64"%016"SCNx64
+#define U128_SCAN_ARGS(cl)       &(cl)->u64.hi, &(cl)->u64.lo
+
+/* Returns non-zero if the parameters have equal value. */
+static inline int
+ovs_u128_equal(const ovs_u128 *a, const ovs_u128 *b)
+{
+    return (a->u64.hi == b->u64.hi) && (a->u64.lo == b->u64.lo);
+}
+
+static inline int ovs_u128_nonzero(ovs_u128 a)
+{
+    return !is_all_zeros(&a, sizeof(a));
+}
+
 #ifdef _WIN32
 
 char *ovs_format_message(int error);
diff --git a/tests/test-hash.c b/tests/test-hash.c
index 8352156..a5f8d34 100644
--- a/tests/test-hash.c
+++ b/tests/test-hash.c
@@ -216,8 +216,8 @@ check_256byte_hash(void (*hash)(const void *, size_t, 
uint32_t, ovs_u128 *),
         hash(in1, sizeof(ovs_u128) * 16, 0, &out1);
         if (!ovs_u128_equal(&out0, &out1)) {
             printf("%s hash not the same for non-64 aligned data "
-                   "%016"PRIx64"%016"PRIx64" != %016"PRIx64"%016"PRIx64"\n",
-                   name, out0.u64.lo, out0.u64.hi, out1.u64.lo, out1.u64.hi);
+                   U128_FMT" != "U128_FMT"\n", name, U128_ARGS(&out0),
+                   U128_ARGS(&out1));
         }
 
         for (j = i + 1; j <= n_bits; j++) {
@@ -228,10 +228,8 @@ check_256byte_hash(void (*hash)(const void *, size_t, 
uint32_t, ovs_u128 *),
             hash(in2, sizeof(ovs_u128) * 16, 0, &out2);
             if ((out1.u64.lo & unique_mask) == (out2.u64.lo & unique_mask)) {
                 printf("%s has a partial collision:\n", name);
-                printf("hash(1 << %4d) == %016"PRIx64"%016"PRIx64"\n", i,
-                       out1.u64.hi, out1.u64.lo);
-                printf("hash(1 << %4d) == %016"PRIx64"%016"PRIx64"\n", j,
-                       out2.u64.hi, out2.u64.lo);
+                printf("hash(1 << %4d) == "U128_FMT"\n", i, U128_ARGS(&out1));
+                printf("hash(1 << %4d) == "U128_FMT"\n", j, U128_ARGS(&out2));
                 printf("The low-order %d bits of output are both "
                        "0x%"PRIx64"\n", min_unique, out1.u64.lo & unique_mask);
             }
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to