Signed-off-by: Joe Stringer <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev