X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat.c;h=ea1add6abd029673506a4a5ce6c5f9269e2298f5;hb=603e75465;hp=60ef22f05cc7a8b2ebf592944e74442be2e8470e;hpb=cf9bb22a9483b97b00b7dcacc35b37ae0fcaefbe;p=vpp.git diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index 60ef22f05cc..ea1add6abd0 100644 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -22,9 +22,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -85,22 +83,6 @@ VNET_FEATURE_INIT (ip4_nat_classify, static) = { .node_name = "nat44-classify", .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"), }; -VNET_FEATURE_INIT (ip4_snat_det_in2out, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-det-in2out", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"), -}; -VNET_FEATURE_INIT (ip4_snat_det_out2in, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-det-out2in", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature", - "ip4-dhcp-client-detect"), -}; -VNET_FEATURE_INIT (ip4_nat_det_classify, static) = { - .arc_name = "ip4-unicast", - .node_name = "nat44-det-classify", - .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"), -}; VNET_FEATURE_INIT (ip4_nat44_ed_in2out, static) = { .arc_name = "ip4-unicast", .node_name = "nat44-ed-in2out", @@ -1798,6 +1780,40 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm, return 0; } +static void +nat_validate_counters (snat_main_t * sm, u32 sw_if_index) +{ +#define _(x) \ + vlib_validate_simple_counter (&sm->counters.fastpath.in2out.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.fastpath.in2out.x, sw_if_index); \ + vlib_validate_simple_counter (&sm->counters.fastpath.out2in.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.fastpath.out2in.x, sw_if_index); \ + vlib_validate_simple_counter (&sm->counters.slowpath.in2out.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.slowpath.in2out.x, sw_if_index); \ + vlib_validate_simple_counter (&sm->counters.slowpath.out2in.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.slowpath.out2in.x, sw_if_index); \ + vlib_validate_simple_counter (&sm->counters.fastpath.in2out_ed.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.fastpath.in2out_ed.x, sw_if_index); \ + vlib_validate_simple_counter (&sm->counters.fastpath.out2in_ed.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.fastpath.out2in_ed.x, sw_if_index); \ + vlib_validate_simple_counter (&sm->counters.slowpath.in2out_ed.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.slowpath.in2out_ed.x, sw_if_index); \ + vlib_validate_simple_counter (&sm->counters.slowpath.out2in_ed.x, \ + sw_if_index); \ + vlib_zero_simple_counter (&sm->counters.slowpath.out2in_ed.x, sw_if_index); + foreach_nat_counter; +#undef _ + vlib_validate_simple_counter (&sm->counters.hairpinning, sw_if_index); + vlib_zero_simple_counter (&sm->counters.hairpinning, sw_if_index); +} + int snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del) { @@ -1806,7 +1822,6 @@ snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del) const char *feature_name, *del_feature_name; snat_address_t *ap; snat_static_mapping_t *m; - snat_det_map_t *dm; nat_outside_fib_t *outside_fib; u32 fib_index = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index); @@ -1826,12 +1841,10 @@ snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del) feature_name = is_inside ? "nat44-in2out-fast" : "nat44-out2in-fast"; else { - if (sm->num_workers > 1 && !sm->deterministic) + if (sm->num_workers > 1) feature_name = is_inside ? "nat44-in2out-worker-handoff" : "nat44-out2in-worker-handoff"; - else if (sm->deterministic) - feature_name = is_inside ? "nat44-det-in2out" : "nat44-det-out2in"; else if (sm->endpoint_dependent) { feature_name = is_inside ? "nat-pre-in2out" : "nat-pre-out2in"; @@ -1840,11 +1853,11 @@ snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del) feature_name = is_inside ? "nat44-in2out" : "nat44-out2in"; } - if (sm->fq_in2out_index == ~0 && !sm->deterministic && sm->num_workers > 1) + if (sm->fq_in2out_index == ~0 && sm->num_workers > 1) sm->fq_in2out_index = vlib_frame_queue_main_init (sm->in2out_node_index, NAT_FQ_NELTS); - if (sm->fq_out2in_index == ~0 && !sm->deterministic && sm->num_workers > 1) + if (sm->fq_out2in_index == ~0 && sm->num_workers > 1) sm->fq_out2in_index = vlib_frame_queue_main_init (sm->out2in_node_index, NAT_FQ_NELTS); @@ -1889,18 +1902,12 @@ feature_set: else i->flags &= ~NAT_INTERFACE_FLAG_IS_OUTSIDE; - if (sm->num_workers > 1 && !sm->deterministic) + if (sm->num_workers > 1) { del_feature_name = "nat44-handoff-classify"; feature_name = !is_inside ? "nat44-in2out-worker-handoff" : "nat44-out2in-worker-handoff"; } - else if (sm->deterministic) - { - del_feature_name = "nat44-det-classify"; - feature_name = !is_inside ? "nat44-det-in2out" : - "nat44-det-out2in"; - } else if (sm->endpoint_dependent) { del_feature_name = "nat44-ed-classify"; @@ -1926,7 +1933,7 @@ feature_set: vnet_feature_enable_disable ("ip4-local", "nat44-ed-hairpinning", sw_if_index, 1, 0, 0); - else if (!sm->deterministic) + else vnet_feature_enable_disable ("ip4-local", "nat44-hairpinning", sw_if_index, 1, 0, 0); @@ -1946,7 +1953,7 @@ feature_set: vnet_feature_enable_disable ("ip4-local", "nat44-ed-hairpinning", sw_if_index, 0, 0, 0); - else if (!sm->deterministic) + else vnet_feature_enable_disable ("ip4-local", "nat44-hairpinning", sw_if_index, 0, 0, 0); @@ -1959,18 +1966,12 @@ feature_set: (nat_interface_is_outside(i) && !is_inside)) return 0; - if (sm->num_workers > 1 && !sm->deterministic) + if (sm->num_workers > 1) { del_feature_name = !is_inside ? "nat44-in2out-worker-handoff" : "nat44-out2in-worker-handoff"; feature_name = "nat44-handoff-classify"; } - else if (sm->deterministic) - { - del_feature_name = !is_inside ? "nat44-det-in2out" : - "nat44-det-out2in"; - feature_name = "nat44-det-classify"; - } else if (sm->endpoint_dependent) { del_feature_name = !is_inside ? "nat-pre-in2out" : @@ -1996,7 +1997,7 @@ feature_set: if (sm->endpoint_dependent) vnet_feature_enable_disable ("ip4-local", "nat44-ed-hairpinning", sw_if_index, 0, 0, 0); - else if (!sm->deterministic) + else vnet_feature_enable_disable ("ip4-local", "nat44-hairpinning", sw_if_index, 0, 0, 0); } @@ -2014,6 +2015,8 @@ feature_set: pool_get (sm->interfaces, i); i->sw_if_index = sw_if_index; i->flags = 0; + nat_validate_counters (sm, sw_if_index); + vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index, 1, 0, 0); @@ -2026,7 +2029,7 @@ feature_set: if (sm->endpoint_dependent) vnet_feature_enable_disable ("ip4-local", "nat44-ed-hairpinning", sw_if_index, 1, 0, 0); - else if (!sm->deterministic) + else vnet_feature_enable_disable ("ip4-local", "nat44-hairpinning", sw_if_index, 1, 0, 0); } @@ -2053,11 +2056,6 @@ fib: snat_add_del_addr_to_fib(&m->external_addr, 32, sw_if_index, !is_del); })); - - pool_foreach (dm, sm->det_maps, - ({ - snat_add_del_addr_to_fib(&dm->out_addr, dm->out_plen, sw_if_index, !is_del); - })); /* *INDENT-ON* */ return 0; @@ -2076,8 +2074,7 @@ snat_interface_add_del_output_feature (u32 sw_if_index, sw_if_index); - if (sm->deterministic || - (sm->static_mapping_only && !(sm->static_mapping_connection_tracking))) + if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)) return VNET_API_ERROR_UNSUPPORTED; /* *INDENT-OFF* */ @@ -2235,6 +2232,7 @@ fq: pool_get (sm->output_feature_interfaces, i); i->sw_if_index = sw_if_index; i->flags = 0; + nat_validate_counters (sm, sw_if_index); if (is_inside) i->flags |= NAT_INTERFACE_FLAG_IS_INSIDE; else @@ -2515,11 +2513,6 @@ snat_init (vlib_main_t * vm) node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in-slowpath"); sm->ed_out2in_slowpath_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "nat44-det-in2out"); - sm->det_in2out_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "nat44-det-out2in"); - sm->det_out2in_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpinning"); sm->hairpinning_node_index = node->index; node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpin-dst"); @@ -2590,6 +2583,36 @@ snat_init (vlib_main_t * vm) vlib_validate_simple_counter (&sm->user_limit_reached, 0); vlib_zero_simple_counter (&sm->user_limit_reached, 0); +#define _(x) \ + sm->counters.fastpath.in2out.x.name = #x; \ + sm->counters.fastpath.in2out.x.stat_segment_name = \ + "/nat44/in2out/fastpath/" #x; \ + sm->counters.slowpath.in2out.x.name = #x; \ + sm->counters.slowpath.in2out.x.stat_segment_name = \ + "/nat44/in2out/slowpath/" #x; \ + sm->counters.fastpath.out2in.x.name = #x; \ + sm->counters.fastpath.out2in.x.stat_segment_name = \ + "/nat44/out2in/fastpath/" #x; \ + sm->counters.slowpath.out2in.x.name = #x; \ + sm->counters.slowpath.out2in.x.stat_segment_name = \ + "/nat44/out2in/slowpath/" #x; \ + sm->counters.fastpath.in2out_ed.x.name = #x; \ + sm->counters.fastpath.in2out_ed.x.stat_segment_name = \ + "/nat44/ed/in2out/fastpath/" #x; \ + sm->counters.slowpath.in2out_ed.x.name = #x; \ + sm->counters.slowpath.in2out_ed.x.stat_segment_name = \ + "/nat44/ed/in2out/slowpath/" #x; \ + sm->counters.fastpath.out2in_ed.x.name = #x; \ + sm->counters.fastpath.out2in_ed.x.stat_segment_name = \ + "/nat44/ed/out2in/fastpath/" #x; \ + sm->counters.slowpath.out2in_ed.x.name = #x; \ + sm->counters.slowpath.out2in_ed.x.stat_segment_name = \ + "/nat44/ed/out2in/slowpath/" #x; + foreach_nat_counter; +#undef _ + sm->counters.hairpinning.name = "hairpinning"; + sm->counters.hairpinning.stat_segment_name = "/nat44/hairpinning"; + /* Init IPFIX logging */ snat_ipfix_logging_init (vm); @@ -2598,8 +2621,6 @@ snat_init (vlib_main_t * vm) if (error) return error; - nat66_init (vm); - ip4_table_bind_callback_t cbt4 = { .function = snat_ip4_table_bind, }; @@ -2896,7 +2917,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses, { \ portnum = (port_per_thread * \ snat_thread_index) + \ - snat_random_port(1, port_per_thread) + 1024; \ + snat_random_port(0, port_per_thread - 1) + 1024; \ if (a->busy_##n##_port_refcounts[portnum]) \ continue; \ --a->busy_##n##_port_refcounts[portnum]; \ @@ -2933,7 +2954,7 @@ nat_alloc_addr_and_port_default (snat_address_t * addresses, { \ portnum = (port_per_thread * \ snat_thread_index) + \ - snat_random_port(1, port_per_thread) + 1024; \ + snat_random_port(0, port_per_thread - 1) + 1024; \ if (a->busy_##n##_port_refcounts[portnum]) \ continue; \ ++a->busy_##n##_port_refcounts[portnum]; \ @@ -3913,7 +3934,6 @@ static clib_error_t * snat_config (vlib_main_t * vm, unformat_input_t * input) { snat_main_t *sm = &snat_main; - nat66_main_t *nm = &nat66_main; snat_main_per_thread_data_t *tsm; u32 static_mapping_buckets = 1024; @@ -3943,7 +3963,6 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) u32 tcp_transitory_timeout = SNAT_TCP_TRANSITORY_TIMEOUT; u32 tcp_established_timeout = SNAT_TCP_ESTABLISHED_TIMEOUT; - sm->deterministic = 0; sm->out2in_dpo = 0; sm->endpoint_dependent = 0; @@ -3984,8 +4003,6 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) if (unformat (input, "connection tracking")) static_mapping_connection_tracking = 1; } - else if (unformat (input, "deterministic")) - sm->deterministic = 1; else if (unformat (input, "nat64 bib hash buckets %d", &nat64_bib_buckets)) ; @@ -4007,15 +4024,11 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) format_unformat_error, input); } - if (sm->deterministic && sm->endpoint_dependent) - return clib_error_return (0, - "deterministic and endpoint-dependent modes are mutually exclusive"); - - if (static_mapping_only && (sm->deterministic || sm->endpoint_dependent)) + if (static_mapping_only && (sm->endpoint_dependent)) return clib_error_return (0, "static mapping only mode available only for simple nat"); - if (sm->out2in_dpo && (sm->deterministic || sm->endpoint_dependent)) + if (sm->out2in_dpo && (sm->endpoint_dependent)) return clib_error_return (0, "out2in dpo mode available only for simple nat"); if (sm->endpoint_dependent && max_users_per_thread > 0) @@ -4075,10 +4088,6 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) sm->outside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, outside_vrf_id, nat_fib_src_hi); - nm->outside_vrf_id = outside_ip6_vrf_id; - nm->outside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, - outside_ip6_vrf_id, - nat_fib_src_hi); sm->inside_vrf_id = inside_vrf_id; sm->inside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, inside_vrf_id, @@ -4089,79 +4098,67 @@ snat_config (vlib_main_t * vm, unformat_input_t * input) nat64_set_hash (nat64_bib_buckets, nat64_bib_memory_size, nat64_st_buckets, nat64_st_memory_size); - if (sm->deterministic) + if (sm->endpoint_dependent) { - sm->in2out_node_index = snat_det_in2out_node.index; - sm->in2out_output_node_index = ~0; - sm->out2in_node_index = snat_det_out2in_node.index; - sm->icmp_match_in2out_cb = icmp_match_in2out_det; - sm->icmp_match_out2in_cb = icmp_match_out2in_det; + sm->worker_in2out_cb = nat44_ed_get_worker_in2out_cb; + sm->worker_out2in_cb = nat44_ed_get_worker_out2in_cb; + + sm->in2out_node_index = nat44_ed_in2out_node.index; + sm->in2out_output_node_index = nat44_ed_in2out_output_node.index; + sm->out2in_node_index = nat44_ed_out2in_node.index; + + sm->icmp_match_in2out_cb = icmp_match_in2out_ed; + sm->icmp_match_out2in_cb = icmp_match_out2in_ed; + nat_affinity_init (vm); + nat_ha_init (vm, nat_ha_sadd_ed_cb, nat_ha_sdel_ed_cb, + nat_ha_sref_ed_cb); + clib_bihash_init_16_8 (&sm->out2in_ed, "out2in-ed", + clib_max (1, sm->num_workers) * + sm->translation_buckets, + clib_max (1, sm->num_workers) * + sm->translation_memory_size); + clib_bihash_set_kvp_format_fn_16_8 (&sm->out2in_ed, + format_ed_session_kvp); } else { - if (sm->endpoint_dependent) - { - sm->worker_in2out_cb = nat44_ed_get_worker_in2out_cb; - sm->worker_out2in_cb = nat44_ed_get_worker_out2in_cb; - - sm->in2out_node_index = nat44_ed_in2out_node.index; - sm->in2out_output_node_index = nat44_ed_in2out_output_node.index; - sm->out2in_node_index = nat44_ed_out2in_node.index; - - sm->icmp_match_in2out_cb = icmp_match_in2out_ed; - sm->icmp_match_out2in_cb = icmp_match_out2in_ed; - nat_affinity_init (vm); - nat_ha_init (vm, nat_ha_sadd_ed_cb, nat_ha_sdel_ed_cb, - nat_ha_sref_ed_cb); - clib_bihash_init_16_8 (&sm->out2in_ed, "out2in-ed", - clib_max (1, sm->num_workers) * - sm->translation_buckets, - clib_max (1, sm->num_workers) * - sm->translation_memory_size); - clib_bihash_set_kvp_format_fn_16_8 (&sm->out2in_ed, - format_ed_session_kvp); - } - else - { - sm->worker_in2out_cb = snat_get_worker_in2out_cb; - sm->worker_out2in_cb = snat_get_worker_out2in_cb; + sm->worker_in2out_cb = snat_get_worker_in2out_cb; + sm->worker_out2in_cb = snat_get_worker_out2in_cb; - sm->in2out_node_index = snat_in2out_node.index; - sm->in2out_output_node_index = snat_in2out_output_node.index; - sm->out2in_node_index = snat_out2in_node.index; + sm->in2out_node_index = snat_in2out_node.index; + sm->in2out_output_node_index = snat_in2out_output_node.index; + sm->out2in_node_index = snat_out2in_node.index; - sm->icmp_match_in2out_cb = icmp_match_in2out_slow; - sm->icmp_match_out2in_cb = icmp_match_out2in_slow; - nat_ha_init (vm, nat_ha_sadd_cb, nat_ha_sdel_cb, nat_ha_sref_cb); - } - if (!static_mapping_only || - (static_mapping_only && static_mapping_connection_tracking)) - { + sm->icmp_match_in2out_cb = icmp_match_in2out_slow; + sm->icmp_match_out2in_cb = icmp_match_out2in_slow; + nat_ha_init (vm, nat_ha_sadd_cb, nat_ha_sdel_cb, nat_ha_sref_cb); + } + if (!static_mapping_only || + (static_mapping_only && static_mapping_connection_tracking)) + { /* *INDENT-OFF* */ vec_foreach (tsm, sm->per_thread_data) { nat44_db_init (tsm); } /* *INDENT-ON* */ - } - else - { - sm->icmp_match_in2out_cb = icmp_match_in2out_fast; - sm->icmp_match_out2in_cb = icmp_match_out2in_fast; - } - clib_bihash_init_8_8 (&sm->static_mapping_by_local, - "static_mapping_by_local", static_mapping_buckets, - static_mapping_memory_size); - clib_bihash_set_kvp_format_fn_8_8 (&sm->static_mapping_by_local, - format_static_mapping_kvp); - - clib_bihash_init_8_8 (&sm->static_mapping_by_external, - "static_mapping_by_external", - static_mapping_buckets, - static_mapping_memory_size); - clib_bihash_set_kvp_format_fn_8_8 (&sm->static_mapping_by_external, - format_static_mapping_kvp); } + else + { + sm->icmp_match_in2out_cb = icmp_match_in2out_fast; + sm->icmp_match_out2in_cb = icmp_match_out2in_fast; + } + clib_bihash_init_8_8 (&sm->static_mapping_by_local, + "static_mapping_by_local", static_mapping_buckets, + static_mapping_memory_size); + clib_bihash_set_kvp_format_fn_8_8 (&sm->static_mapping_by_local, + format_static_mapping_kvp); + + clib_bihash_init_8_8 (&sm->static_mapping_by_external, + "static_mapping_by_external", + static_mapping_buckets, static_mapping_memory_size); + clib_bihash_set_kvp_format_fn_8_8 (&sm->static_mapping_by_external, + format_static_mapping_kvp); return 0; }