X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat.c;h=ae34f235a3d8762e8dd0e95047dc3d3257b99632;hb=70a26ac05f2ab9d4cc0669599b09f654de580f36;hp=8e4d9df929cea5adf69faa50ae191d0d69eb762b;hpb=35dfedc55fe40c781278ca04789b5ecc4c56e9c2;p=vpp.git diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index 8e4d9df929c..ae34f235a3d 100755 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -329,10 +329,19 @@ nat_session_alloc_or_recycle (snat_main_t *sm, snat_user_t *u, u32 thread_index) /* Get the session */ s = pool_elt_at_index (tsm->sessions, session_index); nat_free_session_data (sm, s, thread_index); + if (snat_is_session_static(s)) + u->nstaticsessions--; + else + u->nsessions--; s->outside_address_index = ~0; s->flags = 0; s->total_bytes = 0; s->total_pkts = 0; + s->state = 0; + s->ext_host_addr.as_u32 = 0; + s->ext_host_port = 0; + s->ext_host_nat_addr.as_u32 = 0; + s->ext_host_nat_port = 0; } else { @@ -917,7 +926,7 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 1); if (twice_nat || out2in_only) { - m_key.port = clib_host_to_net_u16 (l_port); + m_key.port = clib_host_to_net_u16 (m->local_port); kv.key = m_key.as_u64; kv.value = ~0ULL; if (clib_bihash_add_del_8_8(&tsm->in2out, &kv, 1)) @@ -965,12 +974,8 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, if (snat_is_session_static (s)) continue; - if (!addr_only) - { - if ((s->out2in.addr.as_u32 != e_addr.as_u32) && - (clib_net_to_host_u16 (s->out2in.port) != e_port)) - continue; - } + if (!addr_only && (clib_net_to_host_u16 (s->in2out.port) != m->local_port)) + continue; nat_free_session_data (sm, s, tsm - sm->per_thread_data); clib_dlist_remove (tsm->list_pool, s->per_user_index); @@ -1057,7 +1062,7 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, kv.key = m_key.as_u64; kv.value = ~0ULL; if (clib_bihash_add_del_8_8(&tsm->out2in, &kv, 0)) - clib_warning ("in2out key del failed"); + clib_warning ("out2in key del failed"); } /* Delete session(s) for static mapping if exist */ @@ -1094,6 +1099,9 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, if (is_lb_session (s)) continue; + if (!snat_is_session_static (s)) + continue; + nat_free_session_data (sm, s, tsm - sm->per_thread_data); clib_dlist_remove (tsm->list_pool, s->per_user_index); pool_put_index (tsm->list_pool, s->per_user_index); @@ -1517,7 +1525,10 @@ snat_del_address (snat_main_t *sm, ip4_address_t addr, u8 delete_sm, if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value)) { u = pool_elt_at_index (tsm->users, value.value); - u->nsessions--; + if (snat_is_session_static (ses)) + u->nstaticsessions--; + else + u->nsessions--; } } })); @@ -2685,19 +2696,23 @@ u8 * format_snat_session (u8 * s, va_list * args) s = format (s, " i2o %U\n", format_snat_key, &sess->in2out); s = format (s, " o2i %U\n", format_snat_key, &sess->out2in); } - if (is_twice_nat_session (sess)) - { - s = format (s, " external host o2i %U:%d i2o %U:%d\n", - format_ip4_address, &sess->ext_host_addr, - clib_net_to_host_u16 (sess->ext_host_port), - format_ip4_address, &sess->ext_host_nat_addr, - clib_net_to_host_u16 (sess->ext_host_nat_port)); - } - else + if (is_ed_session (sess) || is_fwd_bypass_session (sess)) { - if (sess->ext_host_addr.as_u32) - s = format (s, " external host %U\n", - format_ip4_address, &sess->ext_host_addr); + if (is_twice_nat_session (sess)) + { + s = format (s, " external host o2i %U:%d i2o %U:%d\n", + format_ip4_address, &sess->ext_host_addr, + clib_net_to_host_u16 (sess->ext_host_port), + format_ip4_address, &sess->ext_host_nat_addr, + clib_net_to_host_u16 (sess->ext_host_nat_port)); + } + else + { + if (sess->ext_host_addr.as_u32) + s = format (s, " external host %U:%u\n", + format_ip4_address, &sess->ext_host_addr, + clib_net_to_host_u16 (sess->ext_host_port)); + } } s = format (s, " last heard %.2f\n", sess->last_heard); s = format (s, " total pkts %d, total bytes %lld\n", @@ -2706,6 +2721,8 @@ u8 * format_snat_session (u8 * s, va_list * args) s = format (s, " static translation\n"); else s = format (s, " dynamic translation\n"); + if (is_fwd_bypass_session (sess)) + s = format (s, " forwarding-bypass\n"); if (sess->flags & SNAT_SESSION_FLAG_LOAD_BALANCING) s = format (s, " load-balancing\n"); if (is_twice_nat_session (sess)) @@ -3094,6 +3111,9 @@ nat44_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port, t = is_in ? &tsm->in2out : &tsm->out2in; if (!clib_bihash_search_8_8 (t, &kv, &value)) { + if (pool_is_free_index (tsm->sessions, value.value)) + return VNET_API_ERROR_UNSPECIFIED; + s = pool_elt_at_index (tsm->sessions, value.value); kv.key = s->in2out.as_u64; clib_bihash_add_del_8_8 (&tsm->in2out, &kv, 0); @@ -3105,9 +3125,13 @@ nat44_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port, if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value)) { u = pool_elt_at_index (tsm->users, value.value); - u->nsessions--; + if (snat_is_session_static (s)) + u->nstaticsessions--; + else + u->nsessions--; } clib_dlist_remove (tsm->list_pool, s->per_user_index); + pool_put_index (tsm->list_pool, s->per_user_index); pool_put (tsm->sessions, s); return 0; } @@ -3115,6 +3139,45 @@ nat44_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port, return VNET_API_ERROR_NO_SUCH_ENTRY; } +int +nat44_del_ed_session (snat_main_t *sm, ip4_address_t *addr, u16 port, + ip4_address_t *eh_addr, u16 eh_port, u8 proto, + u32 vrf_id, int is_in) +{ + ip4_header_t ip; + clib_bihash_16_8_t *t; + nat_ed_ses_key_t key; + clib_bihash_kv_16_8_t kv, value; + u32 thread_index; + u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id); + snat_session_t *s; + + ip.dst_address.as_u32 = ip.src_address.as_u32 = addr->as_u32; + if (sm->num_workers > 1) + thread_index = sm->worker_in2out_cb (&ip, fib_index); + else + thread_index = sm->num_workers; + + t = is_in ? &sm->in2out_ed : &sm->out2in_ed; + key.l_addr.as_u32 = addr->as_u32; + key.r_addr.as_u32 = eh_addr->as_u32; + key.l_port = clib_host_to_net_u16 (port); + key.r_port = clib_host_to_net_u16 (eh_port); + key.proto = proto; + key.fib_index = clib_host_to_net_u32 (fib_index); + kv.key[0] = key.as_u64[0]; + kv.key[1] = key.as_u64[1]; + if (clib_bihash_search_16_8 (t, &kv, &value)) + return VNET_API_ERROR_NO_SUCH_ENTRY; + + if (pool_is_free_index (sm->per_thread_data[thread_index].sessions, value.value)) + return VNET_API_ERROR_UNSPECIFIED; + s = pool_elt_at_index (sm->per_thread_data[thread_index].sessions, value.value); + nat_free_session_data (sm, s, thread_index); + nat44_delete_session (sm, s, thread_index); + return 0; +} + void nat_set_alloc_addr_and_port_mape (u16 psid, u16 psid_offset, u16 psid_length) {