.description = "Network Address Translation (NAT)",
};
-static void nat44_ed_db_init (u32 translations, u32 translation_buckets);
+static void nat44_ed_db_init ();
+static void nat44_ed_db_free ();
static void nat44_ed_worker_db_free (snat_main_per_thread_data_t *tsm);
static int nat44_ed_add_static_mapping_internal (
sm->outside_fib_index = fib_table_find_or_create_and_lock (
FIB_PROTOCOL_IP4, c.outside_vrf, sm->fib_src_hi);
- nat44_ed_db_init (sm->max_translations_per_thread, sm->translation_buckets);
+ nat44_ed_db_init ();
nat_affinity_enable ();
int
nat44_plugin_disable ()
{
- snat_main_per_thread_data_t *tsm;
snat_main_t *sm = &snat_main;
int rc, error = 0;
vec_free (sm->max_translations_per_fib);
sm->max_translations_per_fib = 0;
- clib_bihash_free_16_8 (&sm->flow_hash);
-
- vec_foreach (tsm, sm->per_thread_data)
- {
- nat44_ed_worker_db_free (tsm);
- }
+ nat44_ed_db_free ();
clib_memset (&sm->rconfig, 0, sizeof (sm->rconfig));
}
hash = ip->src_address.as_u32 + (ip->src_address.as_u32 >> 8) +
- (ip->src_address.as_u32 >> 16) + (ip->src_address.as_u32 >> 24);
+ (ip->src_address.as_u32 >> 16) + (ip->src_address.as_u32 >> 24) +
+ rx_fib_index + (rx_fib_index >> 8) + (rx_fib_index >> 16) +
+ (rx_fib_index >> 24);
if (PREDICT_TRUE (is_pow2 (_vec_len (sm->workers))))
next_worker_index += sm->workers[hash & (_vec_len (sm->workers) - 1)];
}
static void
-nat44_ed_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations,
- u32 translation_buckets)
+nat44_ed_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations)
{
dlist_elt_t *head;
+ pool_alloc (tsm->per_vrf_sessions_pool, translations);
pool_alloc (tsm->sessions, translations);
pool_alloc (tsm->lru_pool, translations);
}
static void
-reinit_ed_flow_hash ()
+nat44_ed_flow_hash_init ()
{
snat_main_t *sm = &snat_main;
// we expect 2 flows per session, so multiply translation_buckets by 2
}
static void
-nat44_ed_db_init (u32 translations, u32 translation_buckets)
+nat44_ed_db_init ()
{
snat_main_t *sm = &snat_main;
snat_main_per_thread_data_t *tsm;
- reinit_ed_flow_hash ();
+ nat44_ed_flow_hash_init ();
vec_foreach (tsm, sm->per_thread_data)
{
- nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
- sm->translation_buckets);
+ nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread);
}
}
pool_free (tsm->per_vrf_sessions_pool);
}
-void
-nat44_ed_sessions_clear ()
+static void
+nat44_ed_flow_hash_free ()
{
snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
- reinit_ed_flow_hash ();
+ clib_bihash_free_16_8 (&sm->flow_hash);
+}
+
+static void
+nat44_ed_db_free ()
+{
+ snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm;
vec_foreach (tsm, sm->per_thread_data)
{
nat44_ed_worker_db_free (tsm);
- nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
- sm->translation_buckets);
}
+
+ nat44_ed_flow_hash_free ();
+}
+
+void
+nat44_ed_sessions_clear ()
+{
+ snat_main_t *sm = &snat_main;
+
+ nat44_ed_db_free ();
+ nat44_ed_db_init ();
vlib_zero_simple_counter (&sm->total_sessions, 0);
}
idaddr, idport, xdaddr, xdport, proto, 0,
is_twicenat);
}
+__clib_export void
+nat44_original_dst_lookup (ip4_address_t *i2o_src, u16 i2o_src_port,
+ ip4_address_t *i2o_dst, u16 i2o_dst_port,
+ ip_protocol_t proto, u32 *original_dst,
+ u16 *original_dst_port)
+{
+ snat_main_per_thread_data_t *tsm;
+ snat_main_t *sm = &snat_main;
+ u32 fib_index = 0;
+ snat_session_t *s;
+ ip4_header_t ip;
+
+ ip.src_address.as_u32 = i2o_src->as_u32;
+ fib_index = fib_table_find (FIB_PROTOCOL_IP4, 0);
+ if (sm->num_workers > 1)
+ {
+ tsm = vec_elt_at_index (
+ sm->per_thread_data,
+ nat44_ed_get_in2out_worker_index (0, &ip, fib_index, 0));
+ }
+ else
+ {
+ tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ }
+
+ /* query */
+ clib_bihash_kv_16_8_t kv = { 0 }, value;
+ init_ed_k (&kv, i2o_src->as_u32, i2o_src_port, i2o_dst->as_u32, i2o_dst_port,
+ fib_index, proto);
+ if (tsm->sessions == NULL ||
+ clib_bihash_search_16_8 (&sm->flow_hash, &kv, &value))
+ {
+ return;
+ }
+ s = pool_elt_at_index (tsm->sessions, ed_value_get_session_index (&value));
+ if (s)
+ {
+ *original_dst = s->i2o.rewrite.saddr.as_u32;
+ *original_dst_port = s->i2o.rewrite.sport;
+ }
+ return;
+}
/*
* fd.io coding-style-patch-verification: ON
*