From 6b3f1c0a9cf66f82cda1dc6b15982ee910671340 Mon Sep 17 00:00:00 2001 From: Klement Sekera Date: Tue, 26 Jan 2021 12:18:53 +0100 Subject: nat: reduce number of hash tables for EI NAT Making code more simple and storing thread index along with session index as a preparation step for fixing thread safety patches. Type: improvement Signed-off-by: Klement Sekera Change-Id: Ib0c531e9f1f64b1f1ee912d4a83279200638e931 --- src/plugins/nat/nat.c | 52 +++++++++++++------------- src/plugins/nat/nat.h | 8 ++-- src/plugins/nat/nat44-ei/nat44_ei.c | 33 ++++++++-------- src/plugins/nat/nat44-ei/nat44_ei_ha.c | 16 ++++---- src/plugins/nat/nat44-ei/nat44_ei_in2out.c | 60 +++++++++++++----------------- src/plugins/nat/nat44-ei/nat44_ei_out2in.c | 45 +++++++++++----------- src/plugins/nat/nat44_cli.c | 20 +++++----- src/plugins/nat/nat44_hairpinning.c | 19 ++++------ src/plugins/nat/nat_inlines.h | 29 +++++++++++---- 9 files changed, 141 insertions(+), 141 deletions(-) diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index 245689db45d..57d3b2bfdd1 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -217,7 +217,9 @@ format_session_kvp (u8 * s, va_list * args) { clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *); - s = format (s, "%U session-index %llu", format_snat_key, v->key, v->value); + s = format (s, "%U thread-index %llu session-index %llu", format_snat_key, + v->key, nat_value_get_thread_index (v), + nat_value_get_session_index (v)); return s; } @@ -274,8 +276,6 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, u8 is_ha) { clib_bihash_kv_8_8_t kv; - snat_main_per_thread_data_t *tsm = - vec_elt_at_index (sm->per_thread_data, thread_index); if (is_ed_session (s)) { @@ -311,10 +311,10 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, else { init_nat_i2o_k (&kv, s); - if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0)) + if (clib_bihash_add_del_8_8 (&sm->in2out, &kv, 0)) nat_elog_warn ("in2out key del failed"); init_nat_o2i_k (&kv, s); - if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0)) + if (clib_bihash_add_del_8_8 (&sm->out2in, &kv, 0)) nat_elog_warn ("out2in key del failed"); if (!is_ha) @@ -833,9 +833,8 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, local->fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id, sm->fib_src_low); - init_nat_kv (&kv, m->local_addr, m->local_port, - local->fib_index, m->proto, - m - sm->static_mappings); + init_nat_kv (&kv, m->local_addr, m->local_port, local->fib_index, + m->proto, 0, m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); return 0; } @@ -974,11 +973,11 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, if (!out2in_only) { init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto, - m - sm->static_mappings); + 0, m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); } - init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, + init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0, m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1); @@ -1268,7 +1267,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, else m->affinity_per_service_list_head_index = ~0; - init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, + init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0, m - sm->static_mappings); if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1)) { @@ -1285,7 +1284,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, if (!out2in_only) { init_nat_kv (&kv, locals[i].addr, locals[i].port, - locals[i].fib_index, m->proto, + locals[i].fib_index, m->proto, 0, m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); } @@ -1471,7 +1470,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port, if (!is_out2in_only_static_mapping (m)) { - init_nat_kv (&kv, l_addr, l_port, local->fib_index, proto, + init_nat_kv (&kv, l_addr, l_port, local->fib_index, proto, 0, m - sm->static_mappings); if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1)) nat_elog_err ("static_mapping_by_local key add failed"); @@ -1666,24 +1665,24 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm, vec_free (a->busy_##n##_ports_per_thread); foreach_nat_protocol #undef _ + if (twice_nat) - { - vec_del1 (sm->twice_nat_addresses, i); - return 0; - } - else - vec_del1 (sm->addresses, i); + { + vec_del1 (sm->twice_nat_addresses, i); + return 0; + } + else vec_del1 (sm->addresses, i); /* Delete external address from FIB */ - /* *INDENT-OFF* */ pool_foreach (interface, sm->interfaces) - { - if (nat_interface_is_inside(interface) || sm->out2in_dpo) - continue; + { + if (nat_interface_is_inside (interface) || sm->out2in_dpo) + continue; + + snat_add_del_addr_to_fib (&addr, 32, interface->sw_if_index, 0); + break; + } - snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0); - break; - } pool_foreach (interface, sm->output_feature_interfaces) { if (nat_interface_is_inside(interface) || sm->out2in_dpo) @@ -1692,7 +1691,6 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm, snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0); break; } - /* *INDENT-ON* */ return 0; } diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h index 7fa1ef79c3d..86f6342ab09 100644 --- a/src/plugins/nat/nat.h +++ b/src/plugins/nat/nat.h @@ -492,10 +492,6 @@ typedef struct typedef struct { - /* Main lookup tables */ - clib_bihash_8_8_t out2in; - clib_bihash_8_8_t in2out; - /* Find-a-user => src address lookup */ clib_bihash_8_8_t user_hash; @@ -590,6 +586,10 @@ typedef struct snat_main_s /* Static mapping pool */ snat_static_mapping_t *static_mappings; + /* Endpoint independent lookup tables */ + clib_bihash_8_8_t in2out; + clib_bihash_8_8_t out2in; + /* Endpoint dependent lookup table */ clib_bihash_16_8_t flow_hash; diff --git a/src/plugins/nat/nat44-ei/nat44_ei.c b/src/plugins/nat/nat44-ei/nat44_ei.c index 00aa8e1b65b..34288e14856 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei.c +++ b/src/plugins/nat/nat44-ei/nat44_ei.c @@ -194,15 +194,12 @@ nat44_ei_free_session_data (snat_main_t *sm, snat_session_t *s, { clib_bihash_kv_8_8_t kv; - snat_main_per_thread_data_t *tsm = - vec_elt_at_index (sm->per_thread_data, thread_index); - init_nat_i2o_k (&kv, s); - if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0)) + if (clib_bihash_add_del_8_8 (&sm->in2out, &kv, 0)) nat_elog_warn ("in2out key del failed"); init_nat_o2i_k (&kv, s); - if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0)) + if (clib_bihash_add_del_8_8 (&sm->out2in, &kv, 0)) nat_elog_warn ("out2in key del failed"); if (!is_ha) @@ -709,7 +706,7 @@ nat44_ei_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port, tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers); init_nat_k (&kv, *addr, port, fib_index, proto); - t = is_in ? &tsm->in2out : &tsm->out2in; + t = is_in ? &sm->in2out : &sm->out2in; if (!clib_bihash_search_8_8 (t, &kv, &value)) { if (pool_is_free_index (tsm->sessions, value.value)) @@ -832,7 +829,7 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, local->fib_index = fib_table_find_or_create_and_lock ( FIB_PROTOCOL_IP4, vrf_id, sm->fib_src_low); init_nat_kv (&kv, m->local_addr, m->local_port, local->fib_index, - m->proto, m - sm->static_mappings); + m->proto, 0, m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); return 0; } @@ -956,11 +953,11 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, else tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers); - init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto, + init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto, 0, m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1); - init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, + init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0, m - sm->static_mappings); clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1); @@ -1191,8 +1188,6 @@ nat44_ei_worker_db_free (snat_main_per_thread_data_t *tsm) pool_free (tsm->sessions); pool_free (tsm->users); - clib_bihash_free_8_8 (&tsm->in2out); - clib_bihash_free_8_8 (&tsm->out2in); clib_bihash_free_8_8 (&tsm->user_hash); } @@ -1206,12 +1201,8 @@ nat44_ei_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations, pool_alloc (tsm->lru_pool, translations); pool_alloc (tsm->sessions, translations); - clib_bihash_init_8_8 (&tsm->in2out, "in2out", translation_buckets, 0); - clib_bihash_init_8_8 (&tsm->out2in, "out2in", translation_buckets, 0); clib_bihash_init_8_8 (&tsm->user_hash, "users", user_buckets, 0); - clib_bihash_set_kvp_format_fn_8_8 (&tsm->in2out, format_session_kvp); - clib_bihash_set_kvp_format_fn_8_8 (&tsm->out2in, format_session_kvp); clib_bihash_set_kvp_format_fn_8_8 (&tsm->user_hash, format_user_kvp); pool_get (tsm->lru_pool, head); @@ -1247,6 +1238,8 @@ nat44_ei_db_free () if (sm->pat) { + clib_bihash_free_8_8 (&sm->in2out); + clib_bihash_free_8_8 (&sm->out2in); vec_foreach (tsm, sm->per_thread_data) { nat44_ei_worker_db_free (tsm); @@ -1276,6 +1269,10 @@ nat44_ei_db_init (u32 translations, u32 translation_buckets, u32 user_buckets) if (sm->pat) { + clib_bihash_init_8_8 (&sm->in2out, "in2out", translation_buckets, 0); + clib_bihash_init_8_8 (&sm->out2in, "out2in", translation_buckets, 0); + clib_bihash_set_kvp_format_fn_8_8 (&sm->in2out, format_session_kvp); + clib_bihash_set_kvp_format_fn_8_8 (&sm->out2in, format_session_kvp); vec_foreach (tsm, sm->per_thread_data) { nat44_ei_worker_db_init (tsm, translations, translation_buckets, @@ -1294,6 +1291,12 @@ nat44_ei_sessions_clear () if (sm->pat) { + clib_bihash_free_8_8 (&sm->in2out); + clib_bihash_free_8_8 (&sm->out2in); + clib_bihash_init_8_8 (&sm->in2out, "in2out", nm->translation_buckets, 0); + clib_bihash_init_8_8 (&sm->out2in, "out2in", nm->translation_buckets, 0); + clib_bihash_set_kvp_format_fn_8_8 (&sm->in2out, format_session_kvp); + clib_bihash_set_kvp_format_fn_8_8 (&sm->out2in, format_session_kvp); vec_foreach (tsm, sm->per_thread_data) { nat44_ei_worker_db_free (tsm); diff --git a/src/plugins/nat/nat44-ei/nat44_ei_ha.c b/src/plugins/nat/nat44-ei/nat44_ei_ha.c index 0b904bf079b..aea758af2d4 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei_ha.c +++ b/src/plugins/nat/nat44-ei/nat44_ei_ha.c @@ -241,15 +241,15 @@ nat44_ei_ha_sadd (ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr, } break; } - init_nat_o2i_kv (&kv, s, s - tsm->sessions); - if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 1)) + init_nat_o2i_kv (&kv, s, thread_index, s - tsm->sessions); + if (clib_bihash_add_del_8_8 (&sm->out2in, &kv, 1)) nat_elog_warn ("out2in key add failed"); s->in2out.addr.as_u32 = in_addr->as_u32; s->in2out.port = in_port; s->in2out.fib_index = fib_index; - init_nat_i2o_kv (&kv, s, s - tsm->sessions); - if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 1)) + init_nat_i2o_kv (&kv, s, thread_index, s - tsm->sessions); + if (clib_bihash_add_del_8_8 (&sm->in2out, &kv, 1)) nat_elog_warn ("in2out key add failed"); } @@ -273,10 +273,10 @@ nat44_ei_ha_sdel (ip4_address_t *out_addr, u16 out_port, tsm = vec_elt_at_index (sm->per_thread_data, thread_index); init_nat_k (&kv, *out_addr, out_port, fib_index, proto); - if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv, &value)) return; - s = pool_elt_at_index (tsm->sessions, value.value); + s = pool_elt_at_index (tsm->sessions, nat_value_get_session_index (&value)); nat_free_session_data (sm, s, thread_index, 1); nat44_delete_session (sm, s, thread_index); } @@ -294,10 +294,10 @@ nat44_ei_ha_sref (ip4_address_t *out_addr, u16 out_port, tsm = vec_elt_at_index (sm->per_thread_data, thread_index); init_nat_k (&kv, *out_addr, out_port, fib_index, proto); - if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv, &value)) return; - s = pool_elt_at_index (tsm->sessions, value.value); + s = pool_elt_at_index (tsm->sessions, nat_value_get_session_index (&value)); s->total_pkts = total_pkts; s->total_bytes = total_bytes; } diff --git a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c index 303c588d34e..6a4658513d7 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c +++ b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c @@ -124,8 +124,7 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node, /* NAT packet aimed at external address if */ /* has active sessions */ - if (clib_bihash_search_8_8 (&sm->per_thread_data[thread_index].out2in, &kv0, - &value0)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0)) { /* or is static mappings */ ip4_address_t placeholder_addr; @@ -159,15 +158,13 @@ nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0, init_nat_k (&kv0, ip0->src_address, src_port, ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0); - if (!clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].out2in, &kv0, &value0)) + if (!clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0)) return 1; /* dst NAT check */ init_nat_k (&kv0, ip0->dst_address, dst_port, ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0); - if (!clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].in2out, &kv0, &value0)) + if (!clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0)) { /* hairpinning */ /* *INDENT-OFF* */ @@ -200,7 +197,7 @@ nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg) if (ctx->now >= sess_timeout_time) { init_nat_o2i_k (&s_kv, s); - if (clib_bihash_add_del_8_8 (&tsm->out2in, &s_kv, 0)) + if (clib_bihash_add_del_8_8 (&sm->out2in, &s_kv, 0)) nat_elog_warn ("out2in key del failed"); nat_ipfix_logging_nat44_ses_delete (ctx->thread_index, @@ -354,16 +351,16 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0, /* Add to translation hashes */ ctx0.now = now; ctx0.thread_index = thread_index; - init_nat_i2o_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); - if (clib_bihash_add_or_overwrite_stale_8_8 - (&sm->per_thread_data[thread_index].in2out, &kv0, - nat44_i2o_is_idle_session_cb, &ctx0)) + init_nat_i2o_kv (&kv0, s, thread_index, + s - sm->per_thread_data[thread_index].sessions); + if (clib_bihash_add_or_overwrite_stale_8_8 ( + &sm->in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0)) nat_elog_notice ("in2out key add failed"); - init_nat_o2i_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); - if (clib_bihash_add_or_overwrite_stale_8_8 - (&sm->per_thread_data[thread_index].out2in, &kv0, - nat44_o2i_is_idle_session_cb, &ctx0)) + init_nat_o2i_kv (&kv0, s, thread_index, + s - sm->per_thread_data[thread_index].sessions); + if (clib_bihash_add_or_overwrite_stale_8_8 ( + &sm->out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0)) nat_elog_notice ("out2in key add failed"); /* log NAT event */ @@ -474,7 +471,7 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node, } init_nat_k (&kv0, *addr, *port, *fib_index, *proto); - if (clib_bihash_search_8_8 (&tsm->in2out, &kv0, &value0)) + if (clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0)) { if (vnet_buffer (b0)->sw_if_index[VLIB_TX] != ~0) { @@ -534,7 +531,8 @@ icmp_match_in2out_slow (snat_main_t * sm, vlib_node_runtime_t * node, goto out; } - s0 = pool_elt_at_index (tsm->sessions, value0.value); + s0 = pool_elt_at_index (tsm->sessions, + nat_value_get_session_index (&value0)); } out: @@ -988,9 +986,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, init_nat_k (&kv0, ip0->src_address, vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0, proto0); - if (PREDICT_FALSE - (clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].in2out, &kv0, &value0) != 0)) + if (PREDICT_FALSE (clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0) != + 0)) { if (is_slow_path) { @@ -1043,9 +1040,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } } else - s0 = - pool_elt_at_index (sm->per_thread_data[thread_index].sessions, - value0.value); + s0 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions, + nat_value_get_session_index (&value0)); b0->flags |= VNET_BUFFER_F_IS_NATED; @@ -1212,9 +1208,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, init_nat_k (&kv1, ip1->src_address, vnet_buffer (b1)->ip.reass.l4_src_port, rx_fib_index1, proto1); - if (PREDICT_FALSE - (clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].in2out, &kv1, &value1) != 0)) + if (PREDICT_FALSE (clib_bihash_search_8_8 (&sm->in2out, &kv1, &value1) != + 0)) { if (is_slow_path) { @@ -1267,9 +1262,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } } else - s1 = - pool_elt_at_index (sm->per_thread_data[thread_index].sessions, - value1.value); + s1 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions, + nat_value_get_session_index (&value1)); b1->flags |= VNET_BUFFER_F_IS_NATED; @@ -1463,8 +1457,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0, proto0); - if (clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].in2out, &kv0, &value0)) + if (clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0)) { if (is_slow_path) { @@ -1518,9 +1511,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm, } } else - s0 = - pool_elt_at_index (sm->per_thread_data[thread_index].sessions, - value0.value); + s0 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions, + nat_value_get_session_index (&value0)); b0->flags |= VNET_BUFFER_F_IS_NATED; diff --git a/src/plugins/nat/nat44-ei/nat44_ei_out2in.c b/src/plugins/nat/nat44-ei/nat44_ei_out2in.c index b677e9bde89..f0b6427613a 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei_out2in.c +++ b/src/plugins/nat/nat44-ei/nat44_ei_out2in.c @@ -116,7 +116,7 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg) if (ctx->now >= sess_timeout_time) { init_nat_i2o_k (&s_kv, s); - if (clib_bihash_add_del_8_8 (&tsm->in2out, &s_kv, 0)) + if (clib_bihash_add_del_8_8 (&sm->in2out, &s_kv, 0)) nat_elog_warn ("out2in key del failed"); nat_ipfix_logging_nat44_ses_delete (ctx->thread_index, @@ -222,16 +222,16 @@ create_session_for_static_mapping (snat_main_t * sm, /* Add to translation hashes */ ctx0.now = now; ctx0.thread_index = thread_index; - init_nat_i2o_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); - if (clib_bihash_add_or_overwrite_stale_8_8 - (&sm->per_thread_data[thread_index].in2out, &kv0, - nat44_i2o_is_idle_session_cb, &ctx0)) + init_nat_i2o_kv (&kv0, s, thread_index, + s - sm->per_thread_data[thread_index].sessions); + if (clib_bihash_add_or_overwrite_stale_8_8 ( + &sm->in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0)) nat_elog_notice ("in2out key add failed"); - init_nat_o2i_kv (&kv0, s, s - sm->per_thread_data[thread_index].sessions); - if (clib_bihash_add_or_overwrite_stale_8_8 - (&sm->per_thread_data[thread_index].out2in, &kv0, - nat44_o2i_is_idle_session_cb, &ctx0)) + init_nat_o2i_kv (&kv0, s, thread_index, + s - sm->per_thread_data[thread_index].sessions); + if (clib_bihash_add_or_overwrite_stale_8_8 ( + &sm->out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0)) nat_elog_notice ("out2in key add failed"); /* log NAT event */ @@ -351,7 +351,7 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, u32 mapping_fib_index; init_nat_k (&kv0, *addr, *port, *fib_index, *proto); - if (clib_bihash_search_8_8 (&tsm->out2in, &kv0, &value0)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0)) { /* Try to match static mapping by external address and port, destination address and port in packet */ @@ -423,7 +423,8 @@ icmp_match_out2in_slow (snat_main_t * sm, vlib_node_runtime_t * node, goto out; } - s0 = pool_elt_at_index (tsm->sessions, value0.value); + s0 = pool_elt_at_index (tsm->sessions, + nat_value_get_session_index (&value0)); } out: @@ -823,8 +824,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, init_nat_k (&kv0, ip0->dst_address, vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, proto0); - if (clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].out2in, &kv0, &value0)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0)) { /* Try to match static mapping by external address and port, destination address and port in packet */ @@ -873,7 +873,8 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, } } else - s0 = pool_elt_at_index (tsm->sessions, value0.value); + s0 = pool_elt_at_index (tsm->sessions, + nat_value_get_session_index (&value0)); old_addr0 = ip0->dst_address.as_u32; ip0->dst_address = s0->in2out.addr; @@ -1002,8 +1003,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, init_nat_k (&kv1, ip1->dst_address, vnet_buffer (b1)->ip.reass.l4_dst_port, rx_fib_index1, proto1); - if (clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].out2in, &kv1, &value1)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv1, &value1)) { /* Try to match static mapping by external address and port, destination address and port in packet */ @@ -1052,9 +1052,8 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, } } else - s1 = - pool_elt_at_index (sm->per_thread_data[thread_index].sessions, - value1.value); + s1 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions, + nat_value_get_session_index (&value1)); old_addr1 = ip1->dst_address.as_u32; ip1->dst_address = s1->in2out.addr; @@ -1219,8 +1218,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, proto0); - if (clib_bihash_search_8_8 - (&sm->per_thread_data[thread_index].out2in, &kv0, &value0)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0)) { /* Try to match static mapping by external address and port, destination address and port in packet */ @@ -1269,9 +1267,8 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm, } } else - s0 = - pool_elt_at_index (sm->per_thread_data[thread_index].sessions, - value0.value); + s0 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions, + nat_value_get_session_index (&value0)); old_addr0 = ip0->dst_address.as_u32; ip0->dst_address = s0->in2out.addr; diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44_cli.c index d1a08718ed7..c89963ec85a 100644 --- a/src/plugins/nat/nat44_cli.c +++ b/src/plugins/nat/nat44_cli.c @@ -300,22 +300,20 @@ nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->static_mapping_by_external, verbose); - vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose); + if (sm->endpoint_dependent) + { + vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose); + } + else + { + vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->in2out, verbose); + vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->out2in, verbose); + } vec_foreach_index (i, sm->per_thread_data) { tsm = vec_elt_at_index (sm->per_thread_data, i); vlib_cli_output (vm, "-------- thread %d %s --------\n", i, vlib_worker_threads[i].name); - if (sm->endpoint_dependent) - { - vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, - verbose); - } - else - { - vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->in2out, verbose); - vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->out2in, verbose); - } vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->user_hash, verbose); } diff --git a/src/plugins/nat/nat44_hairpinning.c b/src/plugins/nat/nat44_hairpinning.c index 37dfd7827f6..f458909df20 100644 --- a/src/plugins/nat/nat44_hairpinning.c +++ b/src/plugins/nat/nat44_hairpinning.c @@ -129,15 +129,14 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm, init_nat_k (&kv0, ip0->dst_address, udp0->dst_port, sm->outside_fib_index, proto0); - rv = clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0, - &value0); + rv = clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0); if (rv) { rv = 0; goto trace; } - si = value0.value; + si = nat_value_get_session_index (&value0); s0 = pool_elt_at_index (sm->per_thread_data[ti].sessions, si); new_dst_addr0 = s0->in2out.addr.as_u32; new_dst_port0 = s0->in2out.port; @@ -249,10 +248,9 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, init_nat_k (&kv0, ip0->dst_address, l4_header->src_port, sm->outside_fib_index, protocol); - if (clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, &kv0, - &value0)) + if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0)) return 1; - si = value0.value; + si = nat_value_get_session_index (&value0); s0 = pool_elt_at_index (sm->per_thread_data[ti].sessions, si); new_dst_addr0 = s0->in2out.addr.as_u32; vnet_buffer (b0)->sw_if_index[VLIB_TX] = s0->in2out.fib_index; @@ -290,8 +288,8 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, else { init_nat_k (&kv0, ip0->dst_address, 0, sm->outside_fib_index, 0); - if (clib_bihash_search_8_8 - (&sm->static_mapping_by_external, &kv0, &value0)) + if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0, + &value0)) { icmp_echo_header_t *echo0 = (icmp_echo_header_t *) (icmp0 + 1); u16 icmp_id0 = echo0->identifier; @@ -302,11 +300,10 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0, (clib_net_to_host_u16 (icmp_id0) - 1024) / sm->port_per_thread; else ti = sm->num_workers; - int rv = clib_bihash_search_8_8 (&sm->per_thread_data[ti].out2in, - &kv0, &value0); + int rv = clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0); if (!rv) { - si = value0.value; + si = nat_value_get_session_index (&value0); s0 = pool_elt_at_index (sm->per_thread_data[ti].sessions, si); new_dst_addr0 = s0->in2out.addr.as_u32; vnet_buffer (b0)->sw_if_index[VLIB_TX] = s0->in2out.fib_index; diff --git a/src/plugins/nat/nat_inlines.h b/src/plugins/nat/nat_inlines.h index 3408e533f69..d53e2453607 100644 --- a/src/plugins/nat/nat_inlines.h +++ b/src/plugins/nat/nat_inlines.h @@ -63,11 +63,12 @@ init_nat_k (clib_bihash_kv_8_8_t * kv, ip4_address_t addr, u16 port, } always_inline void -init_nat_kv (clib_bihash_kv_8_8_t * kv, ip4_address_t addr, u16 port, - u32 fib_index, nat_protocol_t proto, u64 value) +init_nat_kv (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port, + u32 fib_index, nat_protocol_t proto, u32 thread_index, + u32 session_index) { init_nat_k (kv, addr, port, fib_index, proto); - kv->value = value; + kv->value = (u64) thread_index << 32 | session_index; } always_inline void @@ -78,11 +79,12 @@ init_nat_i2o_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s) } always_inline void -init_nat_i2o_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value) +init_nat_i2o_kv (clib_bihash_kv_8_8_t *kv, snat_session_t *s, u32 thread_index, + u32 session_index) { init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index, s->nat_proto); - kv->value = value; + kv->value = (u64) thread_index << 32 | session_index; } always_inline void @@ -93,11 +95,24 @@ init_nat_o2i_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s) } always_inline void -init_nat_o2i_kv (clib_bihash_kv_8_8_t * kv, snat_session_t * s, u64 value) +init_nat_o2i_kv (clib_bihash_kv_8_8_t *kv, snat_session_t *s, u32 thread_index, + u32 session_index) { init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index, s->nat_proto); - kv->value = value; + kv->value = (u64) thread_index << 32 | session_index; +} + +always_inline u32 +nat_value_get_thread_index (clib_bihash_kv_8_8_t *value) +{ + return value->value >> 32; +} + +always_inline u32 +nat_value_get_session_index (clib_bihash_kv_8_8_t *value) +{ + return value->value & ~(u32) 0; } static inline uword -- cgit 1.2.3-korg