Since uuid functions may not be available everywhere, implement
uuid functions in DPDK. These are based off the FreeBSD source
of libc, without the annoying DCE style function signature.

Signed-off-by: Stephen Hemminger <sthem...@microsoft.com>
---
 lib/librte_eal/bsdapp/eal/Makefile       |   1 +
 lib/librte_eal/common/Makefile           |   2 +-
 lib/librte_eal/common/eal_common_uuid.c  | 112 ++++++++++++++++++++
 lib/librte_eal/common/include/rte_uuid.h | 129 +++++++++++++++++++++++
 lib/librte_eal/common/meson.build        |   2 +
 lib/librte_eal/linuxapp/eal/Makefile     |   1 +
 6 files changed, 246 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_eal/common/eal_common_uuid.c
 create mode 100644 lib/librte_eal/common/include/rte_uuid.h

diff --git a/lib/librte_eal/bsdapp/eal/Makefile 
b/lib/librte_eal/bsdapp/eal/Makefile
index 3fd33f1e4318..13eafca61243 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -58,6 +58,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_options.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_fbarray.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += malloc_elem.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += malloc_heap.c
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 48f870f24bef..68a680bcb934 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -16,7 +16,7 @@ INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_malloc.h rte_keepalive.h rte_time.h
 INC += rte_service.h rte_service_component.h
 INC += rte_bitmap.h rte_vfio.h rte_hypervisor.h rte_test.h
-INC += rte_reciprocal.h rte_fbarray.h
+INC += rte_reciprocal.h rte_fbarray.h rte_uuid.h
 
 GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h
 GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h
