[1/2] eal: add functions to generate uuid values

Message ID 20240403163432.437275-2-stephen@networkplumber.org (mailing list archive)
State Superseded
Delegated to: Thomas Monjalon
Headers
Series uuid: enhancements and tests |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Stephen Hemminger April 3, 2024, 4:32 p.m. UTC
  Useful to be able to generate uuid values for tests or
for interaction with other subsystems as magic cookie.
Naming and overall algorithm come from libuuid which is used
by permission of original author.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/eal/common/eal_common_uuid.c | 56 ++++++++++++++++++++++++++++++++
 lib/eal/include/rte_uuid.h       | 22 ++++++++++++-
 lib/eal/version.map              |  2 ++
 3 files changed, 79 insertions(+), 1 deletion(-)
  

Comments

Tyler Retzlaff April 4, 2024, 4:11 p.m. UTC | #1
On Wed, Apr 03, 2024 at 09:32:29AM -0700, Stephen Hemminger wrote:
> Useful to be able to generate uuid values for tests or
> for interaction with other subsystems as magic cookie.
> Naming and overall algorithm come from libuuid which is used
> by permission of original author.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  lib/eal/common/eal_common_uuid.c | 56 ++++++++++++++++++++++++++++++++
>  lib/eal/include/rte_uuid.h       | 22 ++++++++++++-
>  lib/eal/version.map              |  2 ++
>  3 files changed, 79 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/eal/common/eal_common_uuid.c b/lib/eal/common/eal_common_uuid.c
> index 0a80bfbb38..fc8f58e8a4 100644
> --- a/lib/eal/common/eal_common_uuid.c
> +++ b/lib/eal/common/eal_common_uuid.c
> @@ -7,7 +7,12 @@
>  #include <stdint.h>
>  #include <stdlib.h>
>  #include <ctype.h>
> +#include <time.h>
>  
> +#include <rte_atomic.h>

i guess this should be rte_stdatomic.h

> +#include <rte_common.h>
> +#include <rte_random.h>
> +#include <rte_time.h>
>  #include <rte_uuid.h>
>  
>  /* UUID packed form */
> @@ -165,3 +170,54 @@ void rte_uuid_unparse(const rte_uuid_t uu, char *out, size_t len)
>  		uuid.node[0], uuid.node[1], uuid.node[2],
>  		uuid.node[3], uuid.node[4], uuid.node[5]);
>  }
> +
> +void rte_uuid_generate_random(rte_uuid_t out)
> +{
> +	union {
> +		uint64_t words[2];
> +		rte_uuid_t uuid;
> +	} buf;
> +	struct uuid uu;
> +
> +	/* UUID is 128 bit */
> +	buf.words[0] = rte_rand();
> +	buf.words[1] = rte_rand();
> +
> +	/* Mark these random bytes a version 4 random uuid */
> +	uuid_unpack(buf.uuid, &uu);
> +	uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
> +	uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
> +	uuid_pack(&uu, out);
> +}
> +
> +void rte_uuid_generate_time(rte_uuid_t out)
> +{
> +	struct uuid uu;
> +	struct timespec ts;
> +	uint64_t ns, rnd;
> +	static uint16_t sequence;

sequence will need to be RTE_ATOMIC(uint16_t) if you build with clang
and you -Denable_stdatomic=true clang enforces the use of atomic types
and build would have failed at the rte_atomic_fetch_add_explicit below.

the CI probably already told you this.

> +
> +	/* The time value for UUID is 100ns since 15 October 1582 */
> +	clock_gettime(CLOCK_REALTIME, &ts);
> +
> +	ns = ts.tv_nsec / 100;
> +	ns += (uint64_t) ts.tv_sec * (NSEC_PER_SEC / 100);
> +	ns += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
> +
> +	uu.time_low = (uint32_t) ns;
> +	uu.time_mid = (uint16_t) (ns >> 32);
> +	uu.time_hi_and_version = (uint16_t) (ns >> 48);
> +	uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
> +	uu.clock_seq = rte_atomic_fetch_add_explicit(&sequence, 1,
> +						     rte_memory_order_relaxed);
> +
> +	rnd = rte_rand();
> +	memcpy(uu.node, &rnd, 6);
> +	/*
> +	 * What libuuid does set multicast bit.
> +	 * This avoids conflicts with network cards.
> +	 */
> +	uu.node[0] |= 0x1;
> +
> +	uuid_pack(&uu, out);
> +}
> diff --git a/lib/eal/include/rte_uuid.h b/lib/eal/include/rte_uuid.h
> index cfefd4308a..052b78a812 100644
> --- a/lib/eal/include/rte_uuid.h
> +++ b/lib/eal/include/rte_uuid.h
> @@ -18,6 +18,8 @@ extern "C" {
>  #include <stddef.h>
>  #include <string.h>
>  
> +#include <rte_compat.h>
> +
>  /**
>   * Struct describing a Universal Unique Identifier
>   */
> @@ -94,12 +96,30 @@ int	rte_uuid_parse(const char *in, rte_uuid_t uu);
>   * @param uu
>   *    UUID to format
>   * @param out
> - *    Resulting string buffer
> + *    Resulting string bufferm

buffer -> bufferm intentional?

>   * @param len
>   *    Sizeof the available string buffer
>   */
>  void	rte_uuid_unparse(const rte_uuid_t uu, char *out, size_t len);
>  
> +/**
> + * Generate a random uuid
> + *
> + * @param uu
> + *   Resulting UUID
> + */
> +__rte_experimental
> +void   rte_uuid_generate_random(rte_uuid_t uu);
> +
> +/**
> + * Generate a uuid based on time stamp.
> + *
> + * @param uu
> + *   Resulting UUID
> + */
> +__rte_experimental
> +void   rte_uuid_generate_time(rte_uuid_t uu);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/eal/version.map b/lib/eal/version.map
> index 3df50c3fbb..5a8aa67244 100644
> --- a/lib/eal/version.map
> +++ b/lib/eal/version.map
> @@ -396,6 +396,8 @@ EXPERIMENTAL {
>  
>  	# added in 24.03

i guess 24.07 now

>  	rte_vfio_get_device_info; # WINDOWS_NO_EXPORT
> +	rte_uuid_generate_random;
> +	rte_uuid_generate_time;
>  };
>  
>  INTERNAL {
> -- 
> 2.43.0
  

Patch

diff --git a/lib/eal/common/eal_common_uuid.c b/lib/eal/common/eal_common_uuid.c
index 0a80bfbb38..fc8f58e8a4 100644
--- a/lib/eal/common/eal_common_uuid.c
+++ b/lib/eal/common/eal_common_uuid.c
@@ -7,7 +7,12 @@ 
 #include <stdint.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <time.h>
 
+#include <rte_atomic.h>
+#include <rte_common.h>
+#include <rte_random.h>
+#include <rte_time.h>
 #include <rte_uuid.h>
 
 /* UUID packed form */
@@ -165,3 +170,54 @@  void rte_uuid_unparse(const rte_uuid_t uu, char *out, size_t len)
 		uuid.node[0], uuid.node[1], uuid.node[2],
 		uuid.node[3], uuid.node[4], uuid.node[5]);
 }
