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