diff --git a/lib/librte_eal/common/eal_common_uuid.c 
b/lib/librte_eal/common/eal_common_uuid.c
new file mode 100644
index 000000000000..1d73a5c4f33c
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_uuid.c
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * All rights reserved.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <rte_uuid.h>
+
+static void rte_uuid_create_nil(rte_uuid_t *u)
+{
+       memset(u, '\0', sizeof(*u));
+}
+
+/* A macro used to improve the readability of uuid_compare(). */
+#define DIFF_RETURN(a, b, field)       do {                    \
+       if ((a)->field != (b)->field)                           \
+               return (((a)->field < (b)->field) ? -1 : 1);    \
+} while (0)
+
+/*
+ * rte_uuid_compare() - compare two UUIDs.
+ *
+ * NOTE: Either UUID can be NULL, meaning a nil UUID. nil UUIDs are smaller
+ *      than any non-nil UUID.
+ */
+int
+rte_uuid_compare(const rte_uuid_t *a, const rte_uuid_t *b)
+{
+       /* Deal with NULL or equal pointers. */
+       if (a == b)
+               return 0;
+
+       if (a == NULL)
+               return rte_uuid_is_nil(b) ? 0 : -1;
+
+       if (b == NULL)
+               return rte_uuid_is_nil(a) ? 0 : 1;
+
+       /* We have to compare the hard way. */
+       DIFF_RETURN(a, b, time_low);
+       DIFF_RETURN(a, b, time_mid);
+       DIFF_RETURN(a, b, time_hi_and_version);
+       DIFF_RETURN(a, b, clock_seq_hi_and_reserved);
+       DIFF_RETURN(a, b, clock_seq_low);
+
+       return memcmp(a->node, b->node, sizeof(a->node));
+}
+
+int
+rte_uuid_from_string(const char *s, rte_uuid_t *u)
+{
+       int n;
+
+       /* Short-circuit 2 special cases: NULL pointer and empty string. */
+       if (s == NULL || *s == '\0') {
+               rte_uuid_create_nil(u);
+               return 0;
+       }
+
+       /* The UUID string representation has a fixed length. */
+       if (strlen(s) != 36)
+               return -1;
+
+       /*
+        * We only work with "new" UUIDs. New UUIDs have the form:
+        *      01234567-89ab-cdef-0123-456789abcdef
+        * The so called "old" UUIDs, which we don't support, have the form:
+        *      0123456789ab.cd.ef.01.23.45.67.89.ab
+        */
+       if (s[8] != '-')
+               return -1;
+
+       n = sscanf(s,
+                  "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
+                  &u->time_low, &u->time_mid, &u->time_hi_and_version,
+                  &u->clock_seq_hi_and_reserved, &u->clock_seq_low, 
&u->node[0],
+                  &u->node[1], &u->node[2], &u->node[3], &u->node[4], 
&u->node[5]);
+
+       /* Make sure we have all conversions. */
+       if (n != 11)
+               return -1;
+
+       /* We have a successful scan. Check semantics... */
+       n = u->clock_seq_hi_and_reserved;
+       if ((n & 0x80) != 0x00 &&                       /* variant 0? */
+           (n & 0xc0) != 0x80 &&                       /* variant 1? */
+           (n & 0xe0) != 0xc0) {                       /* variant 2? */
+               return -1;
+       } else {
+               return 0;
+       }
+}
+
+void
+rte_uuid_to_string(const rte_uuid_t *u, char *out, size_t len)
+{
+       static rte_uuid_t nil;
+
+       if (u == NULL)
+               u = &nil;
+
+       snprintf(out, len,
+                "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+                u->time_low, u->time_mid, u->time_hi_and_version,
+                u->clock_seq_hi_and_reserved, u->clock_seq_low, u->node[0],
+                u->node[1], u->node[2], u->node[3], u->node[4], u->node[5]);
+
+}
diff --git a/lib/librte_eal/common/include/rte_uuid.h 
b/lib/librte_eal/common/include/rte_uuid.h
new file mode 100644
index 000000000000..ba49b006d3e3
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_uuid.h
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2002,2005 Marcel Moolenaar
+ * Copyright (c) 2002 Hiten Mahesh Pandya
+ * All rights reserved.
+ */
+
+/**
+ * @file
+ *
+ * UUID related functions originally from BSD
+ */
+
+#ifndef _RTE_UUID_H_
+#define _RTE_UUID_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define RTE_UUID_NODE_LEN      6
+
+/**
+ * Struct describing a Universal Unique Identifer
+ */
+struct rte_uuid {
+       uint32_t        time_low;
+       uint16_t        time_mid;
+       uint16_t        time_hi_and_version;
+       uint8_t         clock_seq_hi_and_reserved;
+       uint8_t         clock_seq_low;
+       uint8_t         node[RTE_UUID_NODE_LEN];
+};
+typedef struct rte_uuid rte_uuid_t;
+
+/**
+ * Helper for defining UUID values for id tables.
+ */
+#define RTE_UUID_INIT(a, b, c, d, e) {                                 \
+               .time_low = (a),                                        \
+               .time_mid = (b),                                \
+               .clock_seq_hi_and_reserved = ((d) >> 8 & 0xff), \
+               .clock_seq_low = (d) & 0xff, \
+               .node = { (e) >> 24 & 0xff, (e) >> 16 & 0xff,   \
+                         (e) >> 8 & 0xff,  (e) & 0xff }        \
+       }
+
+/**
+ * Test if UUID is all zeros.
+ *
+ * @param u
+ *    The uuid to check.
+ * @return
+ *    true if uuid is NULL value, false otherwise
+ */
+static inline bool rte_uuid_is_nil(const rte_uuid_t *u)
+{
+       const uint32_t *p;
+
+       if (!u)
+               return true;
+
+       /*
+        * Pick the largest type that has equivalent alignment constraints
+        * as an UUID and use it to test if the UUID consists of all zeroes.
+        */
+       p = (const uint32_t *)u;
+       return (p[0] | p[1] | p[2] | p[3]) == 0;
+}
+
+/**
+ * Copy a UUID
+ *
+ * @param dst
+ *   Pointer to the destination UUID
+ * @param src
+ *   Pointer to the source UUID
+ */
+static inline void rte_uuid_copy(rte_uuid_t *dst, const rte_uuid_t *src)
+{
+       *dst = *src;
+}
+
+/**
+ * Compare two UUID's
+ *
+ * @param a
+ *    Pointer to a UUID to compare
+ * @param b
+ *    Pointer to a UUID to compare
+ * @return
+ *   returns an integer less than, equal to, or greater than zero if UUID a is
+ *   is less than, equal, or greater than UUID b.
+ */
+int    rte_uuid_compare(const rte_uuid_t *a, const rte_uuid_t *b);
+
+/**
+ * Extract UUID from string
+ *
+ * @param in
+ *    Pointer to string of characters to convert
+ * @param string
+ *    Destination UUID
+ * @return
+ *    Returns 0 on succes, and -1 if string is not a valid UUID.
+ */
+int    rte_uuid_from_string(const char *in, rte_uuid_t *dst);
+
+/**
+ * Convert UUID to string
+ *
+ * @param u
+ *    Pointer to UUID to format
+ * @param out
+ *    Resulting string buffer
+ * @param len
+ *    Sizeof the available string buffer
+ */
+#define RTE_UUID_STRLEN        (36 + 1)
+void   rte_uuid_to_string(const rte_uuid_t *u, char *out, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_UUID_H */
diff --git a/lib/librte_eal/common/meson.build 
b/lib/librte_eal/common/meson.build
index 8a3dcfee091b..e184e4d7413d 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -25,6 +25,7 @@ common_sources = files(
        'eal_common_tailqs.c',
        'eal_common_thread.c',
        'eal_common_timer.c',
+       'eal_common_uuid.c',
        'malloc_elem.c',
        'malloc_heap.c',
        'malloc_mp.c',
@@ -75,6 +76,7 @@ common_headers = files(
        'include/rte_string_fns.h',
        'include/rte_tailq.h',
        'include/rte_time.h',
+       'include/rte_uuid.h',
        'include/rte_version.h')
 
 # special case install the generic headers, since they go in a subdir
diff --git a/lib/librte_eal/linuxapp/eal/Makefile 
b/lib/librte_eal/linuxapp/eal/Makefile
index 3719ec9d7d53..927a80fec907 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -66,6 +66,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_options.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_proc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_fbarray.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_uuid.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += rte_malloc.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += malloc_elem.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += malloc_heap.c
-- 
2.17.0

Reply via email to