+
+void rte_uuid_generate_random(rte_uuid_t out)
+{
+	union {
+		uint64_t words[2];
+		rte_uuid_t uuid;
+	} buf;
+	struct uuid uu;
+
+	/* UUID is 128 bit */
+	buf.words[0] = rte_rand();
+	buf.words[1] = rte_rand();
+
+	/* Mark these random bytes a version 4 random uuid */
+	uuid_unpack(buf.uuid, &uu);
+	uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
+	uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
+	uuid_pack(&uu, out);
+}
+
+void rte_uuid_generate_time(rte_uuid_t out)
+{
+	struct uuid uu;
+	struct timespec ts;
+	uint64_t ns, rnd;
+	static uint16_t sequence;
+
+	/* The time value for UUID is 100ns since 15 October 1582 */
+	clock_gettime(CLOCK_REALTIME, &ts);
+
+	ns = ts.tv_nsec / 100;
+	ns += (uint64_t) ts.tv_sec * (NSEC_PER_SEC / 100);
+	ns += (((uint64_t) 0x01B21DD2) << 32) + 0x13814000;
+
+	uu.time_low = (uint32_t) ns;
+	uu.time_mid = (uint16_t) (ns >> 32);
+	uu.time_hi_and_version = (uint16_t) (ns >> 48);
+	uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
+	uu.clock_seq = rte_atomic_fetch_add_explicit(&sequence, 1,
+						     rte_memory_order_relaxed);
+
+	rnd = rte_rand();
+	memcpy(uu.node, &rnd, 6);
+	/*
+	 * What libuuid does set multicast bit.
+	 * This avoids conflicts with network cards.
+	 */
+	uu.node[0] |= 0x1;
+
+	uuid_pack(&uu, out);
+}
diff --git a/lib/eal/include/rte_uuid.h b/lib/eal/include/rte_uuid.h
index cfefd4308a..052b78a812 100644
--- a/lib/eal/include/rte_uuid.h
+++ b/lib/eal/include/rte_uuid.h
@@ -18,6 +18,8 @@  extern "C" {
 #include <stddef.h>
 #include <string.h>
 
+#include <rte_compat.h>
+
 /**
  * Struct describing a Universal Unique Identifier
  */
@@ -94,12 +96,30 @@  int	rte_uuid_parse(const char *in, rte_uuid_t uu);
  * @param uu
  *    UUID to format
  * @param out
- *    Resulting string buffer
+ *    Resulting string bufferm
  * @param len
  *    Sizeof the available string buffer
  */
 void	rte_uuid_unparse(const rte_uuid_t uu, char *out, size_t len);
 
+/**
+ * Generate a random uuid
+ *
+ * @param uu
+ *   Resulting UUID
+ */
+__rte_experimental
+void   rte_uuid_generate_random(rte_uuid_t uu);
+
+/**
+ * Generate a uuid based on time stamp.
+ *
+ * @param uu
+ *   Resulting UUID
+ */
+__rte_experimental
+void   rte_uuid_generate_time(rte_uuid_t uu);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/eal/version.map b/lib/eal/version.map
index 3df50c3fbb..5a8aa67244 100644
--- a/lib/eal/version.map
+++ b/lib/eal/version.map
@@ -396,6 +396,8 @@  EXPERIMENTAL {
 
 	# added in 24.03
 	rte_vfio_get_device_info; # WINDOWS_NO_EXPORT
+	rte_uuid_generate_random;
+	rte_uuid_generate_time;
 };
 
 INTERNAL {