From 302b25a00ed913767798d58148ef4d36092ee490 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Mon, 19 Oct 2020 13:23:33 +0000 Subject: ipsec: Add to the SA info directly in the bihash Type: improvement this save the cache miss on the protect structure. Signed-off-by: Neale Ranns Change-Id: I867d5e49df5edfd6b368f17a34747f32840080e4 --- src/vnet/ipsec/ipsec.h | 8 ++-- src/vnet/ipsec/ipsec_cli.c | 8 ++-- src/vnet/ipsec/ipsec_tun.c | 52 +++++++++++--------- src/vnet/ipsec/ipsec_tun.h | 52 ++++++++++---------- src/vnet/ipsec/ipsec_tun_in.c | 44 ++++++++--------- src/vppinfra/bihash_24_16.h | 102 +++++++++++++++++++++++++++++++++++++++ src/vppinfra/bihash_8_16.h | 109 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 294 insertions(+), 81 deletions(-) create mode 100644 src/vppinfra/bihash_24_16.h create mode 100644 src/vppinfra/bihash_8_16.h diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h index fe44b80b321..97ef6262f71 100644 --- a/src/vnet/ipsec/ipsec.h +++ b/src/vnet/ipsec/ipsec.h @@ -26,9 +26,9 @@ #include #include -#include +#include -#include +#include typedef clib_error_t *(*add_del_sa_sess_cb_t) (u32 sa_index, u8 is_add); typedef clib_error_t *(*check_support_cb_t) (ipsec_sa_t * sa); @@ -130,8 +130,8 @@ typedef struct uword *ipsec_if_real_dev_by_show_dev; uword *ipsec_if_by_sw_if_index; - clib_bihash_8_8_t tun4_protect_by_key; - clib_bihash_24_8_t tun6_protect_by_key; + clib_bihash_8_16_t tun4_protect_by_key; + clib_bihash_24_16_t tun6_protect_by_key; /* node indices */ u32 error_drop_node_index; diff --git a/src/vnet/ipsec/ipsec_cli.c b/src/vnet/ipsec/ipsec_cli.c index 7d265f7e64d..d7378534eb8 100644 --- a/src/vnet/ipsec/ipsec_cli.c +++ b/src/vnet/ipsec/ipsec_cli.c @@ -1040,7 +1040,7 @@ VLIB_CLI_COMMAND (ipsec_tun_protect_show_node, static) = /* *INDENT-ON* */ static int -ipsec_tun_protect4_hash_show_one (clib_bihash_kv_8_8_t * kv, void *arg) +ipsec_tun_protect4_hash_show_one (clib_bihash_kv_8_16_t * kv, void *arg) { ipsec4_tunnel_kv_t *ikv = (ipsec4_tunnel_kv_t *) kv; vlib_main_t *vm = arg; @@ -1051,7 +1051,7 @@ ipsec_tun_protect4_hash_show_one (clib_bihash_kv_8_8_t * kv, void *arg) } static int -ipsec_tun_protect6_hash_show_one (clib_bihash_kv_24_8_t * kv, void *arg) +ipsec_tun_protect6_hash_show_one (clib_bihash_kv_24_16_t * kv, void *arg) { ipsec6_tunnel_kv_t *ikv = (ipsec6_tunnel_kv_t *) kv; vlib_main_t *vm = arg; @@ -1071,12 +1071,12 @@ ipsec_tun_protect_hash_show (vlib_main_t * vm, { vlib_cli_output (vm, "IPv4:"); - clib_bihash_foreach_key_value_pair_8_8 + clib_bihash_foreach_key_value_pair_8_16 (&im->tun4_protect_by_key, ipsec_tun_protect4_hash_show_one, vm); vlib_cli_output (vm, "IPv6:"); - clib_bihash_foreach_key_value_pair_24_8 + clib_bihash_foreach_key_value_pair_24_16 (&im->tun6_protect_by_key, ipsec_tun_protect6_hash_show_one, vm); } diff --git a/src/vnet/ipsec/ipsec_tun.c b/src/vnet/ipsec/ipsec_tun.c index 4985c549ccc..c4c8fa7d262 100644 --- a/src/vnet/ipsec/ipsec_tun.c +++ b/src/vnet/ipsec/ipsec_tun.c @@ -23,6 +23,12 @@ #include #include +/* instantiate the bihash functions */ +#include +#include +#include +#include + #define IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS (64 * 1024) #define IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE 512 << 20 @@ -224,6 +230,8 @@ ipsec_tun_protect_rx_db_add (ipsec_main_t * im, ipsec_tun_lkup_result_t res = { .tun_index = itp - ipsec_tun_protect_pool, .sa_index = sai, + .flags = itp->itp_flags, + .sw_if_index = itp->itp_sw_if_index, }; /* @@ -235,18 +243,18 @@ ipsec_tun_protect_rx_db_add (ipsec_main_t * im, ipsec4_tunnel_kv_t key = { .value = res, }; - clib_bihash_kv_8_8_t *bkey = (clib_bihash_kv_8_8_t*)&key; + clib_bihash_kv_8_16_t *bkey = (clib_bihash_kv_8_16_t*)&key; ipsec4_tunnel_mk_key(&key, &itp->itp_crypto.dst.ip4, clib_host_to_net_u32 (sa->spi)); if (!im->tun4_protect_by_key.nbuckets) - clib_bihash_init_8_8 (&im->tun4_protect_by_key, + clib_bihash_init_8_16 (&im->tun4_protect_by_key, "IPSec IPv4 tunnels", IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS, IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE); - clib_bihash_add_del_8_8 (&im->tun4_protect_by_key, bkey, 1); + clib_bihash_add_del_8_16 (&im->tun4_protect_by_key, bkey, 1); ipsec_tun_register_nodes(AF_IP4); } else @@ -258,14 +266,14 @@ ipsec_tun_protect_rx_db_add (ipsec_main_t * im, }, .value = res, }; - clib_bihash_kv_24_8_t *bkey = (clib_bihash_kv_24_8_t*)&key; + clib_bihash_kv_24_16_t *bkey = (clib_bihash_kv_24_16_t*)&key; if (!im->tun4_protect_by_key.nbuckets) - clib_bihash_init_24_8 (&im->tun6_protect_by_key, + clib_bihash_init_24_16 (&im->tun6_protect_by_key, "IPSec IPv6 tunnels", IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS, IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE); - clib_bihash_add_del_24_8 (&im->tun6_protect_by_key, bkey, 1); + clib_bihash_add_del_24_16 (&im->tun6_protect_by_key, bkey, 1); ipsec_tun_register_nodes(AF_IP6); } })) @@ -355,14 +363,14 @@ ipsec_tun_protect_rx_db_remove (ipsec_main_t * im, if (ip46_address_is_ip4 (&itp->itp_crypto.dst)) { ipsec4_tunnel_kv_t key; - clib_bihash_kv_8_8_t res, *bkey = (clib_bihash_kv_8_8_t*)&key; + clib_bihash_kv_8_16_t res, *bkey = (clib_bihash_kv_8_16_t*)&key; ipsec4_tunnel_mk_key(&key, &itp->itp_crypto.dst.ip4, clib_host_to_net_u32 (sa->spi)); - if (!clib_bihash_search_8_8 (&im->tun4_protect_by_key, bkey, &res)) + if (!clib_bihash_search_8_16 (&im->tun4_protect_by_key, bkey, &res)) { - clib_bihash_add_del_8_8 (&im->tun4_protect_by_key, bkey, 0); + clib_bihash_add_del_8_16 (&im->tun4_protect_by_key, bkey, 0); ipsec_tun_unregister_nodes(AF_IP4); } } @@ -374,11 +382,11 @@ ipsec_tun_protect_rx_db_remove (ipsec_main_t * im, .spi = clib_host_to_net_u32 (sa->spi), }, }; - clib_bihash_kv_24_8_t res, *bkey = (clib_bihash_kv_24_8_t*)&key; + clib_bihash_kv_24_16_t res, *bkey = (clib_bihash_kv_24_16_t*)&key; - if (!clib_bihash_search_24_8 (&im->tun6_protect_by_key, bkey, &res)) + if (!clib_bihash_search_24_16 (&im->tun6_protect_by_key, bkey, &res)) { - clib_bihash_add_del_24_8 (&im->tun6_protect_by_key, bkey, 0); + clib_bihash_add_del_24_16 (&im->tun6_protect_by_key, bkey, 0); ipsec_tun_unregister_nodes(AF_IP6); } } @@ -971,11 +979,11 @@ ipsec_tun_table_init (ip_address_family_t af, uword table_size, u32 n_buckets) im = &ipsec_main; if (AF_IP4 == af) - clib_bihash_init_8_8 (&im->tun4_protect_by_key, - "IPSec IPv4 tunnels", n_buckets, table_size); + clib_bihash_init_8_16 (&im->tun4_protect_by_key, + "IPSec IPv4 tunnels", n_buckets, table_size); else - clib_bihash_init_24_8 (&im->tun6_protect_by_key, - "IPSec IPv6 tunnels", n_buckets, table_size); + clib_bihash_init_24_16 (&im->tun6_protect_by_key, + "IPSec IPv6 tunnels", n_buckets, table_size); } clib_error_t * @@ -984,14 +992,14 @@ ipsec_tunnel_protect_init (vlib_main_t * vm) ipsec_main_t *im; im = &ipsec_main; - clib_bihash_init_24_8 (&im->tun6_protect_by_key, - "IPSec IPv6 tunnels", + clib_bihash_init_24_16 (&im->tun6_protect_by_key, + "IPSec IPv6 tunnels", + IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS, + IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE); + clib_bihash_init_8_16 (&im->tun4_protect_by_key, + "IPSec IPv4 tunnels", IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS, IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE); - clib_bihash_init_8_8 (&im->tun4_protect_by_key, - "IPSec IPv4 tunnels", - IPSEC_TUN_DEFAULT_HASH_NUM_BUCKETS, - IPSEC_TUN_DEFAULT_HASH_MEMORY_SIZE); /* set up feature nodes to drop outbound packets with no crypto alg set */ im->esp4_no_crypto_tun_node_index = diff --git a/src/vnet/ipsec/ipsec_tun.h b/src/vnet/ipsec/ipsec_tun.h index 0d911a2876c..b8e80d3565f 100644 --- a/src/vnet/ipsec/ipsec_tun.h +++ b/src/vnet/ipsec/ipsec_tun.h @@ -17,20 +17,31 @@ #include +#define foreach_ipsec_protect_flags \ + _(L2, 1, "l2") \ + _(ENCAPED, 2, "encapped") \ + _(ITF, 4, "itf") \ + +typedef enum ipsec_protect_flags_t_ +{ + IPSEC_PROTECT_NONE = 0, +#define _(a,b,c) IPSEC_PROTECT_##a = b, + foreach_ipsec_protect_flags +#undef _ +} __clib_packed ipsec_protect_flags_t; + +extern u8 *format_ipsec_tun_protect_flags (u8 * s, va_list * args); + /** * result of a lookup in the protection bihash */ typedef struct ipsec_tun_lkup_result_t_ { - union - { - struct - { - u32 tun_index; - u32 sa_index; - }; - u64 as_u64; - }; + u32 tun_index; + u32 sa_index; + u32 sw_if_index; + ipsec_protect_flags_t flags; + u8 __pad[3]; } ipsec_tun_lkup_result_t; typedef struct ipsec4_tunnel_kv_t @@ -43,9 +54,9 @@ typedef struct ipsec4_tunnel_kv_t ipsec_tun_lkup_result_t value; } __clib_packed ipsec4_tunnel_kv_t; -STATIC_ASSERT_SIZEOF (ipsec4_tunnel_kv_t, sizeof (clib_bihash_kv_8_8_t)); +STATIC_ASSERT_SIZEOF (ipsec4_tunnel_kv_t, sizeof (clib_bihash_kv_8_16_t)); STATIC_ASSERT_OFFSET_OF (ipsec4_tunnel_kv_t, value, - STRUCT_OFFSET_OF (clib_bihash_kv_8_8_t, value)); + STRUCT_OFFSET_OF (clib_bihash_kv_8_16_t, value)); static inline void ipsec4_tunnel_mk_key (ipsec4_tunnel_kv_t * k, @@ -77,28 +88,13 @@ typedef struct ipsec6_tunnel_kv_t_ ipsec_tun_lkup_result_t value; } __clib_packed ipsec6_tunnel_kv_t; -STATIC_ASSERT_SIZEOF (ipsec6_tunnel_kv_t, sizeof (clib_bihash_kv_24_8_t)); +STATIC_ASSERT_SIZEOF (ipsec6_tunnel_kv_t, sizeof (clib_bihash_kv_24_16_t)); STATIC_ASSERT_OFFSET_OF (ipsec6_tunnel_kv_t, value, - STRUCT_OFFSET_OF (clib_bihash_kv_24_8_t, value)); + STRUCT_OFFSET_OF (clib_bihash_kv_24_16_t, value)); extern u8 *format_ipsec4_tunnel_kv (u8 * s, va_list * args); extern u8 *format_ipsec6_tunnel_kv (u8 * s, va_list * args); -#define foreach_ipsec_protect_flags \ - _(L2, 1, "l2") \ - _(ENCAPED, 2, "encapped") \ - _(ITF, 4, "itf") \ - -typedef enum ipsec_protect_flags_t_ -{ - IPSEC_PROTECT_NONE = 0, -#define _(a,b,c) IPSEC_PROTECT_##a = b, - foreach_ipsec_protect_flags -#undef _ -} __clib_packed ipsec_protect_flags_t; - -extern u8 *format_ipsec_tun_protect_flags (u8 * s, va_list * args); - typedef struct ipsec_ep_t_ { ip46_address_t src; diff --git a/src/vnet/ipsec/ipsec_tun_in.c b/src/vnet/ipsec/ipsec_tun_in.c index 804c7299c6f..6b7abce2866 100644 --- a/src/vnet/ipsec/ipsec_tun_in.c +++ b/src/vnet/ipsec/ipsec_tun_in.c @@ -149,10 +149,10 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, }; ipsec4_tunnel_kv_t last_key4; ipsec6_tunnel_kv_t last_key6; + ipsec_tun_lkup_result_t itr0; vlib_combined_counter_main_t *rx_counter; vlib_combined_counter_main_t *drop_counter; - ipsec_tun_protect_t *itp0; if (is_ip6) clib_memset (&last_key6, 0xff, sizeof (last_key6)); @@ -165,9 +165,8 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, while (n_left_from > 0) { u32 sw_if_index0, len0, hdr_sz0; - ipsec_tun_lkup_result_t itr0; - clib_bihash_kv_24_8_t bkey60; - clib_bihash_kv_8_8_t bkey40; + clib_bihash_kv_24_16_t bkey60; + clib_bihash_kv_8_16_t bkey40; ipsec4_tunnel_kv_t *key40; ipsec6_tunnel_kv_t *key60; ip4_header_t *ip40; @@ -231,17 +230,18 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (memcmp (key60, &last_key6, sizeof (last_key6)) == 0) { - itr0 = last_result; + clib_memcpy_fast (&itr0, &last_result, sizeof (itr0)); } else { int rv = - clib_bihash_search_inline_24_8 (&im->tun6_protect_by_key, - &bkey60); + clib_bihash_search_inline_24_16 (&im->tun6_protect_by_key, + &bkey60); if (!rv) { - itr0.as_u64 = bkey60.value; - last_result = itr0; + clib_memcpy_fast (&itr0, &bkey60.value, sizeof (itr0)); + clib_memcpy_fast (&last_result, &bkey60.value, + sizeof (last_result)); clib_memcpy_fast (&last_key6, key60, sizeof (last_key6)); } else @@ -258,17 +258,18 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, if (key40->key == last_key4.key) { - itr0 = last_result; + clib_memcpy_fast (&itr0, &last_result, sizeof (itr0)); } else { int rv = - clib_bihash_search_inline_8_8 (&im->tun4_protect_by_key, - &bkey40); + clib_bihash_search_inline_8_16 (&im->tun4_protect_by_key, + &bkey40); if (!rv) { - itr0.as_u64 = bkey40.value; - last_result = itr0; + clib_memcpy_fast (&itr0, &bkey40.value, sizeof (itr0)); + clib_memcpy_fast (&last_result, &bkey40.value, + sizeof (last_result)); last_key4.key = key40->key; } else @@ -281,11 +282,10 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, } } - itp0 = pool_elt_at_index (ipsec_tun_protect_pool, itr0.tun_index); vnet_buffer (b[0])->ipsec.sad_index = itr0.sa_index; vnet_buffer (b[0])->ipsec.protect_index = itr0.tun_index; - sw_if_index0 = itp0->itp_sw_if_index; + sw_if_index0 = itr0.sw_if_index; vnet_buffer (b[0])->sw_if_index[VLIB_RX] = sw_if_index0; if (PREDICT_FALSE (!vnet_sw_interface_is_admin_up (vnm, sw_if_index0))) @@ -306,7 +306,7 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, } else { - if (n_packets && !(itp0->itp_flags & IPSEC_PROTECT_ENCAPED)) + if (n_packets && !(itr0.flags & IPSEC_PROTECT_ENCAPED)) { vlib_increment_combined_counter (rx_counter, thread_index, last_sw_if_index, @@ -344,12 +344,10 @@ ipsec_tun_protect_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, n_left_from -= 1; } - if (n_packets && !(itp0->itp_flags & IPSEC_PROTECT_ENCAPED)) - { - vlib_increment_combined_counter (rx_counter, - thread_index, - last_sw_if_index, n_packets, n_bytes); - } + if (n_packets && !(itr0.flags & IPSEC_PROTECT_ENCAPED)) + vlib_increment_combined_counter (rx_counter, + thread_index, + last_sw_if_index, n_packets, n_bytes); vlib_node_increment_counter (vm, node->node_index, IPSEC_TUN_PROTECT_INPUT_ERROR_RX, diff --git a/src/vppinfra/bihash_24_16.h b/src/vppinfra/bihash_24_16.h new file mode 100644 index 00000000000..4e979b49410 --- /dev/null +++ b/src/vppinfra/bihash_24_16.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2015 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. + */ +#undef BIHASH_TYPE +#undef BIHASH_KVP_PER_PAGE +#undef BIHASH_32_64_SVM +#undef BIHASH_ENABLE_STATS +#undef BIHASH_KVP_AT_BUCKET_LEVEL +#undef BIHASH_LAZY_INSTANTIATE +#undef BIHASH_BUCKET_PREFETCH_CACHE_LINES +#undef BIHASH_USE_HEAP + +#define BIHASH_TYPE _24_16 +#define BIHASH_KVP_PER_PAGE 4 +#define BIHASH_KVP_AT_BUCKET_LEVEL 0 +#define BIHASH_LAZY_INSTANTIATE 1 +#define BIHASH_BUCKET_PREFETCH_CACHE_LINES 1 +#define BIHASH_USE_HEAP 1 + +#ifndef __included_bihash_24_16_h__ +#define __included_bihash_24_16_h__ + +#include +#include +#include +#include +#include + +typedef struct +{ + u64 key[3]; + u64 value[2]; +} clib_bihash_kv_24_16_t; + +static inline int +clib_bihash_is_free_24_16 (const clib_bihash_kv_24_16_t * v) +{ + /* Free values are clib_memset to 0xff, check a bit... */ + if (v->key[0] == ~0ULL && v->value[0] == ~0ULL && v->value[1] == ~0ULL) + return 1; + return 0; +} + +static inline u64 +clib_bihash_hash_24_16 (const clib_bihash_kv_24_16_t * v) +{ +#ifdef clib_crc32c_uses_intrinsics + return clib_crc32c ((u8 *) v->key, 24); +#else + u64 tmp = v->key[0] ^ v->key[1] ^ v->key[2]; + return clib_xxhash (tmp); +#endif +} + +static inline u8 * +format_bihash_kvp_24_16 (u8 * s, va_list * args) +{ + clib_bihash_kv_24_16_t *v = va_arg (*args, clib_bihash_kv_24_16_t *); + + s = format (s, "key %llu %llu %llu value %llu %llu", + v->key[0], v->key[1], v->key[2], v->value[0], v->value[1]); + return s; +} + +static inline int +clib_bihash_key_compare_24_16 (u64 * a, u64 * b) +{ +#if defined (CLIB_HAVE_VEC512) + u64x8 v = u64x8_load_unaligned (a) ^ u64x8_load_unaligned (b); + return (u64x8_is_zero_mask (v) & 0x7) == 0; +#elif defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_UNALIGNED_LOAD_STORE) + u64x2 v = { a[2] ^ b[2], 0 }; + v |= u64x2_load_unaligned (a) ^ u64x2_load_unaligned (b); + return u64x2_is_all_zero (v); +#else + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) == 0; +#endif +} + +#undef __included_bihash_template_h__ +#include + +#endif /* __included_bihash_24_16_h__ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vppinfra/bihash_8_16.h b/src/vppinfra/bihash_8_16.h new file mode 100644 index 00000000000..b42b32c33d2 --- /dev/null +++ b/src/vppinfra/bihash_8_16.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015 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. + */ +#undef BIHASH_TYPE +#undef BIHASH_KVP_PER_PAGE +#undef BIHASH_32_64_SVM +#undef BIHASH_ENABLE_STATS +#undef BIHASH_KVP_AT_BUCKET_LEVEL +#undef BIHASH_LAZY_INSTANTIATE +#undef BIHASH_BUCKET_PREFETCH_CACHE_LINES +#undef BIHASH_USE_HEAP + +#define BIHASH_TYPE _8_16 +#define BIHASH_KVP_PER_PAGE 7 +#define BIHASH_KVP_AT_BUCKET_LEVEL 1 +#define BIHASH_LAZY_INSTANTIATE 0 +#define BIHASH_BUCKET_PREFETCH_CACHE_LINES 2 +#define BIHASH_USE_HEAP 1 + +#ifndef __included_bihash_8_16_h__ +#define __included_bihash_8_16_h__ + +#include +#include +#include +#include +#include + +/** 8 octet key, 8 octet key value pair */ +typedef struct +{ + u64 key; /**< the key */ + u64 value[2]; /**< the value */ +} clib_bihash_kv_8_16_t; + +/** Decide if a clib_bihash_kv_8_16_t instance is free + @param v- pointer to the (key,value) pair +*/ +static inline int +clib_bihash_is_free_8_16 (clib_bihash_kv_8_16_t * v) +{ + if (v->key == ~0ULL && v->value[0] == ~0ULL && v->value[1] == ~0ULL) + return 1; + return 0; +} + +/** Hash a clib_bihash_kv_8_16_t instance + @param v - pointer to the (key,value) pair, hash the key (only) +*/ +static inline u64 +clib_bihash_hash_8_16 (clib_bihash_kv_8_16_t * v) +{ + /* Note: to torture-test linear scan, make this fn return a constant */ +#ifdef clib_crc32c_uses_intrinsics + return clib_crc32c ((u8 *) & v->key, 8); +#else + return clib_xxhash (v->key); +#endif +} + +/** Format a clib_bihash_kv_8_16_t instance + @param s - u8 * vector under construction + @param args (vararg) - the (key,value) pair to format + @return s - the u8 * vector under construction +*/ +static inline u8 * +format_bihash_kvp_8_16 (u8 * s, va_list * args) +{ + clib_bihash_kv_8_16_t *v = va_arg (*args, clib_bihash_kv_8_16_t *); + + s = + format (s, "key %llu value [%ll,%llx]u", v->key, v->value[0], + v->value[1]); + return s; +} + +/** Compare two clib_bihash_kv_8_16_t instances + @param a - first key + @param b - second key +*/ +static inline int +clib_bihash_key_compare_8_16 (u64 a, u64 b) +{ + return a == b; +} + +#undef __included_bihash_template_h__ +#include + +#endif /* __included_bihash_8_16_h__ */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ -- cgit 1.2.3-korg