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