[dpdk-dev] [PATCH v7 1/5] eal: add rte_uuid support

Stephen Hemminger stephen at networkplumber.org
Tue May 15 06:31:50 CEST 2018


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 <sthemmin at 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



More information about the dev mailing list