X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat44-ed%2Fnat44_ed.c;h=a11043682b959db764779d1dd7ef5377407564b8;hb=4d41f954abc2965d187bcaf165dee81c8b3fd14a;hp=ad78dc2dd1f3f31c0eae206c814e1b2d9e2da62c;hpb=5ae454312c2ffccf47e4b8c430c81f1a3d067e67;p=vpp.git diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c index ad78dc2dd1f..a11043682b9 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.c +++ b/src/plugins/nat/nat44-ed/nat44_ed.c @@ -239,58 +239,76 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index, if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 0)) nat_elog_warn (sm, "flow hash del failed"); - if (is_fwd_bypass_session (s)) - { - return; - } + if (na44_ed_is_fwd_bypass_session (s)) + { + return; + } - if (is_affinity_sessions (s)) - nat_affinity_unlock (s->ext_host_addr, s->out2in.addr, - s->nat_proto, s->out2in.port); + if (nat44_ed_is_affinity_session (s)) + nat_affinity_unlock (s->ext_host_addr, s->out2in.addr, s->nat_proto, + s->out2in.port); if (!is_ha) nat_syslog_nat44_sdel ( 0, 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->nat_proto, - is_twice_nat_session (s)); + nat44_ed_is_twice_nat_session (s)); - if (snat_is_unk_proto_session (s)) - return; + if (snat_is_unk_proto_session (s)) + return; - if (!is_ha) - { - /* log NAT event */ - nat_ipfix_logging_nat44_ses_delete (thread_index, - s->in2out.addr.as_u32, - s->out2in.addr.as_u32, - s->nat_proto, - s->in2out.port, - s->out2in.port, - s->in2out.fib_index); - } + if (!is_ha) + { + /* log NAT event */ + nat_ipfix_logging_nat44_ses_delete ( + thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32, + s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index); + } /* Twice NAT address and port for external host */ - if (is_twice_nat_session (s)) - { - snat_free_outside_address_and_port (sm->twice_nat_addresses, - thread_index, - &s->ext_host_nat_addr, - s->ext_host_nat_port, s->nat_proto); - } + if (nat44_ed_is_twice_nat_session (s)) + { + snat_free_outside_address_and_port ( + sm->twice_nat_addresses, thread_index, &s->ext_host_nat_addr, + s->ext_host_nat_port, s->nat_proto); + } - if (snat_is_session_static (s)) - return; + if (nat44_ed_is_session_static (s)) + return; - snat_free_outside_address_and_port (sm->addresses, thread_index, - &s->out2in.addr, s->out2in.port, - s->nat_proto); + snat_free_outside_address_and_port (sm->addresses, thread_index, + &s->out2in.addr, s->out2in.port, + s->nat_proto); } -void -snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index, - int is_add) +static int +is_snat_address_used_in_static_mapping (snat_main_t *sm, ip4_address_t addr) +{ + snat_static_mapping_t *m; + pool_foreach (m, sm->static_mappings) + { + if (is_sm_addr_only (m->flags) || is_sm_out2in_only (m->flags) || + is_sm_identity_nat (m->flags)) + { + continue; + } + if (m->external_addr.as_u32 == addr.as_u32) + { + return 1; + } + } + return 0; +} + +static void +nat44_ed_add_del_addr_to_fib (ip4_address_t *addr, u8 p_len, u32 sw_if_index, + int is_add) { + // Add the external NAT address to the FIB as receive entries. This ensures + // that VPP will reply to ARP for this address and we don't need to enable + // proxy ARP on the outside interface. + snat_main_t *sm = &snat_main; fib_prefix_t prefix = { .fp_len = p_len, @@ -302,33 +320,68 @@ snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index, u32 fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index); if (is_add) - fib_table_entry_update_one_path (fib_index, - &prefix, - sm->fib_src_low, - (FIB_ENTRY_FLAG_CONNECTED | - FIB_ENTRY_FLAG_LOCAL | - FIB_ENTRY_FLAG_EXCLUSIVE), - DPO_PROTO_IP4, - NULL, - sw_if_index, - ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE); + { + fib_table_entry_update_one_path (fib_index, &prefix, sm->fib_src_low, + (FIB_ENTRY_FLAG_CONNECTED | + FIB_ENTRY_FLAG_LOCAL | + FIB_ENTRY_FLAG_EXCLUSIVE), + DPO_PROTO_IP4, NULL, sw_if_index, ~0, 1, + NULL, FIB_ROUTE_PATH_FLAG_NONE); + } else - fib_table_entry_delete (fib_index, &prefix, sm->fib_src_low); + { + fib_table_entry_delete (fib_index, &prefix, sm->fib_src_low); + } } -static int -is_snat_address_used_in_static_mapping (snat_main_t *sm, ip4_address_t addr) +static void +nat44_ed_add_del_addr_to_fib_foreach_out_if (ip4_address_t *addr, u8 is_add) +{ + snat_main_t *sm = &snat_main; + snat_interface_t *i; + + pool_foreach (i, sm->interfaces) + { + if (nat44_ed_is_interface_outside (i)) + { + nat44_ed_add_del_addr_to_fib (addr, 32, i->sw_if_index, is_add); + } + } + pool_foreach (i, sm->output_feature_interfaces) + { + if (nat44_ed_is_interface_outside (i)) + { + nat44_ed_add_del_addr_to_fib (addr, 32, i->sw_if_index, is_add); + } + } +} + +static_always_inline void +nat44_ed_add_del_addr_to_fib_foreach_addr (u32 sw_if_index, u8 is_add) +{ + snat_main_t *sm = &snat_main; + snat_address_t *ap; + + vec_foreach (ap, sm->addresses) + { + nat44_ed_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, is_add); + } +} + +static_always_inline void +nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (u32 sw_if_index, u8 is_add) { + snat_main_t *sm = &snat_main; snat_static_mapping_t *m; + pool_foreach (m, sm->static_mappings) { - if (is_sm_addr_only (m->flags) || is_sm_out2in_only (m->flags) || - is_sm_identity_nat (m->flags)) - continue; - if (m->external_addr.as_u32 == addr.as_u32) - return 1; + if (is_sm_addr_only (m->flags) && !is_sm_identity_nat (m->flags)) + { + nat44_ed_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index, + is_add); + } } - return 0; } int @@ -337,7 +390,6 @@ nat44_ed_add_address (ip4_address_t *addr, u32 vrf_id, u8 twice_nat) snat_main_t *sm = &snat_main; vlib_thread_main_t *tm = vlib_get_thread_main (); snat_address_t *ap, *addresses; - snat_interface_t *i; addresses = twice_nat ? sm->twice_nat_addresses : sm->addresses; @@ -386,22 +438,9 @@ nat44_ed_add_address (ip4_address_t *addr, u32 vrf_id, u8 twice_nat) if (!twice_nat) { - pool_foreach (i, sm->interfaces) - { - if (!nat_interface_is_inside (i)) - { - snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1); - break; - } - } - pool_foreach (i, sm->output_feature_interfaces) - { - if (!nat_interface_is_inside (i)) - { - snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1); - break; - } - } + // if we don't have enabled interface we don't add address + // to fib + nat44_ed_add_del_addr_to_fib_foreach_out_if (addr, 1); } return 0; } @@ -415,7 +454,6 @@ nat44_ed_del_address (ip4_address_t addr, u8 delete_sm, u8 twice_nat) u32 *ses_to_be_removed = 0, *ses_index; snat_main_per_thread_data_t *tsm; snat_static_mapping_t *m; - snat_interface_t *i; int j; addresses = twice_nat ? sm->twice_nat_addresses : sm->addresses; @@ -492,23 +530,7 @@ nat44_ed_del_address (ip4_address_t addr, u8 delete_sm, u8 twice_nat) if (!twice_nat) { vec_del1 (sm->addresses, j); - // delete external address from FIB - pool_foreach (i, sm->interfaces) - { - if (!nat_interface_is_inside (i)) - { - snat_add_del_addr_to_fib (&addr, 32, i->sw_if_index, 0); - break; - } - } - pool_foreach (i, sm->output_feature_interfaces) - { - if (!nat_interface_is_inside (i)) - { - snat_add_del_addr_to_fib (&addr, 32, i->sw_if_index, 0); - break; - } - } + nat44_ed_add_del_addr_to_fib_foreach_out_if (&addr, 0); } else { vec_del1 (sm->twice_nat_addresses, j); } return 0; @@ -554,9 +576,9 @@ nat_ed_static_mapping_del_sessions (snat_main_t * sm, continue; } - if (is_lb_session (s)) + if (nat44_ed_is_lb_session (s)) continue; - if (!snat_is_session_static (s)) + if (!nat44_ed_is_session_static (s)) continue; nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0); vec_add1 (indexes_to_free, s - tsm->sessions); @@ -765,7 +787,6 @@ nat44_ed_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, { snat_main_t *sm = &snat_main; clib_bihash_kv_8_8_t kv, value; - snat_interface_t *interface; nat44_lb_addr_port_t *local; snat_static_mapping_t *m; u32 fib_index = ~0; @@ -924,6 +945,12 @@ nat44_ed_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, { m->vrf_id = vrf_id; m->fib_index = fib_index; + + // not identity && addr only + if (is_sm_addr_only (flags)) + { + nat44_ed_add_del_addr_to_fib_foreach_out_if (&e_addr, 1); + } } if (!is_sm_out2in_only (flags)) @@ -949,27 +976,6 @@ nat44_ed_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, vec_add1 (m->workers, worker_index); } - if (is_sm_identity_nat (flags) || !is_sm_addr_only (flags)) - return 0; - - pool_foreach (interface, sm->interfaces) - { - if (nat_interface_is_inside (interface)) - continue; - - snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 1); - break; - } - - pool_foreach (interface, sm->output_feature_interfaces) - { - if (nat_interface_is_inside (interface)) - continue; - - snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 1); - break; - } - return 0; } @@ -982,7 +988,6 @@ nat44_ed_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, snat_main_t *sm = &snat_main; clib_bihash_kv_8_8_t kv, value; - snat_interface_t *interface; nat44_lb_addr_port_t *local; snat_static_mapping_t *m; u32 fib_index = ~0; @@ -1107,36 +1112,21 @@ nat44_ed_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); - if (pool_elts (m->locals)) - return 0; - - // fib_index 0 - init_nat_k (&kv, e_addr, e_port, 0, proto); - clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0); - - vec_free (m->tag); - vec_free (m->workers); - pool_put (sm->static_mappings, m); - - if (is_sm_identity_nat (flags) || !is_sm_addr_only (flags)) - return 0; - - pool_foreach (interface, sm->interfaces) + if (!pool_elts (m->locals)) { - if (nat_interface_is_inside (interface)) - continue; + // this is last record remove all required stuff + // fib_index 0 + init_nat_k (&kv, e_addr, e_port, 0, proto); + clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0); - snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 0); - break; - } + vec_free (m->tag); + vec_free (m->workers); + pool_put (sm->static_mappings, m); - pool_foreach (interface, sm->output_feature_interfaces) - { - if (nat_interface_is_inside (interface)) - continue; - - snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 0); - break; + if (is_sm_addr_only (flags) && !is_sm_identity_nat (flags)) + { + nat44_ed_add_del_addr_to_fib_foreach_out_if (&e_addr, 0); + } } return 0; @@ -1165,20 +1155,28 @@ nat44_ed_add_lb_static_mapping (ip4_address_t e_addr, u16 e_port, init_nat_k (&kv, e_addr, e_port, 0, proto); if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) - m = 0; + { + m = 0; + } else - m = pool_elt_at_index (sm->static_mappings, value.value); + { + m = pool_elt_at_index (sm->static_mappings, value.value); + } if (m) - return VNET_API_ERROR_VALUE_EXIST; + { + return VNET_API_ERROR_VALUE_EXIST; + } if (vec_len (locals) < 2) - return VNET_API_ERROR_INVALID_VALUE; + { + return VNET_API_ERROR_INVALID_VALUE; + } - /* Find external address in allocated addresses and reserve port for - address and port pair mapping when dynamic translations enabled */ if (!(sm->static_mapping_only || is_sm_out2in_only (flags))) { + /* Find external address in allocated addresses and reserve port for + address and port pair mapping when dynamic translations enabled */ for (i = 0; i < vec_len (sm->addresses); i++) { if (sm->addresses[i].addr.as_u32 == e_addr.as_u32) @@ -1206,9 +1204,11 @@ nat44_ed_add_lb_static_mapping (ip4_address_t e_addr, u16 e_port, break; } } - /* External address must be allocated */ + // external address must be allocated if (!a) - return VNET_API_ERROR_NO_SUCH_ENTRY; + { + return VNET_API_ERROR_NO_SUCH_ENTRY; + } } pool_get (sm->static_mappings, m); @@ -1306,7 +1306,6 @@ nat44_ed_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, if (!is_sm_lb (m->flags)) return VNET_API_ERROR_INVALID_VALUE; - /* Free external address port */ if (!(sm->static_mapping_only || is_sm_out2in_only (flags))) { for (i = 0; i < vec_len (sm->addresses); i++) @@ -1371,7 +1370,7 @@ nat44_ed_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port, /* Delete sessions */ pool_foreach (s, tsm->sessions) { - if (!(is_lb_session (s))) + if (!(nat44_ed_is_lb_session (s))) continue; if ((s->in2out.addr.as_u32 != local->addr.as_u32) || @@ -1422,10 +1421,14 @@ nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port, m = pool_elt_at_index (sm->static_mappings, value.value); if (!m) - return VNET_API_ERROR_NO_SUCH_ENTRY; + { + return VNET_API_ERROR_NO_SUCH_ENTRY; + } if (!is_sm_lb (m->flags)) - return VNET_API_ERROR_INVALID_VALUE; + { + return VNET_API_ERROR_INVALID_VALUE; + } pool_foreach (local, m->locals) { @@ -1440,7 +1443,9 @@ nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port, if (is_add) { if (match_local) - return VNET_API_ERROR_VALUE_EXIST; + { + return VNET_API_ERROR_VALUE_EXIST; + } pool_get (m->locals, local); clib_memset (local, 0, sizeof (*local)); @@ -1492,15 +1497,15 @@ nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port, /* Delete sessions */ pool_foreach (s, tsm->sessions) { - if (!(is_lb_session (s))) - continue; + if (!(nat44_ed_is_lb_session (s))) + continue; - if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) || - s->in2out.port != match_local->port) - continue; + if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) || + s->in2out.port != match_local->port) + continue; - nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0); - nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1); + nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0); + nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1); } pool_put (m->locals, match_local); @@ -1633,9 +1638,7 @@ nat44_ed_add_interface (u32 sw_if_index, u8 is_inside) snat_main_t *sm = &snat_main; nat_outside_fib_t *outside_fib; - snat_static_mapping_t *m; snat_interface_t *i; - snat_address_t *ap; u32 fib_index; int rv; @@ -1654,8 +1657,8 @@ nat44_ed_add_interface (u32 sw_if_index, u8 is_inside) i = nat44_ed_get_interface (sm->interfaces, sw_if_index); if (i) { - if ((nat_interface_is_inside (i) && is_inside) || - (nat_interface_is_outside (i) && !is_inside)) + if ((nat44_ed_is_interface_inside (i) && is_inside) || + (nat44_ed_is_interface_outside (i) && !is_inside)) { return 0; } @@ -1725,19 +1728,8 @@ nat44_ed_add_interface (u32 sw_if_index, u8 is_inside) outside_fib->refcount = 1; } - vec_foreach (ap, sm->addresses) - { - snat_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, 1); - } - pool_foreach (m, sm->static_mappings) - { - if (!(is_sm_addr_only (m->flags)) || - (m->local_addr.as_u32 == m->external_addr.as_u32)) - { - continue; - } - snat_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index, 1); - } + nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 1); + nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 1); } else { @@ -1754,9 +1746,7 @@ nat44_ed_del_interface (u32 sw_if_index, u8 is_inside) snat_main_t *sm = &snat_main; nat_outside_fib_t *outside_fib; - snat_static_mapping_t *m; snat_interface_t *i; - snat_address_t *ap; u32 fib_index; int rv; @@ -1773,7 +1763,7 @@ nat44_ed_del_interface (u32 sw_if_index, u8 is_inside) return VNET_API_ERROR_NO_SUCH_ENTRY; } - if (nat_interface_is_inside (i) && nat_interface_is_outside (i)) + if (nat44_ed_is_interface_inside (i) && nat44_ed_is_interface_outside (i)) { if (sm->num_workers > 1) { @@ -1847,20 +1837,8 @@ nat44_ed_del_interface (u32 sw_if_index, u8 is_inside) } } - vec_foreach (ap, sm->addresses) - { - snat_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, 0); - } - - pool_foreach (m, sm->static_mappings) - { - if (!(is_sm_addr_only (m->flags)) || - (m->local_addr.as_u32 == m->external_addr.as_u32)) - { - continue; - } - snat_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index, 0); - } + nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 0); + nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 0); } return 0; @@ -1872,9 +1850,7 @@ nat44_ed_add_output_interface (u32 sw_if_index) snat_main_t *sm = &snat_main; nat_outside_fib_t *outside_fib; - snat_static_mapping_t *m; snat_interface_t *i; - snat_address_t *ap; u32 fib_index; int rv; @@ -1960,20 +1936,8 @@ nat44_ed_add_output_interface (u32 sw_if_index) outside_fib->refcount = 1; } - vec_foreach (ap, sm->addresses) - { - snat_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, 1); - } - - pool_foreach (m, sm->static_mappings) - { - if (!((is_sm_addr_only (m->flags))) || - (m->local_addr.as_u32 == m->external_addr.as_u32)) - { - continue; - } - snat_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index, 1); - } + nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 1); + nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 1); return 0; } @@ -1984,9 +1948,7 @@ nat44_ed_del_output_interface (u32 sw_if_index) snat_main_t *sm = &snat_main; nat_outside_fib_t *outside_fib; - snat_static_mapping_t *m; snat_interface_t *i; - snat_address_t *ap; u32 fib_index; int rv; @@ -2060,20 +2022,8 @@ nat44_ed_del_output_interface (u32 sw_if_index) } } - vec_foreach (ap, sm->addresses) - { - snat_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, 0); - } - - pool_foreach (m, sm->static_mappings) - { - if (!((is_sm_addr_only (m->flags))) || - (m->local_addr.as_u32 == m->external_addr.as_u32)) - { - continue; - } - snat_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index, 0); - } + nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 0); + nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 0); return 0; } @@ -2133,7 +2083,7 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, { if (i->sw_if_index == sw_if_index) { - if (!(nat_interface_is_outside (i))) + if (!(nat44_ed_is_interface_outside (i))) return; match = 1; } @@ -2143,7 +2093,7 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, { if (i->sw_if_index == sw_if_index) { - if (!(nat_interface_is_outside (i))) + if (!(nat44_ed_is_interface_outside (i))) return; match = 1; } @@ -2189,7 +2139,7 @@ static void nat44_ed_add_del_interface_address_cb ( ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete); -static void nat44_ed_add_del_sm_addr_only_cb ( +static void nat44_ed_add_del_static_mapping_addr_only_cb ( ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete); @@ -2388,7 +2338,7 @@ nat_init (vlib_main_t * vm) /* callbacks to call when interface address changes. */ cbi.function = nat44_ed_add_del_interface_address_cb; vec_add1 (sm->ip4_main->add_del_interface_address_callbacks, cbi); - cbi.function = nat44_ed_add_del_sm_addr_only_cb; + cbi.function = nat44_ed_add_del_static_mapping_addr_only_cb; vec_add1 (sm->ip4_main->add_del_interface_address_callbacks, cbi); /* callbacks to call when interface to table biding changes */ @@ -2515,11 +2465,11 @@ nat44_plugin_disable () pool = pool_dup (sm->interfaces); pool_foreach (i, pool) { - if (nat_interface_is_inside (i)) + if (nat44_ed_is_interface_inside (i)) { error = nat44_ed_del_interface (i->sw_if_index, 1); } - if (nat_interface_is_outside (i)) + if (nat44_ed_is_interface_outside (i)) { error = nat44_ed_del_interface (i->sw_if_index, 0); } @@ -2590,7 +2540,7 @@ nat44_ed_forwarding_enable_disable (u8 is_enable) { pool_foreach (s, tsm->sessions) { - if (is_fwd_bypass_session (s)) + if (na44_ed_is_fwd_bypass_session (s)) { vec_add1 (ses_to_be_removed, s - tsm->sessions); } @@ -2854,6 +2804,28 @@ nat44_ed_get_in2out_worker_index (vlib_buffer_t *b, ip4_header_t *ip, } } + if (PREDICT_FALSE (ip->protocol == IP_PROTOCOL_ICMP)) + { + ip4_address_t lookup_saddr, lookup_daddr; + u16 lookup_sport, lookup_dport; + u8 lookup_protocol; + + if (!nat_get_icmp_session_lookup_values ( + b, ip, &lookup_saddr, &lookup_sport, &lookup_daddr, + &lookup_dport, &lookup_protocol)) + { + init_ed_k (&kv16, lookup_saddr, lookup_sport, lookup_daddr, + lookup_dport, rx_fib_index, lookup_protocol); + if (!clib_bihash_search_16_8 (&sm->flow_hash, &kv16, &value16)) + { + next_worker_index = ed_value_get_thread_index (&value16); + vnet_buffer2 (b)->nat.cached_session_index = + ed_value_get_session_index (&value16); + goto out; + } + } + } + init_ed_k (&kv16, ip->src_address, vnet_buffer (b)->ip.reass.l4_src_port, ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port, fib_index, ip->protocol); @@ -3231,32 +3203,36 @@ nat44_ed_sessions_clear () } static void -nat44_ed_add_del_sm_addr_only_cb (ip4_main_t *im, uword opaque, - u32 sw_if_index, ip4_address_t *address, - u32 address_length, u32 if_address_index, - u32 is_delete) +nat44_ed_add_del_static_mapping_addr_only_cb ( + ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, + u32 address_length, u32 if_address_index, u32 is_delete) { clib_bihash_kv_8_8_t kv, value; snat_static_map_resolve_t *rp; snat_main_t *sm = &snat_main; snat_static_mapping_t *m; - ip4_address_t l_addr; - int i, rv = 0; + int i, rv = 0, match = 0; if (!sm->enabled) - return; + { + return; + } + // find first addr_only resolve record by sw_if_index for (i = 0; i < vec_len (sm->to_resolve); i++) { rp = sm->to_resolve + i; if (rp->addr_only && rp->sw_if_index == sw_if_index) { - goto match; + match = 1; + break; } } - return; + if (!match) + { + return; + } -match: init_nat_k (&kv, *address, rp->addr_only ? 0 : rp->e_port, sm->outside_fib_index, rp->addr_only ? 0 : rp->proto); @@ -3269,21 +3245,11 @@ match: m = pool_elt_at_index (sm->static_mappings, value.value); } - // Indetity mapping - if (rp->l_addr.as_u32 == 0) - { - l_addr.as_u32 = address[0].as_u32; - } - else - { - l_addr.as_u32 = rp->l_addr.as_u32; - } - if (is_delete) { if (m) { - rv = nat44_ed_del_static_mapping (l_addr, address[0], rp->l_port, + rv = nat44_ed_del_static_mapping (rp->l_addr, address[0], rp->l_port, rp->e_port, rp->proto, rp->vrf_id, ~0, rp->flags); } @@ -3293,10 +3259,10 @@ match: if (!m) { rv = nat44_ed_add_static_mapping ( - l_addr, address[0], rp->l_port, rp->e_port, rp->proto, rp->vrf_id, - ~0, rp->flags, rp->pool_addr, rp->tag); + rp->l_addr, address[0], rp->l_port, rp->e_port, rp->proto, + rp->vrf_id, ~0, rp->flags, rp->pool_addr, rp->tag); } - // else don't trip over lease renewal, static config + // else: don't trip over lease renewal, static config } if (rv) { @@ -3305,6 +3271,20 @@ match: } } +static_always_inline int +is_sw_if_index_reg_for_auto_resolve (u32 *sw_if_indices, u32 sw_if_index) +{ + u32 *i; + vec_foreach (i, sw_if_indices) + { + if (*i == sw_if_index) + { + return 1; + } + } + return 0; +} + static void nat44_ed_add_del_interface_address_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, @@ -3313,61 +3293,55 @@ nat44_ed_add_del_interface_address_cb (ip4_main_t *im, uword opaque, { snat_main_t *sm = &snat_main; snat_static_map_resolve_t *rp; - ip4_address_t l_addr; - int i, j; - int rv; - u8 twice_nat = 0; snat_address_t *addresses = sm->addresses; + u8 twice_nat = 0; + int rv, i; if (!sm->enabled) { return; } - for (i = 0; i < vec_len (sm->auto_add_sw_if_indices); i++) - { - if (sw_if_index == sm->auto_add_sw_if_indices[i]) - goto match; - } - - for (i = 0; i < vec_len (sm->auto_add_sw_if_indices_twice_nat); i++) + if (!is_sw_if_index_reg_for_auto_resolve (sm->auto_add_sw_if_indices, + sw_if_index)) { - twice_nat = 1; - addresses = sm->twice_nat_addresses; - if (sw_if_index == sm->auto_add_sw_if_indices_twice_nat[i]) - goto match; + if (!is_sw_if_index_reg_for_auto_resolve ( + sm->auto_add_sw_if_indices_twice_nat, sw_if_index)) + { + return; + } + else + { + addresses = sm->twice_nat_addresses; + twice_nat = 1; + } } - return; - -match: if (!is_delete) { - /* Don't trip over lease renewal, static config */ - for (j = 0; j < vec_len (addresses); j++) - if (addresses[j].addr.as_u32 == address->as_u32) - return; + // don't trip over lease renewal, static config + for (i = 0; i < vec_len (addresses); i++) + { + if (addresses[i].addr.as_u32 == address->as_u32) + { + return; + } + } (void) nat44_ed_add_address (address, ~0, twice_nat); - /* Scan static map resolution vector */ - for (j = 0; j < vec_len (sm->to_resolve); j++) + + // scan static mapping switch address resolution record vector + for (i = 0; i < vec_len (sm->to_resolve); i++) { - rp = sm->to_resolve + j; + rp = sm->to_resolve + i; if (rp->addr_only) - continue; - /* On this interface? */ + { + continue; + } if (rp->sw_if_index == sw_if_index) { - // TODO: remove if not needed (handled by function) - /* Indetity mapping? */ - if (rp->l_addr.as_u32 == 0) - l_addr.as_u32 = address[0].as_u32; - else - l_addr.as_u32 = rp->l_addr.as_u32; - - /* Add the static mapping */ rv = nat44_ed_add_static_mapping ( - l_addr, address[0], rp->l_port, rp->e_port, rp->proto, + rp->l_addr, address[0], rp->l_port, rp->e_port, rp->proto, rp->vrf_id, ~0, rp->flags, rp->pool_addr, rp->tag); if (rv) { @@ -3376,7 +3350,6 @@ match: } } } - return; } else {