diff options
Diffstat (limited to 'lib/includes/hicn/common.h')
-rw-r--r-- | lib/includes/hicn/common.h | 257 |
1 files changed, 138 insertions, 119 deletions
diff --git a/lib/includes/hicn/common.h b/lib/includes/hicn/common.h index 30f370241..64aca8f1f 100644 --- a/lib/includes/hicn/common.h +++ b/lib/includes/hicn/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -36,59 +36,23 @@ #include <stdint.h> #include <assert.h> -/* Concise type definitions */ +#include <hicn/util/types.h> -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; +#define HICN_EXPECT_FALSE(x) __builtin_expect ((x), 1) +#define HICN_EXPECT_TRUE(x) __builtin_expect ((x), 0) +#define HICN_UNUSED(x) x __attribute__ ((unused)) -/* - * Code annotations - * - * NOTE: these are defined by default in VPP. - */ - -#ifndef HICN_VPP_PLUGIN - -#define PREDICT_FALSE(x) (x) -#define PREDICT_TRUE(x) (x) -#define always_inline static inline -#define static_always_inline static inline -#define STRUCT_SIZE_OF(type, member) sizeof(((type *)0)->member) -#define ASSERT - -#define STATIC_ASSERT(x) - -/* Architecture-dependent uword size */ -#if INTPTR_MAX == INT64_MAX -#define log2_uword_bits 6 -#elif INTPTR_MAX == INT32_MAX -#define log2_uword_bits 5 -#else -#error "Impossible to detect architecture" -#endif - -#define uword_bits (1 << log2_uword_bits) - -/* Word types. */ -#if uword_bits == 64 -/* 64 bit word machines. */ -typedef u64 uword; +#ifndef NDEBUG +#define _ASSERT(x) assert (x) #else -/* 32 bit word machines. */ -typedef u32 uword; +#define _ASSERT(x) ((void) (x)) #endif -typedef uword ip_csum_t; - -#endif /* ! HICN_VPP_PLUGIN */ - /* - * Windows compilers do not support named initilizers when .h files are included - * inside C++ files. For readability, we either use the following macro, or - * duplicate some code, with the intent of preserving those safeguards for - * non-Windows platforms. + * Windows compilers do not support named initilizers when .h files are + * included inside C++ files. For readability, we either use the following + * macro, or duplicate some code, with the intent of preserving those + * safeguards for non-Windows platforms. */ #ifndef _WIN32 #define ATTR_INIT(key, value) .key = value @@ -97,13 +61,16 @@ typedef uword ip_csum_t; #endif #ifdef _WIN32 - /* Endianness detection for Windows platforms */ +/* Endianness detection for Windows platforms */ #define __ORDER_LITTLE_ENDIAN__ 0x41424344UL -#define __ORDER_BIG_ENDIAN__ 0x44434241UL -#define __BYTE_ORDER__ ('ABCD') +#define __ORDER_BIG_ENDIAN__ 0x44434241UL +#define __BYTE_ORDER__ ('ABCD') - /* Windows compatibility headers */ +/* Windows compatibility headers */ #define WIN32_LEAN_AND_MEAN +#ifndef NOMINMAX +#define NOMINMAX +#endif #include <windows.h> #include <winsock2.h> #include <ws2ipdef.h> @@ -113,10 +80,10 @@ typedef uword ip_csum_t; #define strdup _strdup #define __attribute__(A) -#ifndef IOVEC +#ifndef IOVEC #define IOVEC #define UIO_MAXIOV 16 -#define IOV_MAX UIO_MAXIOV +#define IOV_MAX UIO_MAXIOV struct iovec { void *iov_base; @@ -129,57 +96,20 @@ struct iovec * Portable attribute packed. */ #ifndef _WIN32 -#define PACKED( __Declaration__ ) __Declaration__ __attribute__((__packed__)) +#define PACKED(__Declaration__) __Declaration__ __attribute__ ((__packed__)) #else -#define PACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) ) +#define PACKED(__Declaration__) \ + __pragma (pack (push, 1)) __Declaration__ __pragma (pack (pop)) #endif - /* * IP address types */ -#ifdef HICN_VPP_PLUGIN - -#include <vnet/ip/ip4_packet.h> // ip4_address_t -#include <vnet/ip/ip6_packet.h> // ip6_address_t -#include <vnet/ip/ip46_address.h> - -#else - - #ifndef _WIN32 #include <netinet/in.h> #endif -typedef union -{ - u32 as_u32; - struct in_addr as_inaddr; -} ip4_address_t; - -typedef union -{ - u64 as_u64[2]; - u32 as_u32[4]; - u8 as_u8[16]; - struct in6_addr as_in6addr; -} ip6_address_t; - -typedef union -{ - struct - { - u32 pad[3]; - ip4_address_t ip4; - }; - ip6_address_t ip6; -} ip46_address_t; - -#define ip46_address_is_ip4(ip46) (((ip46)->pad[0] | (ip46)->pad[1] | (ip46)->pad[2]) == 0) - -#endif /* ! HICN_VPP_PLUGIN */ - /** * @brief Returns the family of an IP address * @param [in] ip_address - IP address in presentation format @@ -203,33 +133,33 @@ int get_addr_family (const char *ip_address); * borrow this code here. */ -static_always_inline u16 -ip_csum_fold (ip_csum_t c) +static inline u16 +ip_csum_fold (hicn_ip_csum_t c) { /* Reduce to 16 bits. */ #if uword_bits == 64 - c = (c & (ip_csum_t) 0xffffffff) + (c >> (ip_csum_t) 32); + c = (c & (hicn_ip_csum_t) 0xffffffff) + (c >> (hicn_ip_csum_t) 32); c = (c & 0xffff) + (c >> 16); #endif c = (c & 0xffff) + (c >> 16); c = (c & 0xffff) + (c >> 16); - return (u16)c; + return (u16) c; } -static_always_inline ip_csum_t -ip_csum_with_carry (ip_csum_t sum, ip_csum_t x) +static inline hicn_ip_csum_t +ip_csum_with_carry (hicn_ip_csum_t sum, hicn_ip_csum_t x) { - ip_csum_t t = sum + x; + hicn_ip_csum_t t = sum + x; return t + (t < x); } /* Update checksum changing field at even byte offset from x -> 0. */ -static_always_inline ip_csum_t -ip_csum_add_even (ip_csum_t c, ip_csum_t x) +static inline hicn_ip_csum_t +ip_csum_add_even (hicn_ip_csum_t c, hicn_ip_csum_t x) { - ip_csum_t d; + hicn_ip_csum_t d; d = c - x; @@ -240,19 +170,17 @@ ip_csum_add_even (ip_csum_t c, ip_csum_t x) } /* Update checksum changing field at even byte offset from 0 -> x. */ -static_always_inline ip_csum_t -ip_csum_sub_even (ip_csum_t c, ip_csum_t x) +static inline hicn_ip_csum_t +ip_csum_sub_even (hicn_ip_csum_t c, hicn_ip_csum_t x) { return ip_csum_with_carry (c, x); } +#endif /* ! HICN_VPP_PLUGIN */ + u32 cumulative_hash32 (const void *data, size_t len, u32 lastValue); u32 hash32 (const void *data, size_t len); -u64 cumulative_hash64 (const void *data, size_t len, u64 lastValue); -u64 hash64 (const void *data, size_t len); -void hicn_packet_dump (uint8_t * buffer, size_t len); - -#endif /* ! HICN_VPP_PLUGIN */ +void hicn_packet_dump (const uint8_t *buffer, size_t len); /** * @brief Computes buffer checksum @@ -261,7 +189,7 @@ void hicn_packet_dump (uint8_t * buffer, size_t len); * @param [in] init - Checksum initial value * @return Checksum of specified buffer */ -always_inline u16 +static inline u16 csum (const void *addr, size_t size, u16 init) { u32 sum = init; @@ -279,7 +207,7 @@ csum (const void *addr, size_t size, u16 init) sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); - return (u16) ~ sum; + return (u16) ~sum; } /* @@ -293,19 +221,110 @@ csum (const void *addr, size_t size, u16 init) * Query IP version from packet (either 4 or 6) * (version is located as same offsets in both protocol headers) */ -#define HICN_IP_VERSION(packet) ((hicn_header_t *)packet)->v4.ip.version +typedef struct +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + u8 dummy : 4; + u8 version : 4; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + u8 version : 4; + u8 dummy : 4; +#else +#error "Unsupported endianness" +#endif +} ip_version_t; +#define HICN_IP_VERSION(packet) ((ip_version_t *) packet)->version /* - * ntohll / htonll allows byte swapping for 64 bits integers + * Endianess utils */ -#ifndef htonll -#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) + +#if (__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__) +#define HICN_LITTLE_ENDIAN_ARCH +#else +#define HICN_BIG_ENDIAN_ARCH +#endif + +static inline u16 +hicn_conditional_swap_u16 (u16 value) +{ +#ifdef HICN_LITTLE_ENDIAN_ARCH + value = __builtin_bswap16 (value); +#endif + + return value; +} + +static inline u32 +hicn_conditional_swap_u32 (u32 value) +{ +#ifdef HICN_LITTLE_ENDIAN_ARCH + value = __builtin_bswap32 (value); #endif -#ifndef ntohll -#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) + return value; +} + +static inline u64 +hicn_conditional_swap_u64 (u64 value) +{ +#ifdef HICN_LITTLE_ENDIAN_ARCH + value = __builtin_bswap64 (value); #endif + return value; +} + +#define hicn_net_to_host_16(x) hicn_conditional_swap_u16 ((u16) (x)) +#define hicn_net_to_host_32(x) hicn_conditional_swap_u32 ((u32) (x)) +#define hicn_net_to_host_64(x) hicn_conditional_swap_u64 ((u64) (x)) + +#define hicn_host_to_net_16(x) hicn_conditional_swap_u16 ((u16) (x)) +#define hicn_host_to_net_32(x) hicn_conditional_swap_u32 ((u32) (x)) +#define hicn_host_to_net_64(x) hicn_conditional_swap_u64 ((u64) (x)) + +#define hicn_round_pow2(x, pow2) (((x) + (pow2) -1) & ~((pow2) -1)) + +#define _SIZEOF_ALIGNED(x, size) hicn_round_pow2 (sizeof (x), size) +#define SIZEOF_ALIGNED(x) _SIZEOF_ALIGNED (x, sizeof (void *)) + +/* Definitions for builtins unavailable on MSVC */ +#if defined(_MSC_VER) && !defined(__clang__) +#include <intrin.h> + +uint32_t __inline __builtin_ctz (uint32_t value) +{ + uint32_t trailing_zero = 0; + if (_BitScanForward (&trailing_zero, value)) + return trailing_zero; + else + return 32; +} + +uint32_t __inline __builtin_clz (uint32_t value) +{ + uint32_t leading_zero = 0; + if (_BitScanReverse (&leading_zero, value)) + return 31 - leading_zero; + else + return 32; +} + +uint32_t __inline __builtin_clzl2 (uint64_t value) +{ + uint32_t leading_zero = 0; + if (_BitScanReverse64 (&leading_zero, value)) + return 63 - leading_zero; + else + return 64; +} + +#define __builtin_clzl __builtin_clzll +#endif + +#define next_pow2(x) (x <= 1 ? 1 : 1ul << (64 - __builtin_clzl (x - 1))) +#define _unused(x) ((void) (x)) + #endif /* HICN_COMMON_H */ /* |