X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat.c;h=b4e5c799ac685546d5af80065197d45e37acaa8c;hb=f13a8787365300d757eca4624c8f8a6b7c49392b;hp=a2b4010df0b8888766580fd71313331d4b8a37b8;hpb=4772e7ad53392e5ee78d05061ed18762bd4b8e8e;p=vpp.git diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index a2b4010df0b..b4e5c799ac6 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -522,7 +522,7 @@ snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index, if (is_add) fib_table_entry_update_one_path(fib_index, &prefix, - FIB_SOURCE_PLUGIN_HI, + FIB_SOURCE_PLUGIN_LOW, (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_EXCLUSIVE), @@ -536,7 +536,7 @@ snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index, else fib_table_entry_delete(fib_index, &prefix, - FIB_SOURCE_PLUGIN_HI); + FIB_SOURCE_PLUGIN_LOW); } void snat_add_address (snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, @@ -562,7 +562,7 @@ void snat_add_address (snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, if (vrf_id != ~0) ap->fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id, - FIB_SOURCE_PLUGIN_HI); + FIB_SOURCE_PLUGIN_LOW); else ap->fib_index = ~0; #define _(N, i, n, s) \ @@ -682,12 +682,12 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, u32 ses_index; u64 user_index; snat_session_t * s; + snat_static_map_resolve_t *rp, *rp_match = 0; /* If the external address is a specific interface address */ if (sw_if_index != ~0) { ip4_address_t * first_int_addr; - snat_static_map_resolve_t *rp, *rp_match = 0; for (i = 0; i < vec_len (sm->to_resolve); i++) { @@ -785,6 +785,17 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, vrf_id = sm->inside_vrf_id; } + if (!out2in_only) + { + m_key.addr = l_addr; + m_key.port = addr_only ? 0 : l_port; + m_key.protocol = addr_only ? 0 : proto; + m_key.fib_index = fib_index; + kv.key = m_key.as_u64; + if (!clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value)) + return VNET_API_ERROR_VALUE_EXIST; + } + /* Find external address in allocated addresses and reserve port for address and port pair mapping when dynamic translations enabled */ if (!(addr_only || sm->static_mapping_only || out2in_only)) @@ -819,7 +830,26 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, } /* External address must be allocated */ if (!a && (l_addr.as_u32 != e_addr.as_u32)) - return VNET_API_ERROR_NO_SUCH_ENTRY; + { + if (sw_if_index != ~0) + { + for (i = 0; i < vec_len (sm->to_resolve); i++) + { + rp = sm->to_resolve + i; + if (rp->addr_only) + continue; + if (rp->sw_if_index != sw_if_index && + rp->l_addr.as_u32 != l_addr.as_u32 && + rp->vrf_id != vrf_id && rp->l_port != l_port && + rp->e_port != e_port && rp->proto != proto) + continue; + + vec_del1 (sm->to_resolve, i); + break; + } + } + return VNET_API_ERROR_NO_SUCH_ENTRY; + } } pool_get (sm->static_mappings, m); @@ -931,7 +961,12 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, else { if (!m) - return VNET_API_ERROR_NO_SUCH_ENTRY; + { + if (sw_if_index != ~0) + return 0; + else + return VNET_API_ERROR_NO_SUCH_ENTRY; + } /* Free external address port */ if (!(addr_only || sm->static_mapping_only || out2in_only)) @@ -1143,7 +1178,7 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id, - FIB_SOURCE_PLUGIN_HI); + FIB_SOURCE_PLUGIN_LOW); /* Find external address in allocated addresses and reserve port for address and port pair mapping when dynamic translations enabled */ @@ -1256,7 +1291,7 @@ int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, if (!m) return VNET_API_ERROR_NO_SUCH_ENTRY; - fib_table_unlock (m->fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_PLUGIN_HI); + fib_table_unlock (m->fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_PLUGIN_LOW); /* Free external address port */ if (!(sm->static_mapping_only || out2in_only)) @@ -1427,7 +1462,7 @@ snat_del_address (snat_main_t *sm, ip4_address_t addr, u8 delete_sm, if (a->fib_index != ~0) fib_table_unlock(a->fib_index, FIB_PROTOCOL_IP4, - FIB_SOURCE_PLUGIN_HI); + FIB_SOURCE_PLUGIN_LOW); /* Delete sessions using address */ if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)