From 7e46a4dc841f635e45b8e8739338de407621667d Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Thu, 6 Oct 2016 04:28:29 -0700 Subject: [PATCH] VPP-446: 1:1 SNAT Inside overlapping interfaces Change-Id: Idabf89bd27ee95769da16331a6bd1439497b2765 Signed-off-by: Matus Fabian --- plugins/snat-plugin/snat/in2out.c | 10 ++++++++-- plugins/snat-plugin/snat/out2in.c | 10 ++++++++-- plugins/snat-plugin/snat/snat.c | 28 +++++++++++++++------------- plugins/snat-plugin/snat/snat.h | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/plugins/snat-plugin/snat/in2out.c b/plugins/snat-plugin/snat/in2out.c index 25dad934cad..9a4aeb01fd4 100644 --- a/plugins/snat-plugin/snat/in2out.c +++ b/plugins/snat-plugin/snat/in2out.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -1004,7 +1005,8 @@ static inline u32 icmp_in2out_static_map (snat_main_t *sm, icmp46_header_t * icmp0, u32 sw_if_index0, vlib_node_runtime_t * node, - u32 next0) + u32 next0, + u32 rx_fib_index0) { snat_session_key_t key0, sm0; icmp_echo_header_t *echo0; @@ -1017,6 +1019,7 @@ static inline u32 icmp_in2out_static_map (snat_main_t *sm, key0.addr = ip0->src_address; key0.port = echo0->identifier; + key0.fib_index = rx_fib_index0; if (snat_static_mapping_match(sm, key0, &sm0, 0)) { @@ -1106,6 +1109,7 @@ snat_in2out_fast_static_map_fn (vlib_main_t * vm, icmp46_header_t * icmp0; snat_session_key_t key0, sm0; u32 proto0; + u32 rx_fib_index0; /* speculatively enqueue b0 to the current next frame */ bi0 = from[0]; @@ -1124,6 +1128,7 @@ snat_in2out_fast_static_map_fn (vlib_main_t * vm, icmp0 = (icmp46_header_t *) udp0; sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX]; + rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index(sw_if_index0); proto0 = ~0; proto0 = (ip0->protocol == IP_PROTOCOL_UDP) @@ -1155,12 +1160,13 @@ snat_in2out_fast_static_map_fn (vlib_main_t * vm, goto trace0; next0 = icmp_in2out_static_map - (sm, b0, ip0, icmp0, sw_if_index0, node, next0); + (sm, b0, ip0, icmp0, sw_if_index0, node, next0, rx_fib_index0); goto trace0; } key0.addr = ip0->src_address; key0.port = udp0->src_port; + key0.fib_index = rx_fib_index0; if (snat_static_mapping_match(sm, key0, &sm0, 0)) { diff --git a/plugins/snat-plugin/snat/out2in.c b/plugins/snat-plugin/snat/out2in.c index b3497c40d31..7601eb8dfdd 100644 --- a/plugins/snat-plugin/snat/out2in.c +++ b/plugins/snat-plugin/snat/out2in.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -778,7 +779,8 @@ static inline u32 icmp_out2in_fast (snat_main_t *sm, icmp46_header_t * icmp0, u32 sw_if_index0, vlib_node_runtime_t * node, - u32 next0) + u32 next0, + u32 rx_fib_index0) { snat_session_key_t key0, sm0; icmp_echo_header_t *echo0; @@ -791,6 +793,7 @@ static inline u32 icmp_out2in_fast (snat_main_t *sm, key0.addr = ip0->dst_address; key0.port = echo0->identifier; + key0.fib_index = rx_fib_index0; if (snat_static_mapping_match(sm, key0, &sm0, 1)) { @@ -879,6 +882,7 @@ snat_out2in_fast_node_fn (vlib_main_t * vm, icmp46_header_t * icmp0; snat_session_key_t key0, sm0; u32 proto0; + u32 rx_fib_index0; /* speculatively enqueue b0 to the current next frame */ bi0 = from[0]; @@ -896,6 +900,7 @@ snat_out2in_fast_node_fn (vlib_main_t * vm, icmp0 = (icmp46_header_t *) udp0; sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX]; + rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index(sw_if_index0); vnet_get_config_data (&cm->config_main, &b0->current_config_index, @@ -915,12 +920,13 @@ snat_out2in_fast_node_fn (vlib_main_t * vm, if (PREDICT_FALSE (proto0 == SNAT_PROTOCOL_ICMP)) { next0 = icmp_out2in_fast - (sm, b0, ip0, icmp0, sw_if_index0, node, next0); + (sm, b0, ip0, icmp0, sw_if_index0, node, next0, rx_fib_index0); goto trace00; } key0.addr = ip0->dst_address; key0.port = udp0->dst_port; + key0.fib_index = rx_fib_index0; if (snat_static_mapping_match(sm, key0, &sm0, 1)) { diff --git a/plugins/snat-plugin/snat/snat.c b/plugins/snat-plugin/snat/snat.c index 8360db5ee42..8490bd83374 100644 --- a/plugins/snat-plugin/snat/snat.c +++ b/plugins/snat-plugin/snat/snat.c @@ -321,9 +321,18 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, uword * p; int i; + /* If outside FIB index is not resolved yet */ + if (sm->outside_fib_index == ~0) + { + p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->outside_vrf_id); + if (!p) + return VNET_API_ERROR_NO_SUCH_FIB; + sm->outside_fib_index = p[0]; + } + m_key.addr = e_addr; m_key.port = addr_only ? 0 : e_port; - m_key.pad = 0; + m_key.fib_index = sm->outside_fib_index; kv.key = m_key.as_u64; if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) m = 0; @@ -360,15 +369,6 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, vrf_id = sm->inside_vrf_id; } - /* If outside FIB index is not resolved yet */ - if (sm->outside_fib_index == ~0) - { - p = hash_get (sm->ip4_main->fib_index_by_table_id, sm->outside_vrf_id); - if (!p) - return VNET_API_ERROR_NO_SUCH_FIB; - sm->outside_fib_index = p[0]; - } - /* 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)) @@ -409,13 +409,14 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, m_key.addr = m->local_addr; m_key.port = m->local_port; - m_key.pad = 0; + m_key.fib_index = m->fib_index; kv.key = m_key.as_u64; kv.value = m - sm->static_mappings; clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 1); m_key.addr = m->external_addr; m_key.port = m->external_port; + m_key.fib_index = sm->outside_fib_index; kv.key = m_key.as_u64; kv.value = m - sm->static_mappings; clib_bihash_add_del_8_8(&sm->static_mapping_by_external, &kv, 1); @@ -444,12 +445,13 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, m_key.addr = m->local_addr; m_key.port = m->local_port; - m_key.pad = 0; + m_key.fib_index = m->fib_index; kv.key = m_key.as_u64; clib_bihash_add_del_8_8(&sm->static_mapping_by_local, &kv, 0); m_key.addr = m->external_addr; m_key.port = m->external_port; + m_key.fib_index = sm->outside_fib_index; kv.key = m_key.as_u64; clib_bihash_add_del_8_8(&sm->static_mapping_by_external, &kv, 0); @@ -967,7 +969,7 @@ int snat_static_mapping_match (snat_main_t * sm, m_key.addr = match.addr; m_key.port = clib_net_to_host_u16 (match.port); - m_key.pad = 0; + m_key.fib_index = match.fib_index; kv.key = m_key.as_u64; diff --git a/plugins/snat-plugin/snat/snat.h b/plugins/snat-plugin/snat/snat.h index 823b8608b1a..531da284e93 100644 --- a/plugins/snat-plugin/snat/snat.h +++ b/plugins/snat-plugin/snat/snat.h @@ -62,7 +62,7 @@ typedef struct { { ip4_address_t addr; u16 port; - u16 pad; + u16 fib_index; }; u64 as_u64; }; -- 2.16.6