diff options
-rw-r--r-- | src/vnet/session/session_cli.c | 269 |
1 files changed, 194 insertions, 75 deletions
diff --git a/src/vnet/session/session_cli.c b/src/vnet/session/session_cli.c index 76ecfeae243..c29a465d056 100644 --- a/src/vnet/session/session_cli.c +++ b/src/vnet/session/session_cli.c @@ -237,6 +237,27 @@ done: return rv; } +static uword +unformat_ip_port (unformat_input_t *input, va_list *args) +{ + ip46_address_t *ip = va_arg (*args, ip46_address_t *); + u16 *port = va_arg (*args, u16 *); + + if (unformat (input, "%U:%d", unformat_ip46_address, ip, IP46_TYPE_ANY, + port)) + ; + else if (unformat (input, "%U", unformat_ip46_address, ip, IP46_TYPE_ANY)) + { + *port = 0; + } + else + { + return 0; + } + + return 1; +} + uword unformat_session (unformat_input_t * input, va_list * args) { @@ -360,30 +381,80 @@ session_cli_show_all_sessions (vlib_main_t * vm, int verbose) } } +typedef enum +{ + SESSION_CLI_FILTER_FORCE_PRINT = 1 << 0, +} session_cli_filter_flags_t; + +typedef enum +{ + SESSION_CLI_FILTER_ENDPT_LOCAL = 1 << 0, + SESSION_CLI_FILTER_ENDPT_REMOTE = 1 << 1, +} session_cli_endpt_flags_t; + +typedef struct session_cli_filter_ +{ + session_cli_filter_flags_t flags; + struct + { + u32 start; + u32 end; + } range; + transport_endpoint_t endpt; + session_cli_endpt_flags_t endpt_flags; + session_state_t *states; + transport_proto_t transport_proto; + u32 thread_index; + u32 verbose; +} session_cli_filter_t; + static int -session_cli_filter_check (session_t * s, session_state_t * states, - transport_proto_t tp) +session_cli_filter_check (session_t *s, session_cli_filter_t *sf) { - if (states) + transport_connection_t *tc; + + if (sf->states) { session_state_t *state; - vec_foreach (state, states) if (s->session_state == *state) + vec_foreach (state, sf->states) + if (s->session_state == *state) goto check_transport; return 0; } check_transport: - if (tp != TRANSPORT_PROTO_INVALID && session_get_transport_proto (s) != tp) + if (sf->transport_proto != TRANSPORT_PROTO_INVALID && + session_get_transport_proto (s) != sf->transport_proto) return 0; - return 1; + if (s->session_state >= SESSION_STATE_TRANSPORT_DELETED) + return 0; + + /* No explicit ip:port match requested */ + if (!sf->endpt_flags) + return 1; + + tc = session_get_transport (s); + if (sf->endpt_flags & SESSION_CLI_FILTER_ENDPT_LOCAL) + { + if (!ip46_address_cmp (&sf->endpt.ip, &tc->lcl_ip) && + (sf->endpt.port == 0 || + sf->endpt.port == clib_net_to_host_u16 (tc->lcl_port))) + return 1; + } + if (sf->endpt_flags & SESSION_CLI_FILTER_ENDPT_REMOTE) + { + if (!ip46_address_cmp (&sf->endpt.ip, &tc->rmt_ip) && + (sf->endpt.port == 0 || + sf->endpt.port == clib_net_to_host_u16 (tc->rmt_port))) + return 1; + } + return 0; } static void -session_cli_show_session_filter (vlib_main_t * vm, u32 thread_index, - u32 start, u32 end, session_state_t * states, - transport_proto_t tp, int verbose) +session_cli_show_session_filter (vlib_main_t *vm, session_cli_filter_t *sf) { u8 output_suppressed = 0; session_worker_t *wrk; @@ -391,54 +462,62 @@ session_cli_show_session_filter (vlib_main_t * vm, u32 thread_index, u32 count = 0, max_index; int i; - wrk = session_main_get_worker_if_valid (thread_index); + if (sf->range.end < sf->range.start) + { + vlib_cli_output (vm, "invalid range start: %u end: %u", sf->range.start, + sf->range.end); + return; + } + + wrk = session_main_get_worker_if_valid (sf->thread_index); if (!wrk) { - vlib_cli_output (vm, "invalid thread index %u", thread_index); + vlib_cli_output (vm, "invalid thread index %u", sf->thread_index); return; } pool = wrk->sessions; - if (tp == TRANSPORT_PROTO_INVALID && states == 0 && !verbose - && (start == 0 && end == ~0)) + if (sf->transport_proto == TRANSPORT_PROTO_INVALID && sf->states == 0 && + !sf->verbose && (sf->range.start == 0 && sf->range.end == ~0)) { - vlib_cli_output (vm, "Thread %d: %u sessions", thread_index, + vlib_cli_output (vm, "Thread %d: %u sessions", sf->thread_index, pool_elts (pool)); return; } max_index = pool_len (pool) ? pool_len (pool) - 1 : 0; - for (i = start; i <= clib_min (end, max_index); i++) + for (i = sf->range.start; i <= clib_min (sf->range.end, max_index); i++) { if (pool_is_free_index (pool, i)) continue; s = pool_elt_at_index (pool, i); - if (session_cli_filter_check (s, states, tp)) + if (!session_cli_filter_check (s, sf)) + continue; + + count += 1; + if (sf->verbose) { - count += 1; - if (verbose) - { - if (count > 50 || (verbose > 1 && count > 10)) - { - output_suppressed = 1; - continue; - } - if (s->session_state < SESSION_STATE_TRANSPORT_DELETED) - vlib_cli_output (vm, "%U", format_session, s, verbose); - } + if (!(sf->flags & SESSION_CLI_FILTER_FORCE_PRINT) && + (count > 50 || (sf->verbose > 1 && count > 10))) + { + output_suppressed = 1; + continue; + } + vlib_cli_output (vm, "%U", format_session, s, sf->verbose); } } if (!output_suppressed) vlib_cli_output (vm, "Thread %d: %u sessions matched filter", - thread_index, count); + sf->thread_index, count); else - vlib_cli_output (vm, "Thread %d: %u sessions matched filter. Not all" - " shown. Use finer grained filter.", thread_index, - count); + vlib_cli_output (vm, + "Thread %d: %u sessions matched filter. Not all" + " shown. Use finer grained filter.", + sf->thread_index, count); } void @@ -506,9 +585,9 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { u8 one_session = 0, do_listeners = 0, sst, do_elog = 0, do_filter = 0; - u32 track_index, thread_index = 0, start = 0, end = ~0, session_index; + u32 track_index, thread_index = 0, session_index; transport_proto_t transport_proto = TRANSPORT_PROTO_INVALID; - session_state_t state = SESSION_N_STATES, *states = 0; + session_state_t state = SESSION_N_STATES; session_main_t *smm = &session_main; clib_error_t *error = 0; app_worker_t *app_wrk; @@ -517,18 +596,51 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input, u8 do_events = 0; int verbose = 0; session_t *s; + session_cli_filter_t sf = { + .transport_proto = TRANSPORT_PROTO_INVALID, + .range = { 0, ~0 }, + }; session_cli_return_if_not_enabled (); while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - if (unformat (input, "verbose %d", &verbose)) + /* + * helpers + */ + if (unformat (input, "protos")) + { + vlib_cli_output (vm, "%U", format_transport_protos); + goto done; + } + else if (unformat (input, "rt-backend")) + { + vlib_cli_output (vm, "%U", format_rt_backend, smm->rt_engine_type); + goto done; + } + else if (unformat (input, "states")) + { + session_cli_print_session_states (vm); + goto done; + } + else if (unformat (input, "verbose %d", &verbose)) ; else if (unformat (input, "verbose")) verbose = 1; + /* + * listeners + */ else if (unformat (input, "listeners %U", unformat_transport_proto, &transport_proto)) do_listeners = 1; + /* + * session events + */ + else if (unformat (input, "events")) + do_events = 1; + /* + * single session filter + */ else if (unformat (input, "%U", unformat_session, &s)) { one_session = 1; @@ -544,17 +656,9 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input, } one_session = 1; } - else if (unformat (input, "thread %u", &thread_index)) - { - do_filter = 1; - } - else if (unformat (input, "state %U", unformat_session_state, &state)) - { - vec_add1 (states, state); - do_filter = 1; - } - else if (unformat (input, "proto %U index %u", unformat_transport_proto, - &transport_proto, &transport_index)) + else if (unformat (input, "thread %u proto %U index %u", &thread_index, + unformat_transport_proto, &transport_proto, + &transport_index)) { transport_connection_t *tc; tc = transport_get_connection (transport_proto, transport_index, @@ -575,35 +679,54 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input, } one_session = 1; } + else if (unformat (input, "elog")) + do_elog = 1; + /* + * session filter + */ + else if (unformat (input, "thread %u", &sf.thread_index)) + { + do_filter = 1; + } + else if (unformat (input, "state %U", unformat_session_state, &state)) + { + vec_add1 (sf.states, state); + do_filter = 1; + } else if (unformat (input, "proto %U", unformat_transport_proto, - &transport_proto)) + &sf.transport_proto)) do_filter = 1; - else if (unformat (input, "range %u %u", &start, &end)) + else if (unformat (input, "range %u %u", &sf.range.start, &sf.range.end)) do_filter = 1; - else if (unformat (input, "range %u", &start)) + else if (unformat (input, "range %u", &sf.range.start)) { - end = start + 50; + sf.range.end = sf.range.start + 50; do_filter = 1; } - else if (unformat (input, "elog")) - do_elog = 1; - else if (unformat (input, "protos")) + else if (unformat (input, "lcl %U", unformat_ip_port, &sf.endpt.ip, + &sf.endpt.port)) { - vlib_cli_output (vm, "%U", format_transport_protos); - goto done; + sf.endpt_flags |= SESSION_CLI_FILTER_ENDPT_LOCAL; + do_filter = 1; } - else if (unformat (input, "rt-backend")) + else if (unformat (input, "rmt %U", unformat_ip_port, &sf.endpt.ip, + &sf.endpt.port)) { - vlib_cli_output (vm, "%U", format_rt_backend, smm->rt_engine_type); - goto done; + sf.endpt_flags |= SESSION_CLI_FILTER_ENDPT_REMOTE; + do_filter = 1; } - else if (unformat (input, "states")) + else if (unformat (input, "ep %U", unformat_ip_port, &sf.endpt.ip, + &sf.endpt.port)) { - session_cli_print_session_states (vm); - goto done; + sf.endpt_flags |= + SESSION_CLI_FILTER_ENDPT_REMOTE | SESSION_CLI_FILTER_ENDPT_LOCAL; + do_filter = 1; + } + else if (unformat (input, "force-print")) + { + sf.flags |= SESSION_CLI_FILTER_FORCE_PRINT; + do_filter = 1; } - else if (unformat (input, "events")) - do_events = 1; else { error = clib_error_return (0, "unknown input `%U'", @@ -660,30 +783,26 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input, if (do_filter) { - if (end < start) - { - error = clib_error_return (0, "invalid range start: %u end: %u", - start, end); - goto done; - } - session_cli_show_session_filter (vm, thread_index, start, end, states, - transport_proto, verbose); + sf.verbose = verbose; + session_cli_show_session_filter (vm, &sf); goto done; } session_cli_show_all_sessions (vm, verbose); done: - vec_free (states); + vec_free (sf.states); return error; } VLIB_CLI_COMMAND (vlib_cli_show_session_command) = { .path = "show session", - .short_help = "show session [verbose [n]] [listeners <proto>] " - "[<session-id> [elog]] [thread <n> [index <n>] " - "[proto <proto>] [state <state>] [range <min> [<max>]] " - "[protos] [states] [rt-backend]", + .short_help = + "show session [protos][states][rt-backend][verbose [n]] " + "[events][listeners <proto>] " + "[<session-id>][thread <n> [[proto <p>] index <n>]][elog] " + "[thread <n>][proto <proto>][state <state>][range <min> [<max>]] " + "[lcl|rmt|ep <ip>[:<port>]][force-print]", .function = show_session_command_fn, }; |