diff options
author | Mauro Sardara <msardara@cisco.com> | 2019-10-07 14:37:42 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@fd.io> | 2019-10-07 14:37:42 +0000 |
commit | 7896701a177d66f376172ab43df4b0c1d5d867a3 (patch) | |
tree | a89986dcceb1d5b6faa7ae529b1d4a1e9f4d6d85 /lib/includes/hicn/common.h | |
parent | 108c55669102931acc9bd99ca9918379722732b8 (diff) | |
parent | 6b84ec54083da9911f5ad4816d0eb4f4745afad4 (diff) |
Merge "[HICN-298] Release new hICN app for Android"
Diffstat (limited to 'lib/includes/hicn/common.h')
-rw-r--r-- | lib/includes/hicn/common.h | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/lib/includes/hicn/common.h b/lib/includes/hicn/common.h new file mode 100644 index 000000000..33323da1b --- /dev/null +++ b/lib/includes/hicn/common.h @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2017-2019 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: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file common.c + * @brief Common interfaces abstracting low-level platform. + * details. + * + * The role of this header file is to provide an uniform interface to the + * different platform on top of which we build the hICN interface: + * - syntax helpers + * - IP address management + * - protocol definition + * - ... + * + * The rationale is to leverage as much as possible platform-specific code, + * however some level of harmonization is needed to build code on top. Whenever + * possible, we align to VPP structure and naming. + */ + +#ifndef HICN_COMMON_H +#define HICN_COMMON_H + +#include <stdint.h> +#include <assert.h> + +/* Concise type definitions */ + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +/* + * 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; +#else +/* 32 bit word machines. */ +typedef u32 uword; +#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. + */ +#ifndef _WIN32 +#define ATTR_INIT(key, value) .key = value +#else +#define ATTR_INIT(key, value) value +#endif + +#ifdef _WIN32 + /* Endianness detection for Windows platforms */ +#define __ORDER_LITTLE_ENDIAN__ 0x41424344UL +#define __ORDER_BIG_ENDIAN__ 0x44434241UL +#define __BYTE_ORDER__ ('ABCD') + + /* Windows compatibility headers */ +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <winsock2.h> +#include <ws2ipdef.h> +#include <Ws2tcpip.h> +#include <In6addr.h> + +#define strdup _strdup +#define __attribute__(A) + +#ifndef IOVEC +#define IOVEC +#define UIO_MAXIOV 16 +#define IOV_MAX UIO_MAXIOV +struct iovec +{ + void *iov_base; + size_t iov_len; +}; +#endif +#endif + +/* + * Portable attribute packed. + */ +#ifndef _WIN32 +#define PACKED( __Declaration__ ) __Declaration__ __attribute__((__packed__)) +#else +#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 + +#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 + * @return AF_INET or AF_INET6 if successful, -1 otherwise + */ +int get_addr_family (const char *ip_address); + +/* + * Checksum computation + * + * NOTE: VPP provides efficient (incremental) checksum computations + * that we reuse, and provide alternative implementation otherwise. + */ + +#ifndef HICN_VPP_PLUGIN + +/* + * Checksum update (incremental and non-incremental) + * + * Those functions are already defined in VPP in vnet/ip/ip_packet.h, and we + * borrow this code here. + */ + +static_always_inline u16 +ip_csum_fold (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 & 0xffff) + (c >> 16); +#endif + + c = (c & 0xffff) + (c >> 16); + c = (c & 0xffff) + (c >> 16); + + return (u16)c; +} + +static_always_inline ip_csum_t +ip_csum_with_carry (ip_csum_t sum, ip_csum_t x) +{ + 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) +{ + ip_csum_t d; + + d = c - x; + + /* Fold in carry from high bit. */ + d -= d > c; + + return d; +} + +/* 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) +{ + return ip_csum_with_carry (c, x); +} + +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 */ + +/** + * @brief Computes buffer checksum + * @param [in] addr - Pointer to buffer start + * @param [in] size - Size of buffer + * @param [in] init - Checksum initial value + * @return Checksum of specified buffer + */ +always_inline u16 +csum (const void *addr, size_t size, u16 init) +{ + u32 sum = init; + const u16 *bytes = (u16 *) addr; + + while (size > 1) + { + sum += *bytes++; + size -= sizeof (u16); + } + if (size) + { + sum += *(const u8 *) bytes; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + + return (u16) ~ sum; +} + +/* + * Useful aliases + */ + +/* Symmetry with IPPROTO_ICMPV6 */ +#define IPPROTO_ICMPV4 IPPROTO_ICMP + +/* + * 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 + +/* + * ntohll / htonll allows byte swapping for 64 bits integers + */ +#ifndef htonll +#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#endif + +#ifndef ntohll +#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32)) +#endif + +#endif /* HICN_COMMON_H */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |