X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fping.c;h=f438ce960606ba9aeb27e6ef7426f4274a2e821b;hb=71612d61930e57e7c8ebf9e5647b15a4b23720b2;hp=68dbe759ebcc4af58b1facbb08e68e341b6933ee;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vnet/ip/ping.c b/src/vnet/ip/ping.c old mode 100644 new mode 100755 index 68dbe759ebc..f438ce96060 --- a/src/vnet/ip/ping.c +++ b/src/vnet/ip/ping.c @@ -13,10 +13,14 @@ * limitations under the License. */ +#include #include #include #include #include +#include + +ping_main_t ping_main; /** * @file @@ -52,8 +56,7 @@ format_icmp_echo_trace (u8 * s, va_list * va) */ static int -signal_ip46_icmp_reply_event (vlib_main_t * vm, - u8 event_type, vlib_buffer_t * b0) +signal_ip46_icmp_reply_event (u8 event_type, vlib_buffer_t * b0) { ping_main_t *pm = &ping_main; u16 net_icmp_id = 0; @@ -83,14 +86,20 @@ signal_ip46_icmp_reply_event (vlib_main_t * vm, return 0; ping_run_t *pr = vec_elt_at_index (pm->ping_runs, p[0]); + vlib_main_t *vm = vlib_mains[pr->cli_thread_index]; if (vlib_buffer_alloc (vm, &bi0_copy, 1) == 1) { - void *dst = vlib_buffer_get_current (vlib_get_buffer (vm, bi0_copy)); + void *dst = vlib_buffer_get_current (vlib_get_buffer (vm, + bi0_copy)); clib_memcpy (dst, vlib_buffer_get_current (b0), b0->current_length); } /* If buffer_alloc failed, bi0_copy == 0 - just signaling an event. */ - - vlib_process_signal_event (vm, pr->cli_process_id, event_type, bi0_copy); + f64 nowts = vlib_time_now (vm); + /* Pass the timestamp to the cli_process thanks to the vnet_buffer unused metadata field */ + clib_memcpy (vnet_buffer + (vlib_get_buffer + (vm, bi0_copy))->unused, &nowts, sizeof (nowts)); + vlib_process_signal_event_mt (vm, pr->cli_process_id, event_type, bi0_copy); return 1; } @@ -115,7 +124,7 @@ ip6_icmp_echo_reply_node_fn (vlib_main_t * vm, bi0 = from[0]; b0 = vlib_get_buffer (vm, bi0); - next0 = signal_ip46_icmp_reply_event (vm, PING_RESPONSE_IP6, b0) ? + next0 = signal_ip46_icmp_reply_event (PING_RESPONSE_IP6, b0) ? ICMP6_ECHO_REPLY_NEXT_DROP : ICMP6_ECHO_REPLY_NEXT_PUNT; if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) @@ -173,7 +182,7 @@ ip4_icmp_echo_reply_node_fn (vlib_main_t * vm, bi0 = from[0]; b0 = vlib_get_buffer (vm, bi0); - next0 = signal_ip46_icmp_reply_event (vm, PING_RESPONSE_IP4, b0) ? + next0 = signal_ip46_icmp_reply_event (PING_RESPONSE_IP4, b0) ? ICMP4_ECHO_REPLY_NEXT_DROP : ICMP4_ECHO_REPLY_NEXT_PUNT; if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) @@ -213,27 +222,6 @@ VLIB_REGISTER_NODE (ip4_icmp_echo_reply_node, static) = char *ip6_lookup_next_nodes[] = IP6_LOOKUP_NEXT_NODES; char *ip4_lookup_next_nodes[] = IP4_LOOKUP_NEXT_NODES; -/* get first interface address */ -static ip6_address_t * -ip6_interface_first_address (ip6_main_t * im, u32 sw_if_index) -{ - ip_lookup_main_t *lm = &im->lookup_main; - ip_interface_address_t *ia = 0; - ip6_address_t *result = 0; - - /* *INDENT-OFF* */ - foreach_ip_interface_address (lm, ia, sw_if_index, - 1 /* honor unnumbered */ , - ({ - ip6_address_t * a = - ip_interface_address_get_address (lm, ia); - result = a; - break; - })); - /* *INDENT-ON* */ - return result; -} - /* Fill in the ICMP ECHO structure, return the safety-checked and possibly shrunk data_len */ static u16 init_icmp46_echo_request (icmp46_echo_request_t * icmp46_echo, @@ -243,15 +231,10 @@ init_icmp46_echo_request (icmp46_echo_request_t * icmp46_echo, icmp46_echo->seq = clib_host_to_net_u16 (seq_host); icmp46_echo->id = clib_host_to_net_u16 (id_host); - for (i = 0; i < sizeof (icmp46_echo->data); i++) - { - icmp46_echo->data[i] = i % 256; - } - - if (data_len > sizeof (icmp46_echo_request_t)) - { - data_len = sizeof (icmp46_echo_request_t); - } + if (data_len > PING_MAXIMUM_DATA_SIZE) + data_len = PING_MAXIMUM_DATA_SIZE; + for (i = 0; i < data_len; i++) + icmp46_echo->data[i] = i % 256; return data_len; } @@ -259,7 +242,7 @@ static send_ip46_ping_result_t send_ip6_ping (vlib_main_t * vm, ip6_main_t * im, u32 table_id, ip6_address_t * pa6, u32 sw_if_index, u16 seq_host, u16 id_host, u16 data_len, - u8 verbose) + u32 burst, u8 verbose) { icmp6_echo_request_header_t *h0; u32 bi0 = 0; @@ -267,11 +250,15 @@ send_ip6_ping (vlib_main_t * vm, ip6_main_t * im, vlib_buffer_t *p0; vlib_frame_t *f; u32 *to_next; + vlib_buffer_free_list_t *fl; if (vlib_buffer_alloc (vm, &bi0, 1) != 1) return SEND_PING_ALLOC_FAIL; p0 = vlib_get_buffer (vm, bi0); + fl = vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX); + vlib_buffer_init_for_free_list (p0, fl); + VLIB_BUFFER_TRACE_TRAJECTORY_INIT (p0); /* * if the user did not provide a source interface, use the any interface @@ -328,6 +315,11 @@ send_ip6_ping (vlib_main_t * vm, ip6_main_t * im, /* Fill in the correct source now */ ip6_address_t *a = ip6_interface_first_address (im, sw_if_index); + if (!a) + { + vlib_buffer_free (vm, &bi0, 1); + return SEND_PING_NO_SRC_ADDRESS; + } h0->ip6.src_address = a[0]; /* Fill in icmp fields */ @@ -355,7 +347,15 @@ send_ip6_ping (vlib_main_t * vm, ip6_main_t * im, f = vlib_get_frame_to_node (vm, ip6_lookup_node.index); to_next = vlib_frame_vector_args (f); to_next[0] = bi0; - f->n_vectors = 1; + + ASSERT (burst <= VLIB_FRAME_SIZE); + f->n_vectors = burst; + while (--burst) + { + vlib_buffer_t *c0 = vlib_buffer_copy (vm, p0); + to_next++; + to_next[0] = vlib_get_buffer_index (vm, c0); + } vlib_put_frame_to_node (vm, ip6_lookup_node.index, f); return SEND_PING_OK; @@ -367,7 +367,7 @@ send_ip4_ping (vlib_main_t * vm, u32 table_id, ip4_address_t * pa4, u32 sw_if_index, - u16 seq_host, u16 id_host, u16 data_len, u8 verbose) + u16 seq_host, u16 id_host, u16 data_len, u32 burst, u8 verbose) { icmp4_echo_request_header_t *h0; u32 bi0 = 0; @@ -376,11 +376,15 @@ send_ip4_ping (vlib_main_t * vm, vlib_frame_t *f; u32 *to_next; u32 if_add_index0; + vlib_buffer_free_list_t *fl; if (vlib_buffer_alloc (vm, &bi0, 1) != 1) return SEND_PING_ALLOC_FAIL; p0 = vlib_get_buffer (vm, bi0); + fl = vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX); + vlib_buffer_init_for_free_list (p0, fl); + VLIB_BUFFER_TRACE_TRAJECTORY_INIT (p0); /* * if the user did not provide a source interface, use the any interface @@ -481,7 +485,15 @@ send_ip4_ping (vlib_main_t * vm, f = vlib_get_frame_to_node (vm, ip4_lookup_node.index); to_next = vlib_frame_vector_args (f); to_next[0] = bi0; - f->n_vectors = 1; + + ASSERT (burst <= VLIB_FRAME_SIZE); + f->n_vectors = burst; + while (--burst) + { + vlib_buffer_t *c0 = vlib_buffer_copy (vm, p0); + to_next++; + to_next[0] = vlib_get_buffer_index (vm, c0); + } vlib_put_frame_to_node (vm, ip4_lookup_node.index, f); return SEND_PING_OK; @@ -493,8 +505,9 @@ print_ip6_icmp_reply (vlib_main_t * vm, u32 bi0) { vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0); icmp6_echo_request_header_t *h0 = vlib_buffer_get_current (b0); - f64 rtt = vlib_time_now (vm) - h0->icmp_echo.time_sent; - + f64 rtt = 0; + clib_memcpy (&rtt, vnet_buffer (b0)->unused, sizeof (rtt)); + rtt -= h0->icmp_echo.time_sent; vlib_cli_output (vm, "%d bytes from %U: icmp_seq=%d ttl=%d time=%.4f ms", clib_host_to_net_u16 (h0->ip6.payload_length), @@ -509,7 +522,9 @@ print_ip4_icmp_reply (vlib_main_t * vm, u32 bi0) { vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0); icmp4_echo_request_header_t *h0 = vlib_buffer_get_current (b0); - f64 rtt = vlib_time_now (vm) - h0->icmp_echo.time_sent; + f64 rtt = 0; + clib_memcpy (&rtt, vnet_buffer (b0)->unused, sizeof (rtt)); + rtt -= h0->icmp_echo.time_sent; u32 rcvd_icmp_len = clib_host_to_net_u16 (h0->ip4.length) - (4 * (0xF & h0->ip4.ip_version_and_header_length)); @@ -535,7 +550,7 @@ static void run_ping_ip46_address (vlib_main_t * vm, u32 table_id, ip4_address_t * pa4, ip6_address_t * pa6, u32 sw_if_index, f64 ping_interval, u32 ping_repeat, u32 data_len, - u32 verbose) + u32 ping_burst, u32 verbose) { int i; ping_main_t *pm = &ping_main; @@ -561,6 +576,7 @@ run_ping_ip46_address (vlib_main_t * vm, u32 table_id, ip4_address_t * pa4, pool_get (pm->ping_runs, pr); ping_run_index = pr - pm->ping_runs; pr->cli_process_id = curr_proc; + pr->cli_thread_index = vlib_get_thread_index (); pr->icmp_id = icmp_id; hash_set (pm->ping_run_by_icmp_id, icmp_id, ping_run_index); for (i = 1; i <= ping_repeat; i++) @@ -573,16 +589,16 @@ run_ping_ip46_address (vlib_main_t * vm, u32 table_id, ip4_address_t * pa4, if (pa6 && (SEND_PING_OK == send_ip6_ping (vm, ping_main.ip6_main, table_id, pa6, sw_if_index, - i, icmp_id, data_len, verbose))) + i, icmp_id, data_len, ping_burst, verbose))) { - n_requests++; + n_requests += ping_burst; } if (pa4 && (SEND_PING_OK == send_ip4_ping (vm, ping_main.ip4_main, table_id, pa4, sw_if_index, - i, icmp_id, data_len, verbose))) + i, icmp_id, data_len, ping_burst, verbose))) { - n_requests++; + n_requests += ping_burst; } while ((i <= ping_repeat) && @@ -601,7 +617,7 @@ run_ping_ip46_address (vlib_main_t * vm, u32 table_id, ip4_address_t * pa4, int i; for (i = 0; i < vec_len (event_data); i++) { - u32 bi0 = event_data[0]; + u32 bi0 = event_data[i]; print_ip6_icmp_reply (vm, bi0); n_replies++; if (0 != bi0) @@ -616,7 +632,7 @@ run_ping_ip46_address (vlib_main_t * vm, u32 table_id, ip4_address_t * pa4, int i; for (i = 0; i < vec_len (event_data); i++) { - u32 bi0 = event_data[0]; + u32 bi0 = event_data[i]; print_ip4_icmp_reply (vm, bi0); n_replies++; if (0 != bi0) @@ -632,6 +648,7 @@ run_ping_ip46_address (vlib_main_t * vm, u32 table_id, ip4_address_t * pa4, i = 1 + ping_repeat; break; } + vec_free (event_data); } } vlib_cli_output (vm, "\n"); @@ -662,6 +679,7 @@ ping_ip_address (vlib_main_t * vm, ip6_address_t a6; clib_error_t *error = 0; u32 ping_repeat = 5; + u32 ping_burst = 1; u8 ping_ip4, ping_ip6; vnet_main_t *vnm = vnet_get_main (); u32 data_len = PING_DEFAULT_DATA_LEN; @@ -759,10 +777,18 @@ ping_ip_address (vlib_main_t * vm, format_unformat_error, input); goto done; } + if (data_len > PING_MAXIMUM_DATA_SIZE) + { + error = + clib_error_return (0, + "%d is bigger than maximum allowed payload size %d", + data_len, PING_MAXIMUM_DATA_SIZE); + goto done; + } } else if (unformat (input, "table-id")) { - if (!unformat (input, "du", &table_id)) + if (!unformat (input, "%u", &table_id)) { error = clib_error_return (0, @@ -793,6 +819,17 @@ ping_ip_address (vlib_main_t * vm, goto done; } } + else if (unformat (input, "burst")) + { + if (!unformat (input, "%u", &ping_burst)) + { + error = + clib_error_return (0, + "expecting burst count but got `%U'", + format_unformat_error, input); + goto done; + } + } else if (unformat (input, "verbose")) { verbose = 1; @@ -805,9 +842,13 @@ ping_ip_address (vlib_main_t * vm, } } + if (ping_burst < 1 || ping_burst > VLIB_FRAME_SIZE) + return clib_error_return (0, "burst size must be between 1 and %u", + VLIB_FRAME_SIZE); + run_ping_ip46_address (vm, table_id, ping_ip4 ? &a4 : NULL, ping_ip6 ? &a6 : NULL, sw_if_index, ping_interval, - ping_repeat, data_len, verbose); + ping_repeat, data_len, ping_burst, verbose); done: return error; } @@ -862,6 +903,7 @@ VLIB_CLI_COMMAND (ping_command, static) = " [ipv4 | ipv6 ] [source ]" " [size ] [interval ] [repeat ] [table-id ]" " [verbose]", + .is_mp_safe = 1, }; /* *INDENT-ON* */