Upcoming commits will be implementing the ChaCha20 high-speed
symmetric hashing algorithm as part of a CSPRNG for use with
NAT tuple generation.  ChaCha20 treats internal stream data
as little endian bytes, which means the implementation will
need a way to read and write byte streams of le32 values.

To facilitate this, introduce the ovs_htole32 and ovs_le32toh
functions.  Some proto-POSIX implementations exist on various
systems and can be found in `endian.h` or `sys/endian.h`, so
try to detect those and prefer them.  On systems where they
don't exist, the ovs_* functions will have actual byteswap
implementations.

Assisted-by: LLM (claude, opencode, sonnet, opus, qwen3.8)
Signed-off-by: Aaron Conole <[email protected]>
---

v2->v3:
  * Reworked to detect the endian.h that exists on the system, and
    hook up ovs_le32toh / ovs_htole32 appropriately based on the
    results of that check.

 configure.ac     |  7 +++++++
 lib/byte-order.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/configure.ac b/configure.ac
index db233fad45..c2834c1b3d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -117,6 +117,13 @@ AC_CHECK_HEADERS([mntent.h sys/statvfs.h linux/types.h 
linux/if_ether.h])
 AC_CHECK_HEADERS([linux/net_namespace.h stdatomic.h bits/floatn-common.h])
 AC_CHECK_HEADERS([net/if_mib.h], [], [], [[#include <sys/types.h>
 #include <net/if.h>]])
+AC_CHECK_HEADERS([endian.h sys/endian.h])
+AC_CHECK_DECLS([htole32, le32toh], [], [], [[#if HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+#if HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif]])
 
 OVS_CHECK_PKIDIR
 OVS_CHECK_RUNDIR
diff --git a/lib/byte-order.h b/lib/byte-order.h
index f5a21f3298..107f02d53b 100644
--- a/lib/byte-order.h
+++ b/lib/byte-order.h
@@ -20,6 +20,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <inttypes.h>
+#include <string.h>
 #include "openvswitch/types.h"
 
 #ifndef __CHECKER__
@@ -71,6 +72,53 @@ uint32_byteswap(uint32_t crc) {
             ((crc & 0xff000000) >> 24));
 }
 
+#if HAVE_ENDIAN_H
+#include <endian.h>
+#elif HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+
+#if HAVE_DECL_HTOLE32 && HAVE_DECL_LE32TOH
+static inline uint32_t
+ovs_htole32(uint32_t host_32bits)
+{
+    return htole32(host_32bits);
+}
+
+static inline uint32_t
+ovs_le32toh(uint32_t le_32bits)
+{
+    return le32toh(le_32bits);
+}
+#else
+static inline uint32_t
+ovs_htole32(uint32_t host_32bits)
+{
+    return htonl(1) == 1 ? uint32_byteswap(host_32bits) : host_32bits;
+}
+
+static inline uint32_t
+ovs_le32toh(uint32_t le_32bits)
+{
+    return htonl(1) == 1 ? uint32_byteswap(le_32bits) : le_32bits;
+}
+#endif
+
+static inline uint32_t
+ovs_load_le32(const uint8_t *p)
+{
+    uint32_t n;
+    memcpy(&n, p, sizeof n);
+    return ovs_le32toh(n);
+}
+
+static inline void
+ovs_store_le32(uint8_t *p, uint32_t v)
+{
+    uint32_t n = ovs_htole32(v);
+    memcpy(p, &n, sizeof n);
+}
+
 /* These macros may substitute for htons(), htonl(), and htonll() in contexts
  * where function calls are not allowed, such as case labels.  They should not
  * be used elsewhere because all of them evaluate their argument many times. */
-- 
2.56.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to