DPDK patches and discussions
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
	Stephen Hemminger <sthemmin@microsoft.com>
Subject: [dpdk-dev] [PATCH v7 1/5] eal: add rte_uuid support
Date: Mon, 14 May 2018 21:31:50 -0700	[thread overview]
Message-ID: <20180515043154.19239-2-stephen@networkplumber.org> (raw)
In-Reply-To: <20180515043154.19239-1-stephen@networkplumber.org>

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@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	other threads:[~2018-05-15  4:32 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-15  4:31 [dpdk-dev] [PATCH v7 0/5] Hyper-V netvsc PMD and VMBus support Stephen Hemminger
2018-05-15  4:31 ` Stephen Hemminger [this message]
2018-05-15  4:31 ` [dpdk-dev] [PATCH v7 2/5] bus/vmbus: add hyper-v virtual bus support Stephen Hemminger
2018-05-15  4:31 ` [dpdk-dev] [PATCH v7 3/5] net/netvsc: add hyper-v netvsc network device Stephen Hemminger
2018-05-15  4:31 ` [dpdk-dev] [PATCH v7 4/5] net/netvsc: add documentation Stephen Hemminger
2018-05-15  4:31 ` [dpdk-dev] [PATCH v7 5/5] bus/vmbus and net/netvsc: add meson build support Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180515043154.19239-2-stephen@networkplumber.org \
    --to=stephen@networkplumber.org \
    --cc=dev@dpdk.org \
    --cc=sthemmin@microsoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).