diff options
Diffstat (limited to 'src/plugins/nat/nat44-ed')
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.api | 52 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.c | 189 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.h | 95 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_api.c | 73 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_cfg.c | 0 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_cli.c | 234 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_in2out.c | 356 | ||||
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_out2in.c | 9 |
8 files changed, 727 insertions, 281 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.api b/src/plugins/nat/nat44-ed/nat44_ed.api index afb55021bec..88496a3f16e 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.api +++ b/src/plugins/nat/nat44-ed/nat44_ed.api @@ -198,6 +198,58 @@ define nat_worker_details { string name[64]; }; +/** \brief Add/delete inter VRF NAT44-ED routing table + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param table_vrf_id - id of (rx) VRF used for resolving + destination (tx) VRF during dynamic + session creation + @param is_add - if true add else del +*/ +autoreply define nat44_ed_add_del_vrf_table { + u32 client_index; + u32 context; + u32 table_vrf_id; + bool is_add; +}; + +/** \brief Add/del inter VRF NAT44-ED route record + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param table_vrf_id - id of the VRF NAT routing table + @param vrf_id - id of resolving destination (tx) VRF table + @param is_add - if true add else del +*/ +autoreply define nat44_ed_add_del_vrf_route { + u32 client_index; + u32 context; + u32 table_vrf_id; + u32 vrf_id; + bool is_add; +}; + +/** \brief Dump NAT44-ED inter VRF NAT routing tables + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request +*/ +define nat44_ed_vrf_tables_dump { + u32 client_index; + u32 context; +}; + +/** \brief NAT44-ED inter VRF NAT routing table details response + @param context - sender context, to match reply w/ request + @param table_vrf_id - id of the VRF NAT routing table + @param n_vrf_ids - number of vrf_ids + @param vrf_ids - ids of resolving destination (tx) VRFs +*/ +define nat44_ed_vrf_tables_details { + u32 context; + u32 table_vrf_id; + u32 n_vrf_ids; + u32 vrf_ids[n_vrf_ids]; +}; + /** \brief Set TCP MSS rewriting configuration @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c index bf802f59323..3b1c9a2c89f 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.c +++ b/src/plugins/nat/nat44-ed/nat44_ed.c @@ -626,6 +626,134 @@ nat44_ed_del_address (ip4_address_t addr, u8 twice_nat) return 0; } +vrf_table_t * +nat44_ed_get_vrf_table (u32 table_vrf_id) +{ + snat_main_t *sm = &snat_main; + vrf_table_t *t; + + pool_foreach (t, sm->vrf_tables) + { + if (table_vrf_id == t->table_vrf_id) + { + return t; + } + } + return NULL; +} + +vrf_route_t * +nat44_ed_get_vrf_route (vrf_table_t *t, u32 vrf_id) +{ + vrf_route_t *r; + + pool_foreach (r, t->routes) + { + if (vrf_id == r->vrf_id) + { + return r; + } + } + return NULL; +} + +int +nat44_ed_add_del_vrf_table (u32 table_vrf_id, bool is_add) +{ + snat_main_t *sm = &snat_main; + vrf_table_t *t; + vrf_route_t *r; + + t = nat44_ed_get_vrf_table (table_vrf_id); + if (t) + { + if (is_add) + { + return VNET_API_ERROR_VALUE_EXIST; + } + pool_foreach (r, t->routes) + { + fib_table_unlock (r->fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); + } + fib_table_unlock (t->table_fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); + + pool_free (t->routes); + pool_put (sm->vrf_tables, t); + } + else + { + if (!is_add) + { + return VNET_API_ERROR_NO_SUCH_ENTRY; + } + pool_get (sm->vrf_tables, t); + clib_memset (t, 0, sizeof (*t)); + t->table_vrf_id = table_vrf_id; + t->table_fib_index = fib_table_find_or_create_and_lock ( + FIB_PROTOCOL_IP4, table_vrf_id, sm->fib_src_low); + } + + return 0; +} + +void +nat44_ed_del_vrf_tables () +{ + snat_main_t *sm = &snat_main; + vrf_table_t *t; + vrf_route_t *r; + + pool_foreach (t, sm->vrf_tables) + { + pool_foreach (r, t->routes) + { + fib_table_unlock (r->fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); + } + fib_table_unlock (t->table_fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); + pool_free (t->routes); + } + pool_free (sm->vrf_tables); +} + +int +nat44_ed_add_del_vrf_route (u32 table_vrf_id, u32 vrf_id, bool is_add) +{ + snat_main_t *sm = &snat_main; + vrf_table_t *t; + vrf_route_t *r; + + t = nat44_ed_get_vrf_table (table_vrf_id); + if (!t) + { + return VNET_API_ERROR_NO_SUCH_ENTRY; + } + + r = nat44_ed_get_vrf_route (t, vrf_id); + if (r) + { + if (is_add) + { + return VNET_API_ERROR_VALUE_EXIST; + } + fib_table_unlock (r->fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); + pool_put (t->routes, r); + } + else + { + if (!is_add) + { + return VNET_API_ERROR_NO_SUCH_ENTRY; + } + pool_get (t->routes, r); + clib_memset (r, 0, sizeof (*r)); + r->vrf_id = vrf_id; + r->fib_index = fib_table_find_or_create_and_lock ( + FIB_PROTOCOL_IP4, vrf_id, sm->fib_src_low); + } + + return 0; +} + u32 get_thread_idx_by_port (u16 e_port) { @@ -1555,10 +1683,10 @@ update_per_vrf_sessions_vec (u32 fib_index, int is_del) } } -static_always_inline nat_outside_fib_t * -nat44_ed_get_outside_fib (nat_outside_fib_t *outside_fibs, u32 fib_index) +static_always_inline nat_fib_t * +nat44_ed_get_outside_fib (nat_fib_t *outside_fibs, u32 fib_index) { - nat_outside_fib_t *f; + nat_fib_t *f; vec_foreach (f, outside_fibs) { if (f->fib_index == fib_index) @@ -1589,7 +1717,7 @@ nat44_ed_add_interface (u32 sw_if_index, u8 is_inside) const char *del_feature_name, *feature_name; snat_main_t *sm = &snat_main; - nat_outside_fib_t *outside_fib; + nat_fib_t *outside_fib; snat_interface_t *i; u32 fib_index; int rv; @@ -1671,13 +1799,13 @@ nat44_ed_add_interface (u32 sw_if_index, u8 is_inside) outside_fib = nat44_ed_get_outside_fib (sm->outside_fibs, fib_index); if (outside_fib) { - outside_fib->refcount++; + outside_fib->ref_count++; } else { vec_add2 (sm->outside_fibs, outside_fib, 1); outside_fib->fib_index = fib_index; - outside_fib->refcount = 1; + outside_fib->ref_count = 1; } nat44_ed_add_del_nat_addr_fib_reg_entries (sw_if_index, 1); @@ -1699,7 +1827,7 @@ nat44_ed_del_interface (u32 sw_if_index, u8 is_inside) const char *del_feature_name, *feature_name; snat_main_t *sm = &snat_main; - nat_outside_fib_t *outside_fib; + nat_fib_t *outside_fib; snat_interface_t *i; u32 fib_index; int rv; @@ -1784,8 +1912,8 @@ nat44_ed_del_interface (u32 sw_if_index, u8 is_inside) outside_fib = nat44_ed_get_outside_fib (sm->outside_fibs, fib_index); if (outside_fib) { - outside_fib->refcount--; - if (!outside_fib->refcount) + outside_fib->ref_count--; + if (!outside_fib->ref_count) { vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs); } @@ -1803,7 +1931,7 @@ nat44_ed_add_output_interface (u32 sw_if_index) { snat_main_t *sm = &snat_main; - nat_outside_fib_t *outside_fib; + nat_fib_t *outside_fib; snat_interface_t *i; u32 fib_index; int rv; @@ -1881,13 +2009,13 @@ nat44_ed_add_output_interface (u32 sw_if_index) outside_fib = nat44_ed_get_outside_fib (sm->outside_fibs, fib_index); if (outside_fib) { - outside_fib->refcount++; + outside_fib->ref_count++; } else { vec_add2 (sm->outside_fibs, outside_fib, 1); outside_fib->fib_index = fib_index; - outside_fib->refcount = 1; + outside_fib->ref_count = 1; } nat44_ed_add_del_nat_addr_fib_reg_entries (sw_if_index, 1); @@ -1903,7 +2031,7 @@ nat44_ed_del_output_interface (u32 sw_if_index) { snat_main_t *sm = &snat_main; - nat_outside_fib_t *outside_fib; + nat_fib_t *outside_fib; snat_interface_t *i; u32 fib_index; int rv; @@ -1971,8 +2099,8 @@ nat44_ed_del_output_interface (u32 sw_if_index) outside_fib = nat44_ed_get_outside_fib (sm->outside_fibs, fib_index); if (outside_fib) { - outside_fib->refcount--; - if (!outside_fib->refcount) + outside_fib->ref_count--; + if (!outside_fib->ref_count) { vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs); } @@ -2036,7 +2164,7 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index) { snat_main_t *sm = &snat_main; - nat_outside_fib_t *outside_fib; + nat_fib_t *outside_fib; snat_interface_t *i; u8 is_add = 1; u8 match = 0; @@ -2074,8 +2202,8 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, { if (outside_fib->fib_index == old_fib_index) { - outside_fib->refcount--; - if (!outside_fib->refcount) + outside_fib->ref_count--; + if (!outside_fib->ref_count) vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs); break; } @@ -2085,7 +2213,7 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, { if (outside_fib->fib_index == new_fib_index) { - outside_fib->refcount++; + outside_fib->ref_count++; is_add = 0; break; } @@ -2094,7 +2222,7 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, if (is_add) { vec_add2 (sm->outside_fibs, outside_fib, 1); - outside_fib->refcount = 1; + outside_fib->ref_count = 1; outside_fib->fib_index = new_fib_index; } } @@ -2518,6 +2646,8 @@ nat44_plugin_disable () if (rc) error = 1; + nat44_ed_del_vrf_tables (); + vec_free (sm->max_translations_per_fib); sm->max_translations_per_fib = 0; @@ -2587,11 +2717,12 @@ nat44_ed_sm_match (snat_main_t *sm, ip4_address_t match_addr, u16 match_port, if (m) return m; - /* Try address only mapping */ + // try address only mapping m = nat44_ed_sm_i2o_lookup (sm, match_addr, 0, match_fib_index, 0); if (m) return m; + // default static mapping fib index (based on configuration) if (sm->inside_fib_index != match_fib_index) { m = nat44_ed_sm_i2o_lookup (sm, match_addr, match_port, @@ -2599,12 +2730,13 @@ nat44_ed_sm_match (snat_main_t *sm, ip4_address_t match_addr, u16 match_port, if (m) return m; - /* Try address only mapping */ + // try address only mapping m = nat44_ed_sm_i2o_lookup (sm, match_addr, 0, sm->inside_fib_index, 0); if (m) return m; } + // TODO: this specific use case may be deprecated (needs testing) if (sm->outside_fib_index != match_fib_index) { m = nat44_ed_sm_i2o_lookup (sm, match_addr, match_port, @@ -2612,7 +2744,7 @@ nat44_ed_sm_match (snat_main_t *sm, ip4_address_t match_addr, u16 match_port, if (m) return m; - /* Try address only mapping */ + // try address only mapping m = nat44_ed_sm_i2o_lookup (sm, match_addr, 0, sm->outside_fib_index, 0); if (m) @@ -2626,7 +2758,7 @@ nat44_ed_sm_match (snat_main_t *sm, ip4_address_t match_addr, u16 match_port, if (m) return m; - /* Try address only mapping */ + // try address only mapping m = nat44_ed_sm_o2i_lookup (sm, match_addr, 0, 0, 0); if (m) return m; @@ -2635,15 +2767,16 @@ nat44_ed_sm_match (snat_main_t *sm, ip4_address_t match_addr, u16 match_port, } int -snat_static_mapping_match (vlib_main_t *vm, snat_main_t *sm, - ip4_address_t match_addr, u16 match_port, - u32 match_fib_index, ip_protocol_t match_protocol, +snat_static_mapping_match (vlib_main_t *vm, ip4_address_t match_addr, + u16 match_port, u32 match_fib_index, + ip_protocol_t match_protocol, ip4_address_t *mapping_addr, u16 *mapping_port, u32 *mapping_fib_index, int by_external, u8 *is_addr_only, twice_nat_type_t *twice_nat, lb_nat_type_t *lb, ip4_address_t *ext_host_addr, u8 *is_identity_nat, snat_static_mapping_t **out) { + snat_main_t *sm = &snat_main; snat_static_mapping_t *m; u32 rand, lo = 0, hi, mid, *tmp = 0, i; nat44_lb_addr_port_t *local; @@ -2787,7 +2920,7 @@ nat44_ed_get_in2out_worker_index (vlib_buffer_t *b, ip4_header_t *ip, if (PREDICT_FALSE (is_output)) { fib_index = sm->outside_fib_index; - nat_outside_fib_t *outside_fib; + nat_fib_t *outside_fib; fib_node_index_t fei = FIB_NODE_INDEX_INVALID; fib_prefix_t pfx = { .fp_proto = FIB_PROTOCOL_IP4, diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h index e2047fe12ac..1ca71187ac7 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.h +++ b/src/plugins/nat/nat44-ed/nat44_ed.h @@ -355,18 +355,6 @@ typedef struct typedef struct { - u32 fib_index; - u32 ref_count; -} nat_fib_t; - -typedef struct -{ - u32 fib_index; - u32 refcount; -} nat_outside_fib_t; - -typedef struct -{ /* backend IP address */ ip4_address_t addr; /* backend port number */ @@ -504,6 +492,25 @@ typedef int (nat_alloc_out_addr_and_port_function_t) ( ip_protocol_t proto, ip4_address_t *addr, u16 *port, u16 port_per_thread, u32 snat_thread_index); +typedef struct nat_fib_s +{ + u32 fib_index; + u32 ref_count; +} nat_fib_t; + +typedef struct vrf_route_s +{ + u32 vrf_id; + u32 fib_index; +} vrf_route_t; + +typedef struct vrf_table_s +{ + u32 table_vrf_id; + u32 table_fib_index; + vrf_route_t *routes; +} vrf_table_t; + typedef struct snat_main_s { /* Thread settings */ @@ -525,6 +532,21 @@ typedef struct snat_main_s /* Endpoint dependent lookup table */ clib_bihash_16_8_t flow_hash; + // vector of fibs + nat_fib_t *fibs; + + u32 inside_vrf_id; + u32 inside_fib_index; + + u32 outside_vrf_id; + u32 outside_fib_index; + + // vector of outside fibs + nat_fib_t *outside_fibs; + + // VRF routing table for dynamic sessions + vrf_table_t *vrf_tables; + /* Interface pool */ snat_interface_t *interfaces; snat_interface_t *output_feature_interfaces; @@ -539,12 +561,6 @@ typedef struct snat_main_s /* first interface address should be auto-added */ snat_address_resolve_t *addr_to_resolve; - /* vector of fibs */ - nat_fib_t *fibs; - - /* vector of outside fibs */ - nat_outside_fib_t *outside_fibs; - /* vector of fib entries */ snat_fib_entry_reg_t *fib_entry_reg; @@ -571,11 +587,6 @@ typedef struct snat_main_s u32 max_translations_per_thread; u32 *max_translations_per_fib; - u32 outside_vrf_id; - u32 outside_fib_index; - u32 inside_vrf_id; - u32 inside_fib_index; - nat_timeouts_t timeouts; /* TCP MSS clamping */ @@ -849,6 +860,10 @@ int nat44_ed_del_address (ip4_address_t addr, u8 twice_nat); int nat44_ed_add_interface_address (u32 sw_if_index, u8 twice_nat); int nat44_ed_del_interface_address (u32 sw_if_index, u8 twice_nat); +int nat44_ed_add_del_vrf_table (u32 table_vrf_id, bool is_add); +int nat44_ed_add_del_vrf_route (u32 table_vrf_id, u32 vrf_id, bool is_add); +void nat44_ed_del_vrf_tables (); + int nat44_ed_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port, ip_protocol_t proto, u32 vrf_id, u32 sw_if_index, u32 flags, @@ -910,31 +925,15 @@ int nat44_update_session_limit (u32 session_limit, u32 vrf_id); void expire_per_vrf_sessions (u32 fib_index); -/** - * @brief Match NAT44 static mapping. - * - * @param key address and port to match - * @param addr external/local address of the matched mapping - * @param port port of the matched mapping - * @param fib_index fib index of the matched mapping - * @param by_external if 0 match by local address otherwise match by external - * address - * @param is_addr_only 1 if matched mapping is address only - * @param twice_nat matched mapping is twice NAT type - * @param lb 1 if matched mapping is load-balanced - * @param ext_host_addr external host address - * @param is_identity_nat 1 if indentity mapping - * @param out if !=0 set to pointer of the mapping structure - * - * @returns 0 if match found otherwise 1. - */ -int snat_static_mapping_match ( - vlib_main_t *vm, snat_main_t *sm, ip4_address_t match_addr, u16 match_port, - u32 match_fib_index, ip_protocol_t match_protocol, - ip4_address_t *mapping_addr, u16 *mapping_port, u32 *mapping_fib_index, - int by_external, u8 *is_addr_only, twice_nat_type_t *twice_nat, - lb_nat_type_t *lb, ip4_address_t *ext_host_addr, u8 *is_identity_nat, - snat_static_mapping_t **out); +int snat_static_mapping_match (vlib_main_t *vm, ip4_address_t match_addr, + u16 match_port, u32 match_fib_index, + ip_protocol_t match_protocol, + ip4_address_t *mapping_addr, u16 *mapping_port, + u32 *mapping_fib_index, int by_external, + u8 *is_addr_only, twice_nat_type_t *twice_nat, + lb_nat_type_t *lb, ip4_address_t *ext_host_addr, + u8 *is_identity_nat, + snat_static_mapping_t **out); u32 get_thread_idx_by_port (u16 e_port); diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c index f4ba2bc9e8e..19e497e00c2 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_api.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c @@ -1194,6 +1194,79 @@ vl_api_nat44_show_running_config_t_handler ( })); } +static void +vl_api_nat44_ed_add_del_vrf_table_t_handler ( + vl_api_nat44_ed_add_del_vrf_table_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat44_ed_add_del_vrf_table_reply_t *rmp; + int rv = nat44_ed_add_del_vrf_table (clib_net_to_host_u32 (mp->table_vrf_id), + mp->is_add); + REPLY_MACRO (VL_API_NAT44_ED_ADD_DEL_VRF_TABLE); +} + +static void +vl_api_nat44_ed_add_del_vrf_route_t_handler ( + vl_api_nat44_ed_add_del_vrf_route_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_nat44_ed_add_del_vrf_route_reply_t *rmp; + int rv = + nat44_ed_add_del_vrf_route (clib_net_to_host_u32 (mp->table_vrf_id), + clib_net_to_host_u32 (mp->vrf_id), mp->is_add); + REPLY_MACRO (VL_API_NAT44_ED_ADD_DEL_VRF_ROUTE); +} + +static void +nat44_ed_vrf_tables_send_details (vl_api_registration_t *rp, u32 context, + vrf_table_t *t) +{ + snat_main_t *sm = &snat_main; + vl_api_nat44_ed_vrf_tables_details_t *mp; + + u32 *vrf_ids = 0; + vrf_route_t *r; + + mp = vl_msg_api_alloc_zero (sizeof (*mp) + + sizeof (mp->vrf_ids[0]) * vec_len (t->routes)); + mp->_vl_msg_id = + ntohs (VL_API_NAT44_ED_VRF_TABLES_DETAILS + sm->msg_id_base); + mp->context = context; + mp->n_vrf_ids = clib_host_to_net_u32 (vec_len (t->routes)); + + pool_foreach (r, t->routes) + { + vec_add1 (vrf_ids, r->vrf_id); + } + + // copy the records + clib_memcpy (mp->vrf_ids, vrf_ids, + sizeof (mp->vrf_ids[0]) * vec_len (t->routes)); + + vec_free (vrf_ids); + + // send the message + vl_api_send_msg (rp, (u8 *) mp); +} + +static void +vl_api_nat44_ed_vrf_tables_dump_t_handler ( + vl_api_nat44_ed_vrf_tables_dump_t *mp) +{ + snat_main_t *sm = &snat_main; + vl_api_registration_t *rp; + vrf_table_t *t; + + rp = vl_api_client_index_to_registration (mp->client_index); + if (rp == 0) + return; + + pool_foreach (t, sm->vrf_tables) + { + nat44_ed_vrf_tables_send_details (rp, mp->context, t); + } +} + /* user (internal host) key */ typedef struct { diff --git a/src/plugins/nat/nat44-ed/nat44_ed_cfg.c b/src/plugins/nat/nat44-ed/nat44_ed_cfg.c deleted file mode 100644 index e69de29bb2d..00000000000 --- a/src/plugins/nat/nat44-ed/nat44_ed_cfg.c +++ /dev/null diff --git a/src/plugins/nat/nat44-ed/nat44_ed_cli.c b/src/plugins/nat/nat44-ed/nat44_ed_cli.c index 7693063b8d8..bddd635272c 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_cli.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_cli.c @@ -916,8 +916,6 @@ add_static_mapping_command_fn (vlib_main_t * vm, e_port = clib_host_to_net_u16 (e_port); } - // TODO: specific pool_addr for both pool & twice nat pool ? - if (is_add) { rv = @@ -930,25 +928,17 @@ add_static_mapping_command_fn (vlib_main_t * vm, vrf_id, sw_if_index, flags); } - // TODO: fix returns - switch (rv) { - case VNET_API_ERROR_INVALID_VALUE: - error = clib_error_return (0, "External port already in use."); - goto done; + case VNET_API_ERROR_UNSUPPORTED: + error = clib_error_return (0, "Plugin disabled."); + break; case VNET_API_ERROR_NO_SUCH_ENTRY: - if (is_add) - error = clib_error_return (0, "External address must be allocated."); - else - error = clib_error_return (0, "Mapping not exist."); - goto done; - case VNET_API_ERROR_NO_SUCH_FIB: - error = clib_error_return (0, "No such VRF id."); - goto done; + error = clib_error_return (0, "Mapping not exist."); + break; case VNET_API_ERROR_VALUE_EXIST: error = clib_error_return (0, "Mapping already exist."); - goto done; + break; default: break; } @@ -959,7 +949,6 @@ done: return error; } -// TODO: either delete this bullshit or update it static clib_error_t * add_identity_mapping_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -976,7 +965,6 @@ add_identity_mapping_command_fn (vlib_main_t * vm, flags = NAT_SM_FLAG_IDENTITY_NAT; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -1029,25 +1017,17 @@ add_identity_mapping_command_fn (vlib_main_t * vm, sw_if_index, flags); } - // TODO: fix returns - switch (rv) { - case VNET_API_ERROR_INVALID_VALUE: - error = clib_error_return (0, "External port already in use."); - goto done; + case VNET_API_ERROR_UNSUPPORTED: + error = clib_error_return (0, "Plugin disabled."); + break; case VNET_API_ERROR_NO_SUCH_ENTRY: - if (is_add) - error = clib_error_return (0, "External address must be allocated."); - else - error = clib_error_return (0, "Mapping not exist."); - goto done; - case VNET_API_ERROR_NO_SUCH_FIB: - error = clib_error_return (0, "No such VRF id."); - goto done; + error = clib_error_return (0, "Mapping not exist."); + break; case VNET_API_ERROR_VALUE_EXIST: error = clib_error_return (0, "Mapping already exist."); - goto done; + break; default: break; } @@ -1073,7 +1053,6 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm, int rv, is_add = 1; u32 flags = 0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -1342,6 +1321,156 @@ done: } static clib_error_t * +nat44_ed_add_del_vrf_table_command_fn (vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = 0; + bool is_add = true, not_set = true; + u32 vrf_id = ~0; + int rv; + + if (!unformat_user (input, unformat_line_input, line_input)) + return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%u", &vrf_id)) + ; + else if (not_set) + { + if (unformat (line_input, "add")) + { + is_add = true; + } + else if (unformat (line_input, "del")) + { + is_add = false; + } + not_set = false; + } + else + { + error = clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input); + goto done; + } + } + + if (not_set) + { + error = clib_error_return (0, "missing required parameter"); + goto done; + } + + if (~0 == vrf_id) + { + error = clib_error_return (0, "missing vrf id"); + goto done; + } + + rv = nat44_ed_add_del_vrf_table (vrf_id, is_add); + if (rv) + { + error = clib_error_return (0, "%s vrf table returned %d", + is_add ? "add" : "del", rv); + } + +done: + unformat_free (line_input); + + return error; +} + +static clib_error_t * +nat44_ed_add_del_vrf_route_command_fn (vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = 0; + bool is_add = true, not_set = true; + u32 vrf_id = ~0, table_vrf_id = ~0; + int rv; + + if (!unformat_user (input, unformat_line_input, line_input)) + return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "table %u", &table_vrf_id)) + ; + else if (unformat (line_input, "%u", &vrf_id)) + ; + else if (not_set) + { + if (unformat (line_input, "add")) + { + is_add = true; + } + else if (unformat (line_input, "del")) + { + is_add = false; + } + not_set = false; + } + else + { + error = clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input); + goto done; + } + } + + if (not_set) + { + error = clib_error_return (0, "missing required parameter"); + goto done; + } + + if ((~0 == vrf_id) || (~0 == table_vrf_id)) + { + error = clib_error_return (0, "missing vrf id"); + goto done; + } + + rv = nat44_ed_add_del_vrf_route (table_vrf_id, vrf_id, is_add); + if (rv) + { + error = clib_error_return (0, "%s vrf table returned %d", + is_add ? "add" : "del", rv); + } + +done: + unformat_free (line_input); + + return error; +} + +static clib_error_t * +nat44_ed_show_vrf_tables_command_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + snat_main_t *sm = &snat_main; + vrf_table_t *t; + vrf_route_t *r; + int i = 0; + + pool_foreach (t, sm->vrf_tables) + { + vlib_cli_output (vm, "table %u:", t->table_vrf_id); + pool_foreach (r, t->routes) + { + vlib_cli_output (vm, "[%u] vrf-id %u", i, r->vrf_id); + i++; + } + } + + return 0; +} + +static clib_error_t * nat44_show_interface_address_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -2093,6 +2222,45 @@ VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = { /*? * @cliexpar + * @cliexstart{nat44 vrf table} + * Add empty inter VRF routing table + * vpp# nat44 vrf table add 10 + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_table_command, static) = { + .path = "nat44 vrf table", + .short_help = "nat44 vrf table [add|del] <vrf-id>", + .function = nat44_ed_add_del_vrf_table_command_fn, +}; + +/*? + * @cliexpar + * @cliexstart{nat44 vrf route} + * Add inter VRF route record to VRF routing table + * vpp# nat44 vrf route add table 10 20 + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_route_command, static) = { + .path = "nat44 vrf route", + .short_help = "nat44 vrf route [add|del] table <vrf-id> <vrf-id>", + .function = nat44_ed_add_del_vrf_route_command_fn, +}; + +/*? + * @cliexpar + * @cliexstart{show nat44 vrf tables} + * Show inter VRF route tables + * vpp# show nat44 vrf tables + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat44_ed_show_vrf_tables_command, static) = { + .path = "show nat44 vrf tables", + .short_help = "show nat44 vrf tables", + .function = nat44_ed_show_vrf_tables_command_fn, +}; + +/*? + * @cliexpar * @cliexstart{show nat44 interface address} * Show NAT44 pool address interfaces * vpp# show nat44 interface address diff --git a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c index 6e0a21d890a..179405e72b7 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c @@ -96,74 +96,6 @@ format_nat_in2out_ed_trace (u8 * s, va_list * args) return s; } -/** - * @brief Check if packet should be translated - * - * Packets aimed at outside interface and external address with active session - * should be translated. - * - * @param sm NAT main - * @param rt NAT runtime data - * @param sw_if_index0 index of the inside interface - * @param ip0 IPv4 header - * @param rx_fib_index0 RX FIB index - * - * @returns 0 if packet should be translated otherwise 1 - */ -static inline int -snat_not_translate_fast (snat_main_t *sm, vlib_node_runtime_t *node, - u32 sw_if_index0, ip4_header_t *ip0, - u32 rx_fib_index0) -{ - fib_node_index_t fei = FIB_NODE_INDEX_INVALID; - nat_outside_fib_t *outside_fib; - fib_prefix_t pfx = { - .fp_proto = FIB_PROTOCOL_IP4, - .fp_len = 32, - .fp_addr = { - .ip4.as_u32 = ip0->dst_address.as_u32, - } - , - }; - - /* Don't NAT packet aimed at the intfc address */ - if (PREDICT_FALSE ( - is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32))) - return 1; - - fei = fib_table_lookup (rx_fib_index0, &pfx); - if (FIB_NODE_INDEX_INVALID != fei) - { - u32 sw_if_index = fib_entry_get_resolving_interface (fei); - if (sw_if_index == ~0) - { - vec_foreach (outside_fib, sm->outside_fibs) - { - fei = fib_table_lookup (outside_fib->fib_index, &pfx); - if (FIB_NODE_INDEX_INVALID != fei) - { - sw_if_index = fib_entry_get_resolving_interface (fei); - if (sw_if_index != ~0) - break; - } - } - } - if (sw_if_index == ~0) - return 1; - - snat_interface_t *i; - pool_foreach (i, sm->interfaces) - { - /* NAT packet aimed at outside interface */ - if ((nat44_ed_is_interface_outside (i)) && - (sw_if_index == i->sw_if_index)) - return 0; - } - } - - return 1; -} - static int nat_ed_alloc_addr_and_port_with_snat_address ( snat_main_t *sm, u8 proto, u32 thread_index, snat_address_t *a, @@ -340,31 +272,6 @@ nat_ed_alloc_addr_and_port (snat_main_t *sm, u32 rx_fib_index, return 1; } -static_always_inline u32 -nat_outside_fib_index_lookup (snat_main_t * sm, ip4_address_t addr) -{ - fib_node_index_t fei = FIB_NODE_INDEX_INVALID; - nat_outside_fib_t *outside_fib; - fib_prefix_t pfx = { - .fp_proto = FIB_PROTOCOL_IP4, - .fp_len = 32, - .fp_addr = {.ip4.as_u32 = addr.as_u32,} - , - }; - 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) - { - return outside_fib->fib_index; - } - } - } - return ~0; -} - static_always_inline int nat44_ed_external_sm_lookup (snat_main_t *sm, ip4_address_t match_addr, u16 match_port, ip_protocol_t match_protocol, @@ -388,6 +295,131 @@ nat44_ed_external_sm_lookup (snat_main_t *sm, ip4_address_t match_addr, return 1; } +static_always_inline vrf_table_t * +get_vrf_table_by_fib (u32 fib_index) +{ + snat_main_t *sm = &snat_main; + vrf_table_t *t; + + pool_foreach (t, sm->vrf_tables) + { + if (fib_index == t->table_fib_index) + { + return t; + } + } + + return 0; +} + +static_always_inline u32 +get_tx_fib_index (u32 rx_fib_index, ip4_address_t addr) +{ + fib_node_index_t fei = FIB_NODE_INDEX_INVALID; + fib_prefix_t pfx = { + .fp_proto = FIB_PROTOCOL_IP4, + .fp_len = 32, + .fp_addr = {.ip4.as_u32 = addr.as_u32,} + , + }; + + snat_main_t *sm = &snat_main; + vrf_table_t *t = get_vrf_table_by_fib (rx_fib_index); + // default to rx fib + u32 tx_fib_index = rx_fib_index; + + if (0 != t) + { + // managed routes to other fibs + vrf_route_t *r; + pool_foreach (r, t->routes) + { + fei = fib_table_lookup (r->fib_index, &pfx); + if ((FIB_NODE_INDEX_INVALID != fei) && + (~0 != fib_entry_get_resolving_interface (fei))) + { + tx_fib_index = r->fib_index; + break; + } + } + } + else + { + // default to configured fib + tx_fib_index = sm->outside_fib_index; + + // default routes to other fibs + nat_fib_t *f; + vec_foreach (f, sm->outside_fibs) + { + fei = fib_table_lookup (f->fib_index, &pfx); + if ((FIB_NODE_INDEX_INVALID != fei) && + (~0 != fib_entry_get_resolving_interface (fei))) + { + tx_fib_index = f->fib_index; + break; + } + } + } + + return tx_fib_index; +} + +static_always_inline int +is_destination_resolvable (u32 rx_fib_index, ip4_address_t addr) +{ + fib_node_index_t fei = FIB_NODE_INDEX_INVALID; + fib_prefix_t pfx = { + .fp_proto = FIB_PROTOCOL_IP4, + .fp_len = 32, + .fp_addr = {.ip4.as_u32 = addr.as_u32,} + , + }; + + snat_main_t *sm = &snat_main; + vrf_table_t *t = get_vrf_table_by_fib (rx_fib_index); + u32 ii; + + if (0 != t) + { + // managed routes to other fibs + vrf_route_t *r; + pool_foreach (r, t->routes) + { + fei = fib_table_lookup (r->fib_index, &pfx); + if ((FIB_NODE_INDEX_INVALID != fei) && + (~0 != (ii = fib_entry_get_resolving_interface (fei)))) + { + return 1; + } + } + } + else + { + // default routes to other fibs + nat_fib_t *f; + vec_foreach (f, sm->outside_fibs) + { + fei = fib_table_lookup (f->fib_index, &pfx); + if ((FIB_NODE_INDEX_INVALID != fei) && + (~0 != (ii = fib_entry_get_resolving_interface (fei)))) + { + snat_interface_t *i; + pool_foreach (i, sm->interfaces) + { + if ((nat44_ed_is_interface_outside (i)) && + (ii == i->sw_if_index)) + { + return 1; + } + } + } + } + } + + return 0; +} + static u32 slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, ip4_address_t l_addr, ip4_address_t r_addr, u16 l_port, @@ -398,7 +430,7 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; ip4_address_t outside_addr; u16 outside_port; - u32 outside_fib_index; + u32 tx_fib_index; u8 is_identity_nat = 0; snat_session_t *s = NULL; @@ -419,33 +451,14 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, } } - outside_fib_index = sm->outside_fib_index; - - switch (vec_len (sm->outside_fibs)) - { - case 0: - outside_fib_index = sm->outside_fib_index; - break; - case 1: - outside_fib_index = sm->outside_fibs[0].fib_index; - break; - default: - outside_fib_index = nat_outside_fib_index_lookup (sm, r_addr); - break; - } - ip4_address_t sm_addr; u16 sm_port; u32 sm_fib_index; - /* First try to match static mapping by local address and port */ - int is_sm; - if (snat_static_mapping_match (vm, sm, l_addr, l_port, rx_fib_index, proto, - &sm_addr, &sm_port, &sm_fib_index, 0, 0, 0, - &lb, 0, &is_identity_nat, 0)) - { - is_sm = 0; - } - else + int is_sm = 0; + // First try to match static mapping by local address and port + if (!snat_static_mapping_match (vm, l_addr, l_port, rx_fib_index, proto, + &sm_addr, &sm_port, &sm_fib_index, 0, 0, 0, + &lb, 0, &is_identity_nat, 0)) { if (PREDICT_FALSE (is_identity_nat)) { @@ -468,21 +481,24 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, s = nat_ed_session_alloc (sm, thread_index, now, proto); ASSERT (s); + tx_fib_index = get_tx_fib_index (rx_fib_index, r_addr); + if (!is_sm) { s->in2out.addr = l_addr; s->in2out.port = l_port; s->proto = proto; s->in2out.fib_index = rx_fib_index; - s->out2in.fib_index = outside_fib_index; + s->out2in.fib_index = tx_fib_index; // suggest using local port to allocation function outside_port = l_port; - // hairpinning? - int is_hairpinning = nat44_ed_external_sm_lookup (sm, r_addr, r_port, - proto, &daddr, &dport); - s->flags |= is_hairpinning * SNAT_SESSION_FLAG_HAIRPINNING; + if (PREDICT_FALSE (nat44_ed_external_sm_lookup (sm, r_addr, r_port, + proto, &daddr, &dport))) + { + s->flags |= SNAT_SESSION_FLAG_HAIRPINNING; + } // destination addr/port updated with real values in // nat_ed_alloc_addr_and_port @@ -520,7 +536,7 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, s->in2out.port = l_port; s->proto = proto; s->in2out.fib_index = rx_fib_index; - s->out2in.fib_index = outside_fib_index; + s->out2in.fib_index = tx_fib_index; s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING; // hairpinning? @@ -568,7 +584,7 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, nat_6t_flow_sport_rewrite_set (&s->i2o, outside_port); nat_6t_flow_dport_rewrite_set (&s->i2o, dport); } - nat_6t_flow_txfib_rewrite_set (&s->i2o, outside_fib_index); + nat_6t_flow_txfib_rewrite_set (&s->i2o, tx_fib_index); if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1)) { @@ -600,38 +616,55 @@ error: } static_always_inline int -nat44_ed_not_translate (vlib_main_t *vm, snat_main_t *sm, - vlib_node_runtime_t *node, u32 sw_if_index, - vlib_buffer_t *b, ip4_header_t *ip, u32 proto, - u32 rx_fib_index) +nat44_ed_not_translate (vlib_main_t *vm, vlib_node_runtime_t *node, + u32 sw_if_index, vlib_buffer_t *b, ip4_header_t *ip, + u32 proto, u32 rx_fib_index) { + snat_main_t *sm = &snat_main; + clib_bihash_kv_16_8_t kv, value; + ip4_address_t placeholder_addr; + u32 placeholder_fib_index; + u16 placeholder_port; init_ed_k (&kv, ip->dst_address.as_u32, vnet_buffer (b)->ip.reass.l4_dst_port, ip->src_address.as_u32, vnet_buffer (b)->ip.reass.l4_src_port, sm->outside_fib_index, ip->protocol); - /* NAT packet aimed at external address if has active sessions */ - if (clib_bihash_search_16_8 (&sm->flow_hash, &kv, &value)) + // do nat if active session or is static mapping + if (!clib_bihash_search_16_8 (&sm->flow_hash, &kv, &value) || + !snat_static_mapping_match ( + vm, ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port, + sm->outside_fib_index, proto, &placeholder_addr, &placeholder_port, + &placeholder_fib_index, 1, 0, 0, 0, 0, 0, 0)) { - /* or is static mappings */ - ip4_address_t placeholder_addr; - u16 placeholder_port; - u32 placeholder_fib_index; - if (!snat_static_mapping_match ( - vm, sm, ip->dst_address, vnet_buffer (b)->ip.reass.l4_dst_port, - sm->outside_fib_index, proto, &placeholder_addr, &placeholder_port, - &placeholder_fib_index, 1, 0, 0, 0, 0, 0, 0)) - return 0; + return 0; } - else - return 0; + // do not nat if forwarding enabled if (sm->forwarding_enabled) - return 1; + { + return 1; + } - return snat_not_translate_fast (sm, node, sw_if_index, ip, rx_fib_index); + // do not nat packet aimed at the interface address + if (PREDICT_FALSE ( + is_interface_addr (sm, node, sw_if_index, ip->dst_address.as_u32))) + { + return 1; + } + + // do nat packets with resolvable destination + // destination can be resolved either by: + // a) vrf routing table entry + // b) (non output feature) outside interface fib + if (is_destination_resolvable (rx_fib_index, ip->dst_address)) + { + return 0; + } + + return 1; } static_always_inline int @@ -810,7 +843,7 @@ icmp_in2out_ed_slow_path (snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, else { if (PREDICT_FALSE (nat44_ed_not_translate ( - vm, sm, node, sw_if_index, b, ip, IP_PROTOCOL_ICMP, rx_fib_index))) + vm, node, sw_if_index, b, ip, IP_PROTOCOL_ICMP, rx_fib_index))) { return next; } @@ -868,7 +901,7 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b, snat_static_mapping_t *m = NULL; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; snat_session_t *s = NULL; - u32 outside_fib_index = sm->outside_fib_index; + u32 tx_fib_index; int i; ip4_address_t new_src_addr = { 0 }; ip4_address_t new_dst_addr = ip->dst_address; @@ -883,20 +916,9 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b, return 0; } - switch (vec_len (sm->outside_fibs)) - { - case 0: - outside_fib_index = sm->outside_fib_index; - break; - case 1: - outside_fib_index = sm->outside_fibs[0].fib_index; - break; - default: - outside_fib_index = nat_outside_fib_index_lookup (sm, ip->dst_address); - break; - } + tx_fib_index = get_tx_fib_index (rx_fib_index, ip->dst_address); - /* Try to find static mapping first */ + // Try to find static mapping first m = nat44_ed_sm_i2o_lookup (sm, ip->src_address, 0, rx_fib_index, ip->protocol); if (m) @@ -910,7 +932,7 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b, if (s->ext_host_addr.as_u32 == ip->dst_address.as_u32) { init_ed_k (&s_kv, s->out2in.addr.as_u32, 0, - ip->dst_address.as_u32, 0, outside_fib_index, + ip->dst_address.as_u32, 0, tx_fib_index, ip->protocol); if (clib_bihash_search_16_8 (&sm->flow_hash, &s_kv, &s_value)) { @@ -925,7 +947,7 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b, for (i = 0; i < vec_len (sm->addresses); i++) { init_ed_k (&s_kv, sm->addresses[i].addr.as_u32, 0, - ip->dst_address.as_u32, 0, outside_fib_index, + ip->dst_address.as_u32, 0, tx_fib_index, ip->protocol); if (clib_bihash_search_16_8 (&sm->flow_hash, &s_kv, &s_value)) { @@ -952,7 +974,7 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b, nat_6t_i2o_flow_init (sm, thread_index, s, ip->src_address, 0, ip->dst_address, 0, rx_fib_index, ip->protocol); nat_6t_flow_saddr_rewrite_set (&s->i2o, new_src_addr.as_u32); - nat_6t_flow_txfib_rewrite_set (&s->i2o, outside_fib_index); + nat_6t_flow_txfib_rewrite_set (&s->i2o, tx_fib_index); // hairpinning? int is_hairpinning = nat44_ed_external_sm_lookup ( @@ -960,17 +982,17 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b, s->flags |= is_hairpinning * SNAT_SESSION_FLAG_HAIRPINNING; nat_6t_flow_daddr_rewrite_set (&s->i2o, new_dst_addr.as_u32); - nat_6t_flow_txfib_rewrite_set (&s->i2o, outside_fib_index); + nat_6t_flow_txfib_rewrite_set (&s->i2o, tx_fib_index); nat_6t_o2i_flow_init (sm, thread_index, s, new_dst_addr, 0, new_src_addr, 0, - outside_fib_index, ip->protocol); + tx_fib_index, ip->protocol); nat_6t_flow_saddr_rewrite_set (&s->o2i, ip->dst_address.as_u32); nat_6t_flow_daddr_rewrite_set (&s->o2i, ip->src_address.as_u32); nat_6t_flow_txfib_rewrite_set (&s->o2i, rx_fib_index); s->ext_host_addr.as_u32 = ip->dst_address.as_u32; s->out2in.addr.as_u32 = new_src_addr.as_u32; - s->out2in.fib_index = outside_fib_index; + s->out2in.fib_index = tx_fib_index; s->in2out.addr.as_u32 = ip->src_address.as_u32; s->in2out.fib_index = rx_fib_index; s->in2out.port = s->out2in.port = ip->protocol; @@ -1445,8 +1467,8 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t *vm, else { if (PREDICT_FALSE ( - nat44_ed_not_translate (vm, sm, node, rx_sw_if_index0, b0, - ip0, proto0, rx_fib_index0))) + nat44_ed_not_translate (vm, node, rx_sw_if_index0, b0, ip0, + proto0, rx_fib_index0))) goto trace0; } diff --git a/src/plugins/nat/nat44-ed/nat44_ed_out2in.c b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c index aa0cc508f08..e53d9c5a2de 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_out2in.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c @@ -182,7 +182,7 @@ icmp_out2in_ed_slow_path (snat_main_t *sm, vlib_buffer_t *b, ip4_header_t *ip, goto out; } - if (snat_static_mapping_match (vm, sm, ip->dst_address, lookup_sport, + if (snat_static_mapping_match (vm, ip->dst_address, lookup_sport, rx_fib_index, ip->protocol, &sm_addr, &sm_port, &sm_fib_index, 1, &is_addr_only, 0, 0, 0, &identity_nat, &m)) @@ -1164,10 +1164,9 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm, destination address and port in packet */ if (snat_static_mapping_match ( - vm, sm, ip0->dst_address, - vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, proto0, - &sm_addr, &sm_port, &sm_fib_index, 1, 0, &twice_nat0, &lb_nat0, - &ip0->src_address, &identity_nat0, &m)) + vm, ip0->dst_address, vnet_buffer (b0)->ip.reass.l4_dst_port, + rx_fib_index0, proto0, &sm_addr, &sm_port, &sm_fib_index, 1, 0, + &twice_nat0, &lb_nat0, &ip0->src_address, &identity_nat0, &m)) { /* * Send DHCP packets to the ipv4 stack, or we won't |