X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fplugins%2Fnat%2Fnat64.c;h=717cf6a630a1c58a4fa06959b00a06d1cbecee84;hb=de118da58e80aec43f4b816a1ea957634a8bc07c;hp=405fc84c7b81d2383db9af208aa8940d6772c826;hpb=f126e746fc01c75bc99329d10ce9127b26b23814;p=vpp.git diff --git a/src/plugins/nat/nat64.c b/src/plugins/nat/nat64.c index 405fc84c7b8..717cf6a630a 100644 --- a/src/plugins/nat/nat64.c +++ b/src/plugins/nat/nat64.c @@ -133,12 +133,12 @@ nat64_get_worker_out2in (vlib_buffer_t * b, ip4_header_t * ip) u16 port; u32 proto; - proto = ip_proto_to_snat_proto (ip->protocol); + proto = ip_proto_to_nat_proto (ip->protocol); udp = ip4_next_header (ip); port = udp->dst_port; /* unknown protocol */ - if (PREDICT_FALSE (proto == ~0)) + if (PREDICT_FALSE (proto == NAT_PROTOCOL_OTHER)) { nat64_db_t *db; ip46_address_t daddr; @@ -170,17 +170,17 @@ nat64_get_worker_out2in (vlib_buffer_t * b, ip4_header_t * ip) { /* if error message, then it's not fragmented and we can access it */ ip4_header_t *inner_ip = (ip4_header_t *) (echo + 1); - proto = ip_proto_to_snat_proto (inner_ip->protocol); + proto = ip_proto_to_nat_proto (inner_ip->protocol); void *l4_header = ip4_next_header (inner_ip); switch (proto) { - case SNAT_PROTOCOL_ICMP: + case NAT_PROTOCOL_ICMP: icmp = (icmp46_header_t *) l4_header; echo = (icmp_echo_header_t *) (icmp + 1); port = echo->identifier; break; - case SNAT_PROTOCOL_UDP: - case SNAT_PROTOCOL_TCP: + case NAT_PROTOCOL_UDP: + case NAT_PROTOCOL_TCP: port = ((tcp_udp_header_t *) l4_header)->src_port; break; default: @@ -248,6 +248,13 @@ nat64_init (vlib_main_t * vm) vlib_validate_simple_counter (&nm->total_sessions, 0); vlib_zero_simple_counter (&nm->total_sessions, 0); +#define _(x) \ + nm->counters.in2out.x.name = #x; \ + nm->counters.in2out.x.stat_segment_name = "/nat64/in2out/" #x; \ + nm->counters.out2in.x.name = #x; \ + nm->counters.out2in.x.stat_segment_name = "/nat64/out2in/" #x; + foreach_nat_counter; +#undef _ return 0; } @@ -256,8 +263,8 @@ static void nat64_free_out_addr_and_port (struct nat64_db_s *db, u8 protocol); void -nat64_set_hash (u32 bib_buckets, u32 bib_memory_size, u32 st_buckets, - u32 st_memory_size) +nat64_set_hash (u32 bib_buckets, uword bib_memory_size, u32 st_buckets, + uword st_memory_size) { nat64_main_t *nm = &nat64_main; nat64_db_t *db; @@ -311,10 +318,10 @@ nat64_add_del_pool_addr (u32 thread_index, fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id, nat_fib_src_hi); #define _(N, id, n, s) \ - clib_bitmap_alloc (a->busy_##n##_port_bitmap, 65535); \ + clib_memset (a->busy_##n##_port_refcounts, 0, sizeof(a->busy_##n##_port_refcounts)); \ a->busy_##n##_ports = 0; \ vec_validate_init_empty (a->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0); - foreach_snat_protocol + foreach_nat_protocol #undef _ } else @@ -334,10 +341,6 @@ nat64_add_del_pool_addr (u32 thread_index, vlib_set_simple_counter (&nm->total_sessions, db - nm->db, 0, db->st.st_entries_num); } -#define _(N, id, n, s) \ - clib_bitmap_free (a->busy_##n##_port_bitmap); - foreach_snat_protocol -#undef _ /* *INDENT-ON* */ vec_del1 (nm->addr_pool, i); } @@ -414,9 +417,22 @@ nat64_add_interface_address (u32 sw_if_index, int is_add) return 0; } +static void +nat64_validate_counters (nat64_main_t * nm, u32 sw_if_index) +{ +#define _(x) \ + vlib_validate_simple_counter (&nm->counters.in2out.x, sw_if_index); \ + vlib_zero_simple_counter (&nm->counters.in2out.x, sw_if_index); \ + vlib_validate_simple_counter (&nm->counters.out2in.x, sw_if_index); \ + vlib_zero_simple_counter (&nm->counters.out2in.x, sw_if_index); + foreach_nat_counter; +#undef _ +} + int nat64_add_del_interface (u32 sw_if_index, u8 is_inside, u8 is_add) { + vlib_main_t *vm = vlib_get_main (); nat64_main_t *nm = &nat64_main; snat_interface_t *interface = 0, *i; snat_address_t *ap; @@ -442,6 +458,7 @@ nat64_add_del_interface (u32 sw_if_index, u8 is_inside, u8 is_add) pool_get (nm->interfaces, interface); interface->sw_if_index = sw_if_index; interface->flags = 0; + nat64_validate_counters (nm, sw_if_index); set_flags: if (is_inside) interface->flags |= NAT_INTERFACE_FLAG_IS_INSIDE; @@ -449,7 +466,7 @@ nat64_add_del_interface (u32 sw_if_index, u8 is_inside, u8 is_add) interface->flags |= NAT_INTERFACE_FLAG_IS_OUTSIDE; nm->total_enabled_count++; - vlib_process_signal_event (nm->sm->vlib_main, + vlib_process_signal_event (vm, nm->nat64_expire_walk_node_index, NAT64_CLEANER_RESCHEDULE, 0); @@ -527,30 +544,22 @@ nat64_interfaces_walk (nat64_interface_walk_fn_t fn, void *ctx) } int -nat64_alloc_out_addr_and_port (u32 fib_index, snat_protocol_t proto, +nat64_alloc_out_addr_and_port (u32 fib_index, nat_protocol_t proto, ip4_address_t * addr, u16 * port, u32 thread_index) { nat64_main_t *nm = &nat64_main; snat_main_t *sm = nm->sm; - snat_session_key_t k; u32 worker_index = 0; int rv; - k.protocol = proto; - if (sm->num_workers > 1) worker_index = thread_index - sm->first_worker_index; rv = - sm->alloc_addr_and_port (nm->addr_pool, fib_index, thread_index, &k, - sm->port_per_thread, worker_index); - - if (!rv) - { - *port = k.port; - addr->as_u32 = k.addr.as_u32; - } + sm->alloc_addr_and_port (nm->addr_pool, fib_index, thread_index, + proto, addr, port, sm->port_per_thread, + worker_index); return rv; } @@ -563,7 +572,7 @@ nat64_free_out_addr_and_port (struct nat64_db_s *db, ip4_address_t * addr, int i; snat_address_t *a; u32 thread_index = db - nm->db; - snat_protocol_t proto = ip_proto_to_snat_proto (protocol); + nat_protocol_t proto = ip_proto_to_nat_proto (protocol); u16 port_host_byte_order = clib_net_to_host_u16 (port); for (i = 0; i < vec_len (nm->addr_pool); i++) @@ -574,14 +583,13 @@ nat64_free_out_addr_and_port (struct nat64_db_s *db, ip4_address_t * addr, switch (proto) { #define _(N, j, n, s) \ - case SNAT_PROTOCOL_##N: \ - ASSERT (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \ - port_host_byte_order) == 1); \ - clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, port_host_byte_order, 0); \ + case NAT_PROTOCOL_##N: \ + ASSERT (a->busy_##n##_port_refcounts[port_host_byte_order] >= 1); \ + --a->busy_##n##_port_refcounts[port_host_byte_order]; \ a->busy_##n##_ports--; \ a->busy_##n##_ports_per_thread[thread_index]--; \ break; - foreach_snat_protocol + foreach_nat_protocol #undef _ default: nat_elog_notice ("unknown protocol"); @@ -667,7 +675,7 @@ nat64_add_del_static_bib_entry (ip6_address_t * in_addr, nat64_db_bib_entry_t *bibe; u32 fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id, nat_fib_src_hi); - snat_protocol_t p = ip_proto_to_snat_proto (proto); + nat_protocol_t p = ip_proto_to_nat_proto (proto); ip46_address_t addr; int i; snat_address_t *a; @@ -711,19 +719,17 @@ nat64_add_del_static_bib_entry (ip6_address_t * in_addr, switch (p) { #define _(N, j, n, s) \ - case SNAT_PROTOCOL_##N: \ - if (clib_bitmap_get_no_check (a->busy_##n##_port_bitmap, \ - out_port)) \ + case NAT_PROTOCOL_##N: \ + if (a->busy_##n##_port_refcounts[out_port]) \ return VNET_API_ERROR_INVALID_VALUE; \ - clib_bitmap_set_no_check (a->busy_##n##_port_bitmap, \ - out_port, 1); \ + ++a->busy_##n##_port_refcounts[out_port]; \ if (out_port > 1024) \ { \ a->busy_##n##_ports++; \ a->busy_##n##_ports_per_thread[thread_index]++; \ } \ break; - foreach_snat_protocol + foreach_nat_protocol #undef _ default: clib_memset (&addr, 0, sizeof (addr)); @@ -876,12 +882,12 @@ nat64_session_reset_timeout (nat64_db_st_entry_t * ste, vlib_main_t * vm) nat64_main_t *nm = &nat64_main; u32 now = (u32) vlib_time_now (vm); - switch (ip_proto_to_snat_proto (ste->proto)) + switch (ip_proto_to_nat_proto (ste->proto)) { - case SNAT_PROTOCOL_ICMP: + case NAT_PROTOCOL_ICMP: ste->expire = now + nm->icmp_timeout; return; - case SNAT_PROTOCOL_TCP: + case NAT_PROTOCOL_TCP: { switch (ste->tcp_state) { @@ -900,7 +906,7 @@ nat64_session_reset_timeout (nat64_db_st_entry_t * ste, vlib_main_t * vm) return; } } - case SNAT_PROTOCOL_UDP: + case NAT_PROTOCOL_UDP: ste->expire = now + nm->udp_timeout; return; default: