X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat.c;h=90515acc5b6071f2d0edd6f4fa2edad21e6ef012;hb=c5c6a3342f3cbaaac647d52fd960b6f5b0fcd4e0;hp=e9b2c2c07ba77200cac4e751d7cf131be47ee8f1;hpb=529a425b04751d0590de2f398a20bd36d0e25308;p=vpp.git diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index e9b2c2c07ba..90515acc5b6 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -567,7 +568,7 @@ void snat_add_address (snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, /* Add external address to FIB */ pool_foreach (i, sm->interfaces, ({ - if (nat_interface_is_inside(i)) + if (nat_interface_is_inside(i) || sm->out2in_dpo) continue; snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1); @@ -575,7 +576,7 @@ void snat_add_address (snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, })); pool_foreach (i, sm->output_feature_interfaces, ({ - if (nat_interface_is_inside(i)) + if (nat_interface_is_inside(i) || sm->out2in_dpo) continue; snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1); @@ -951,7 +952,7 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, /* Add/delete external address to FIB */ pool_foreach (interface, sm->interfaces, ({ - if (nat_interface_is_inside(interface)) + if (nat_interface_is_inside(interface) || sm->out2in_dpo) continue; snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add); @@ -959,7 +960,7 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, })); pool_foreach (interface, sm->output_feature_interfaces, ({ - if (nat_interface_is_inside(interface)) + if (nat_interface_is_inside(interface) || sm->out2in_dpo) continue; snat_add_del_addr_to_fib(&e_addr, 32, interface->sw_if_index, is_add); @@ -1324,7 +1325,7 @@ snat_del_address (snat_main_t *sm, ip4_address_t addr, u8 delete_sm, /* Delete external address from FIB */ pool_foreach (interface, sm->interfaces, ({ - if (nat_interface_is_inside(interface)) + if (nat_interface_is_inside(interface) || sm->out2in_dpo) continue; snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0); @@ -1332,7 +1333,7 @@ snat_del_address (snat_main_t *sm, ip4_address_t addr, u8 delete_sm, })); pool_foreach (interface, sm->output_feature_interfaces, ({ - if (nat_interface_is_inside(interface)) + if (nat_interface_is_inside(interface) || sm->out2in_dpo) continue; snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0); @@ -1351,6 +1352,9 @@ int snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del) snat_static_mapping_t * m; snat_det_map_t * dm; + if (sm->out2in_dpo && !is_inside) + return VNET_API_ERROR_UNSUPPORTED; + if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)) feature_name = is_inside ? "nat44-in2out-fast" : "nat44-out2in-fast"; else @@ -1452,7 +1456,7 @@ set_flags: /* Add/delete external addresses to FIB */ fib: - if (is_inside) + if (is_inside && !sm->out2in_dpo) { vnet_feature_enable_disable ("ip4-local", "nat44-hairpinning", sw_if_index, !is_del, 0, 0); @@ -1582,7 +1586,7 @@ int snat_set_workers (uword * bitmap) clib_bitmap_foreach (i, bitmap, ({ vec_add1(sm->workers, i); - sm->per_thread_data[i].snat_thread_index = j; + sm->per_thread_data[sm->first_worker_index + i].snat_thread_index = j; j++; })); @@ -1680,6 +1684,8 @@ static clib_error_t * snat_init (vlib_main_t * vm) vec_add1 (im->add_del_interface_address_callbacks, cb4); + nat_dpo_module_init (); + /* Init IPFIX logging */ snat_ipfix_logging_init(vm); @@ -1988,6 +1994,29 @@ exhausted: return 1; } +void +nat44_add_del_address_dpo (ip4_address_t addr, u8 is_add) +{ + dpo_id_t dpo_v4 = DPO_INVALID; + fib_prefix_t pfx = { + .fp_proto = FIB_PROTOCOL_IP4, + .fp_len = 32, + .fp_addr.ip4.as_u32 = addr.as_u32, + }; + + if (is_add) + { + nat_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4); + fib_table_entry_special_dpo_add (0, &pfx, FIB_SOURCE_PLUGIN_HI, + FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4); + dpo_reset (&dpo_v4); + } + else + { + fib_table_entry_special_remove (0, &pfx, FIB_SOURCE_PLUGIN_HI); + } +} + static clib_error_t * add_address_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -2074,6 +2103,9 @@ add_address_command_fn (vlib_main_t * vm, break; } + if (sm->out2in_dpo) + nat44_add_del_address_dpo (this_addr, is_add); + increment_v4_address (&this_addr); } @@ -2726,6 +2758,7 @@ snat_get_worker_out2in_cb (ip4_header_t * ip0, u32 rx_fib_index0) snat_session_t *s; int i; u32 proto; + u32 next_worker_index = 0; /* first try static mappings without port */ if (PREDICT_FALSE (pool_elts (sm->static_mappings))) @@ -2841,7 +2874,10 @@ snat_get_worker_out2in_cb (ip4_header_t * ip0, u32 rx_fib_index0) } /* worker by outside port */ - return (u32) ((clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread); + next_worker_index = sm->first_worker_index; + next_worker_index += + sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread]; + return next_worker_index; } static clib_error_t * @@ -2864,8 +2900,10 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) u8 static_mapping_only = 0; u8 static_mapping_connection_tracking = 0; snat_main_per_thread_data_t *tsm; + dslite_main_t * dm = &dslite_main; sm->deterministic = 0; + sm->out2in_dpo = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -2906,6 +2944,10 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) else if (unformat (input, "nat64 st hash memory %d", &nat64_st_memory_size)) ; + else if (unformat (input, "out2in dpo")) + sm->out2in_dpo = 1; + else if (unformat (input, "dslite ce")) + dslite_set_ce(dm, 1); else return clib_error_return (0, "unknown input '%U'", format_unformat_error, input);