#include <nat/nat_inlines.h>
#include <nat/nat_affinity.h>
#include <nat/nat_syslog.h>
+#include <nat/nat_ha.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/ip4_fib.h>
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
- .description = "Network Address Translation",
+ .description = "Network Address Translation (NAT)",
};
/* *INDENT-ON* */
void
-nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index)
+nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
+ u8 is_ha)
{
snat_session_key_t key;
clib_bihash_kv_8_8_t kv;
if (is_fwd_bypass_session (s))
{
+ if (snat_is_unk_proto_session (s))
+ {
+ ed_key.proto = s->in2out.port;
+ ed_key.r_port = 0;
+ ed_key.l_port = 0;
+ }
+ else
+ {
+ ed_key.proto = snat_proto_to_ip_proto (s->in2out.protocol);
+ ed_key.l_port = s->in2out.port;
+ ed_key.r_port = s->ext_host_port;
+ }
ed_key.l_addr = s->in2out.addr;
ed_key.r_addr = s->ext_host_addr;
- ed_key.l_port = s->in2out.port;
- ed_key.r_port = s->ext_host_port;
- ed_key.proto = snat_proto_to_ip_proto (s->in2out.protocol);
ed_key.fib_index = 0;
ed_kv.key[0] = ed_key.as_u64[0];
ed_kv.key[1] = ed_key.as_u64[1];
if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &ed_kv, 0))
nat_log_warn ("in2out_ed key del failed");
- nat_syslog_nat44_sdel (s->user_index, s->in2out.fib_index,
- &s->in2out.addr, s->in2out.port,
- &s->ext_host_nat_addr, s->ext_host_nat_port,
- &s->out2in.addr, s->out2in.port,
- &s->ext_host_addr, s->ext_host_port,
- s->in2out.protocol, is_twice_nat_session (s));
+ if (!is_ha)
+ nat_syslog_nat44_sdel (s->user_index, s->in2out.fib_index,
+ &s->in2out.addr, s->in2out.port,
+ &s->ext_host_nat_addr, s->ext_host_nat_port,
+ &s->out2in.addr, s->out2in.port,
+ &s->ext_host_addr, s->ext_host_port,
+ s->in2out.protocol, is_twice_nat_session (s));
}
else
{
if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 0))
nat_log_warn ("out2in key del failed");
- nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
- &s->in2out.addr, s->in2out.port,
- &s->out2in.addr, s->out2in.port,
- s->in2out.protocol);
+ if (!is_ha)
+ nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
+ &s->in2out.addr, s->in2out.port,
+ &s->out2in.addr, s->out2in.port,
+ s->in2out.protocol);
}
if (snat_is_unk_proto_session (s))
return;
- /* log NAT event */
- snat_ipfix_logging_nat44_ses_delete (thread_index,
- s->in2out.addr.as_u32,
- s->out2in.addr.as_u32,
- s->in2out.protocol,
- s->in2out.port,
- s->out2in.port, s->in2out.fib_index);
+ if (!is_ha)
+ {
+ /* log NAT event */
+ snat_ipfix_logging_nat44_ses_delete (thread_index,
+ s->in2out.addr.as_u32,
+ s->out2in.addr.as_u32,
+ s->in2out.protocol,
+ s->in2out.port,
+ s->out2in.port,
+ s->in2out.fib_index);
+
+ nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
+ s->ext_host_port, s->out2in.protocol, s->out2in.fib_index,
+ thread_index);
+ }
/* Twice NAT address and port for external host */
if (is_twice_nat_session (s))
snat_session_t *
nat_session_alloc_or_recycle (snat_main_t * sm, snat_user_t * u,
- u32 thread_index)
+ u32 thread_index, f64 now)
{
snat_session_t *s;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
/* Get the session */
s = pool_elt_at_index (tsm->sessions, session_index);
- nat_free_session_data (sm, s, thread_index);
+ nat_free_session_data (sm, s, thread_index, 0);
if (snat_is_session_static (s))
u->nstaticsessions--;
else
pool_elts (tsm->sessions));
}
+ s->ha_last_refreshed = now;
+
return s;
}
{
clib_dlist_addtail (tsm->list_pool,
u->sessions_per_user_list_head_index, oldest_index);
- nat_free_session_data (sm, s, thread_index);
+ nat_free_session_data (sm, s, thread_index, 0);
if (snat_is_session_static (s))
u->nstaticsessions--;
else
pool_elts (tsm->sessions));
}
+ s->ha_last_refreshed = now;
+
return s;
}
if (!addr_only)
{
- if (rp->l_port != l_port || rp->e_port != e_port
+ if ((rp->l_port != l_port && rp->e_port != e_port)
|| rp->proto != proto)
continue;
}
continue;
nat_free_session_data (sm, s,
- tsm - sm->per_thread_data);
+ tsm - sm->per_thread_data, 0);
nat44_delete_session (sm, s, tsm - sm->per_thread_data);
if (!addr_only && !sm->endpoint_dependent)
continue;
nat_free_session_data (sm, s,
- tsm - sm->per_thread_data);
+ tsm - sm->per_thread_data, 0);
nat44_delete_session (sm, s, tsm - sm->per_thread_data);
if (!addr_only && !sm->endpoint_dependent)
(clib_net_to_host_u16 (s->in2out.port) != local->port))
continue;
- nat_free_session_data (sm, s, tsm - sm->per_thread_data);
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
nat44_delete_session (sm, s, tsm - sm->per_thread_data);
}
}
match_local->port))
continue;
- nat_free_session_data (sm, s, tsm - sm->per_thread_data);
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
nat44_delete_session (sm, s, tsm - sm->per_thread_data);
}
}
pool_foreach (ses, tsm->sessions, ({
if (ses->out2in.addr.as_u32 == addr.as_u32)
{
- nat_free_session_data (sm, ses, tsm - sm->per_thread_data);
+ nat_free_session_data (sm, ses, tsm - sm->per_thread_data, 0);
vec_add1 (ses_to_be_removed, ses - tsm->sessions);
}
}));
uword *bitmap = 0;
u32 i;
ip4_add_del_interface_address_callback_t cb4;
- vlib_node_t *error_drop_node;
+ vlib_node_t *node;
sm->vlib_main = vm;
sm->vnet_main = vnet_get_main ();
sm->workers = 0;
sm->port_per_thread = 0xffff - 1024;
sm->fq_in2out_index = ~0;
+ sm->fq_in2out_output_index = ~0;
sm->fq_out2in_index = ~0;
sm->udp_timeout = SNAT_UDP_TIMEOUT;
sm->tcp_established_timeout = SNAT_TCP_ESTABLISHED_TIMEOUT;
sm->addr_and_port_alloc_alg = NAT_ADDR_AND_PORT_ALLOC_ALG_DEFAULT;
sm->forwarding_enabled = 0;
sm->log_class = vlib_log_register_class ("nat", 0);
- error_drop_node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
- sm->error_node_index = error_drop_node->index;
sm->mss_clamping = 0;
+ node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
+ sm->error_node_index = node->index;
+
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out");
+ sm->in2out_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-output");
+ sm->in2out_output_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-fast");
+ sm->in2out_fast_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-slowpath");
+ sm->in2out_slowpath_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-output-slowpath");
+ sm->in2out_slowpath_output_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-reass");
+ sm->in2out_reass_node_index = node->index;
+
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out");
+ sm->ed_in2out_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out-slowpath");
+ sm->ed_in2out_slowpath_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out-reass");
+ sm->ed_in2out_reass_node_index = node->index;
+
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-out2in");
+ sm->out2in_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-out2in-fast");
+ sm->out2in_fast_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-out2in-reass");
+ sm->out2in_reass_node_index = node->index;
+
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in");
+ sm->ed_out2in_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in-slowpath");
+ sm->ed_out2in_slowpath_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in-reass");
+ sm->ed_out2in_reass_node_index = node->index;
+
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-det-in2out");
+ sm->det_in2out_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-det-out2in");
+ sm->det_out2in_node_index = node->index;
+
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpinning");
+ sm->hairpinning_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpin-dst");
+ sm->hairpin_dst_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpin-src");
+ sm->hairpin_src_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-hairpinning");
+ sm->ed_hairpinning_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-hairpin-dst");
+ sm->ed_hairpin_dst_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-hairpin-src");
+ sm->ed_hairpin_src_node_index = node->index;
+
p = hash_get_mem (tm->thread_registrations_by_name, "workers");
if (p)
{
dslite_init (vm);
- nat66_init ();
+ nat66_init (vm);
ip4_table_bind_callback_t cbt4 = {
.function = snat_ip4_table_bind,
}
}
+static int
+nat_set_outside_address_and_port (snat_address_t * addresses,
+ u32 thread_index, snat_session_key_t * k)
+{
+ snat_address_t *a = 0;
+ u32 address_index;
+ u16 port_host_byte_order = clib_net_to_host_u16 (k->port);
+
+ for (address_index = 0; address_index < vec_len (addresses);
+ address_index++)
+ {
+ if (addresses[address_index].addr.as_u32 != k->addr.as_u32)
+ continue;
+
+ a = addresses + address_index;
+ switch (k->protocol)
+ {
+#define _(N, j, n, s) \
+ case SNAT_PROTOCOL_##N: \
+ if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, port_host_byte_order)) \
+ return VNET_API_ERROR_INSTANCE_IN_USE; \
+ clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, port_host_byte_order, 1); \
+ a->busy_##n##_ports_per_thread[thread_index]++; \
+ a->busy_##n##_ports++; \
+ return 0;
+ foreach_snat_protocol
+#undef _
+ default:
+ nat_log_info ("unknown protocol");
+ return 1;
+ }
+ }
+
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+}
+
int
snat_static_mapping_match (snat_main_t * sm,
snat_session_key_t match,
return next_worker_index;
}
+void
+nat_ha_sadd_cb (ip4_address_t * in_addr, u16 in_port,
+ ip4_address_t * out_addr, u16 out_port,
+ ip4_address_t * eh_addr, u16 eh_port,
+ ip4_address_t * ehn_addr, u16 ehn_port, u8 proto,
+ u32 fib_index, u16 flags, u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_session_key_t key;
+ snat_user_t *u;
+ snat_session_t *s;
+ clib_bihash_kv_8_8_t kv;
+ f64 now = vlib_time_now (sm->vlib_main);
+ nat_outside_fib_t *outside_fib;
+ fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
+ snat_main_per_thread_data_t *tsm;
+ fib_prefix_t pfx = {
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_len = 32,
+ .fp_addr = {
+ .ip4.as_u32 = eh_addr->as_u32,
+ },
+ };
+
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+
+ key.addr.as_u32 = out_addr->as_u32;
+ key.port = out_port;
+ key.protocol = proto;
+
+ if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING))
+ {
+ if (nat_set_outside_address_and_port
+ (sm->addresses, thread_index, &key))
+ return;
+ }
+
+ u = nat_user_get_or_create (sm, in_addr, fib_index, thread_index);
+ if (!u)
+ return;
+
+ s = nat_session_alloc_or_recycle (sm, u, thread_index, now);
+ if (!s)
+ return;
+
+ s->last_heard = now;
+ s->flags = flags;
+ s->ext_host_addr.as_u32 = eh_addr->as_u32;
+ s->ext_host_port = eh_port;
+ user_session_increment (sm, u, snat_is_session_static (s));
+ switch (vec_len (sm->outside_fibs))
+ {
+ case 0:
+ key.fib_index = sm->outside_fib_index;
+ break;
+ case 1:
+ key.fib_index = sm->outside_fibs[0].fib_index;
+ break;
+ default:
+ /* *INDENT-OFF* */
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ fei = fib_table_lookup (outside_fib->fib_index, &pfx);
+ if (FIB_NODE_INDEX_INVALID != fei)
+ {
+ if (fib_entry_get_resolving_interface (fei) != ~0)
+ {
+ key.fib_index = outside_fib->fib_index;
+ break;
+ }
+ }
+ }
+ /* *INDENT-ON* */
+ break;
+ }
+ s->out2in = key;
+ kv.key = key.as_u64;
+ kv.value = s - tsm->sessions;
+ if (clib_bihash_add_del_8_8 (&tsm->out2in, &kv, 1))
+ nat_log_warn ("out2in key add failed");
+
+ key.addr.as_u32 = in_addr->as_u32;
+ key.port = in_port;
+ key.fib_index = fib_index;
+ s->in2out = key;
+ kv.key = key.as_u64;
+ if (clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 1))
+ nat_log_warn ("in2out key add failed");
+}
+
+void
+nat_ha_sdel_cb (ip4_address_t * out_addr, u16 out_port,
+ ip4_address_t * eh_addr, u16 eh_port, u8 proto, u32 fib_index,
+ u32 ti)
+{
+ snat_main_t *sm = &snat_main;
+ snat_session_key_t key;
+ clib_bihash_kv_8_8_t kv, value;
+ u32 thread_index;
+ snat_session_t *s;
+ snat_main_per_thread_data_t *tsm;
+
+ if (sm->num_workers > 1)
+ thread_index =
+ sm->first_worker_index +
+ (sm->workers[(clib_net_to_host_u16 (out_port) -
+ 1024) / sm->port_per_thread]);
+ else
+ thread_index = sm->num_workers;
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+
+ key.addr.as_u32 = out_addr->as_u32;
+ key.port = out_port;
+ key.protocol = proto;
+ key.fib_index = fib_index;
+ kv.key = key.as_u64;
+ if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value))
+ return;
+
+ s = pool_elt_at_index (tsm->sessions, value.value);
+ nat_free_session_data (sm, s, thread_index, 1);
+ nat44_delete_session (sm, s, thread_index);
+}
+
+void
+nat_ha_sref_cb (ip4_address_t * out_addr, u16 out_port,
+ ip4_address_t * eh_addr, u16 eh_port, u8 proto, u32 fib_index,
+ u32 total_pkts, u64 total_bytes, u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_session_key_t key;
+ clib_bihash_kv_8_8_t kv, value;
+ snat_session_t *s;
+ snat_main_per_thread_data_t *tsm;
+
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+
+ key.addr.as_u32 = out_addr->as_u32;
+ key.port = out_port;
+ key.protocol = proto;
+ key.fib_index = fib_index;
+ kv.key = key.as_u64;
+ if (clib_bihash_search_8_8 (&tsm->out2in, &kv, &value))
+ return;
+
+ s = pool_elt_at_index (tsm->sessions, value.value);
+ s->total_pkts = total_pkts;
+ s->total_bytes = total_bytes;
+}
+
+void
+nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
+ ip4_address_t * out_addr, u16 out_port,
+ ip4_address_t * eh_addr, u16 eh_port,
+ ip4_address_t * ehn_addr, u16 ehn_port, u8 proto,
+ u32 fib_index, u16 flags, u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_session_key_t key;
+ snat_user_t *u;
+ snat_session_t *s;
+ clib_bihash_kv_16_8_t kv;
+ f64 now = vlib_time_now (sm->vlib_main);
+ nat_outside_fib_t *outside_fib;
+ fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
+ snat_main_per_thread_data_t *tsm;
+ fib_prefix_t pfx = {
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_len = 32,
+ .fp_addr = {
+ .ip4.as_u32 = eh_addr->as_u32,
+ },
+ };
+
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+
+ key.addr.as_u32 = out_addr->as_u32;
+ key.port = out_port;
+ key.protocol = proto;
+
+ if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING))
+ {
+ if (nat_set_outside_address_and_port
+ (sm->addresses, thread_index, &key))
+ return;
+ }
+
+ key.addr.as_u32 = ehn_addr->as_u32;
+ key.port = ehn_port;
+ if (flags & SNAT_SESSION_FLAG_TWICE_NAT)
+ {
+ if (nat_set_outside_address_and_port
+ (sm->twice_nat_addresses, thread_index, &key))
+ return;
+ }
+
+ u = nat_user_get_or_create (sm, in_addr, fib_index, thread_index);
+ if (!u)
+ return;
+
+ s = nat_ed_session_alloc (sm, u, thread_index, now);
+ if (!s)
+ return;
+
+ s->last_heard = now;
+ s->flags = flags;
+ s->ext_host_nat_addr.as_u32 = s->ext_host_addr.as_u32 = eh_addr->as_u32;
+ s->ext_host_nat_port = s->ext_host_port = eh_port;
+ if (is_twice_nat_session (s))
+ {
+ s->ext_host_nat_addr.as_u32 = ehn_addr->as_u32;
+ s->ext_host_nat_port = ehn_port;
+ }
+ user_session_increment (sm, u, snat_is_session_static (s));
+ switch (vec_len (sm->outside_fibs))
+ {
+ case 0:
+ key.fib_index = sm->outside_fib_index;
+ break;
+ case 1:
+ key.fib_index = sm->outside_fibs[0].fib_index;
+ break;
+ default:
+ /* *INDENT-OFF* */
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ fei = fib_table_lookup (outside_fib->fib_index, &pfx);
+ if (FIB_NODE_INDEX_INVALID != fei)
+ {
+ if (fib_entry_get_resolving_interface (fei) != ~0)
+ {
+ key.fib_index = outside_fib->fib_index;
+ break;
+ }
+ }
+ }
+ /* *INDENT-ON* */
+ break;
+ }
+ key.addr.as_u32 = out_addr->as_u32;
+ key.port = out_port;
+ s->out2in = key;
+ kv.value = s - tsm->sessions;
+
+ key.addr.as_u32 = in_addr->as_u32;
+ key.port = in_port;
+ key.fib_index = fib_index;
+ s->in2out = key;
+
+ make_ed_kv (&kv, in_addr, &s->ext_host_nat_addr,
+ snat_proto_to_ip_proto (proto), fib_index, in_port,
+ s->ext_host_nat_port);
+ if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
+ nat_log_warn ("in2out key add failed");
+
+ make_ed_kv (&kv, out_addr, eh_addr, snat_proto_to_ip_proto (proto),
+ s->out2in.fib_index, out_port, eh_port);
+ if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &kv, 1))
+ nat_log_warn ("out2in key add failed");
+}
+
+void
+nat_ha_sdel_ed_cb (ip4_address_t * out_addr, u16 out_port,
+ ip4_address_t * eh_addr, u16 eh_port, u8 proto,
+ u32 fib_index, u32 ti)
+{
+ snat_main_t *sm = &snat_main;
+ nat_ed_ses_key_t key;
+ clib_bihash_kv_16_8_t kv, value;
+ u32 thread_index;
+ snat_session_t *s;
+ snat_main_per_thread_data_t *tsm;
+
+ if (sm->num_workers > 1)
+ thread_index =
+ sm->first_worker_index +
+ (sm->workers[(clib_net_to_host_u16 (out_port) -
+ 1024) / sm->port_per_thread]);
+ else
+ thread_index = sm->num_workers;
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+
+ key.l_addr.as_u32 = out_addr->as_u32;
+ key.l_port = out_port;
+ key.r_addr.as_u32 = eh_addr->as_u32;
+ key.r_port = eh_port;
+ key.proto = proto;
+ key.fib_index = fib_index;
+ kv.key[0] = key.as_u64[0];
+ kv.key[1] = key.as_u64[1];
+ if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
+ return;
+
+ s = pool_elt_at_index (tsm->sessions, value.value);
+ nat_free_session_data (sm, s, thread_index, 1);
+ nat44_delete_session (sm, s, thread_index);
+}
+
+void
+nat_ha_sref_ed_cb (ip4_address_t * out_addr, u16 out_port,
+ ip4_address_t * eh_addr, u16 eh_port, u8 proto,
+ u32 fib_index, u32 total_pkts, u64 total_bytes,
+ u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ nat_ed_ses_key_t key;
+ clib_bihash_kv_16_8_t kv, value;
+ snat_session_t *s;
+ snat_main_per_thread_data_t *tsm;
+
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+
+ key.l_addr.as_u32 = out_addr->as_u32;
+ key.l_port = out_port;
+ key.r_addr.as_u32 = eh_addr->as_u32;
+ key.r_port = eh_port;
+ key.proto = proto;
+ key.fib_index = fib_index;
+ kv.key[0] = key.as_u64[0];
+ kv.key[1] = key.as_u64[1];
+ if (clib_bihash_search_16_8 (&tsm->out2in_ed, &kv, &value))
+ return;
+
+ s = pool_elt_at_index (tsm->sessions, value.value);
+ s->total_pkts = total_pkts;
+ s->total_bytes = total_bytes;
+}
+
static clib_error_t *
snat_config (vlib_main_t * vm, unformat_input_t * input)
{
sm->icmp_match_in2out_cb = icmp_match_in2out_ed;
sm->icmp_match_out2in_cb = icmp_match_out2in_ed;
nat_affinity_init (vm);
+ nat_ha_init (vm, nat_ha_sadd_ed_cb, nat_ha_sdel_ed_cb,
+ nat_ha_sref_ed_cb);
}
else
{
sm->out2in_node_index = snat_out2in_node.index;
sm->icmp_match_in2out_cb = icmp_match_in2out_slow;
sm->icmp_match_out2in_cb = icmp_match_out2in_slow;
+ nat_ha_init (vm, nat_ha_sadd_cb, nat_ha_sdel_cb, nat_ha_sref_cb);
}
if (!static_mapping_only ||
(static_mapping_only && static_mapping_connection_tracking))
return VNET_API_ERROR_UNSPECIFIED;
s = pool_elt_at_index (tsm->sessions, value.value);
- nat_free_session_data (sm, s, tsm - sm->per_thread_data);
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
nat44_delete_session (sm, s, tsm - sm->per_thread_data);
return 0;
}
if (pool_is_free_index (tsm->sessions, value.value))
return VNET_API_ERROR_UNSPECIFIED;
s = pool_elt_at_index (tsm->sessions, value.value);
- nat_free_session_data (sm, s, tsm - sm->per_thread_data);
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
nat44_delete_session (sm, s, tsm - sm->per_thread_data);
return 0;
}