+static clib_error_t *
+nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ snat_main_per_thread_data_t *tsm;
+ snat_main_t *sm = &snat_main;
+ snat_session_t *s;
+
+ if (sm->deterministic || !sm->endpoint_dependent)
+ return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
+
+ // print session configuration values
+ vlib_cli_output (vm, "max translations: %u", sm->max_translations);
+ vlib_cli_output (vm, "max translations per user: %u",
+ sm->max_translations_per_user);
+
+ u32 count = 0;
+
+ u64 now = vlib_time_now (sm->vlib_main);
+ u64 sess_timeout_time;
+
+ u32 udp_sessions = 0;
+ u32 tcp_sessions = 0;
+ u32 icmp_sessions = 0;
+
+ u32 timed_out = 0;
+ u32 transitory = 0;
+ u32 transitory_wait_closed = 0;
+ u32 transitory_closed = 0;
+ u32 established = 0;
+
+ if (sm->num_workers > 1)
+ {
+ /* *INDENT-OFF* */
+ vec_foreach (tsm, sm->per_thread_data)
+ {
+ pool_foreach (s, tsm->sessions,
+ ({
+ sess_timeout_time = s->last_heard +
+ (f64) nat44_session_get_timeout (sm, s);
+ if (now >= sess_timeout_time)
+ timed_out++;
+
+ switch (s->in2out.protocol)
+ {
+ case SNAT_PROTOCOL_ICMP:
+ icmp_sessions++;
+ break;
+ case SNAT_PROTOCOL_TCP:
+ tcp_sessions++;
+ if (s->state)
+ {
+ if (s->tcp_close_timestamp)
+ {
+ if (now >= s->tcp_close_timestamp)
+ {
+ ++transitory_closed;
+ }
+ else
+ {
+ ++transitory_wait_closed;
+ }
+ }
+ transitory++;
+ }
+ else
+ established++;
+ break;
+ case SNAT_PROTOCOL_UDP:
+ default:
+ udp_sessions++;
+ break;
+ }
+ }));
+ count += pool_elts (tsm->sessions);
+ }
+ /* *INDENT-ON* */
+ }
+ else
+ {
+ tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ /* *INDENT-OFF* */
+ pool_foreach (s, tsm->sessions,
+ ({
+ sess_timeout_time = s->last_heard +
+ (f64) nat44_session_get_timeout (sm, s);
+ if (now >= sess_timeout_time)
+ timed_out++;
+
+ switch (s->in2out.protocol)
+ {
+ case SNAT_PROTOCOL_ICMP:
+ icmp_sessions++;
+ break;
+ case SNAT_PROTOCOL_TCP:
+ tcp_sessions++;
+ if (s->state)
+ {
+ if (s->tcp_close_timestamp)
+ {
+ if (now >= s->tcp_close_timestamp)
+ {
+ ++transitory_closed;
+ }
+ else
+ {
+ ++transitory_wait_closed;
+ }
+ }
+ transitory++;
+ }
+ else
+ established++;
+ break;
+ case SNAT_PROTOCOL_UDP:
+ default:
+ udp_sessions++;
+ break;
+ }
+ }));
+ /* *INDENT-ON* */
+ count = pool_elts (tsm->sessions);
+ }
+
+ vlib_cli_output (vm, "total timed out sessions: %u", timed_out);
+ vlib_cli_output (vm, "total sessions: %u", count);
+ vlib_cli_output (vm, "total tcp sessions: %u", tcp_sessions);
+ vlib_cli_output (vm, "total tcp established sessions: %u", established);
+ vlib_cli_output (vm, "total tcp transitory sessions: %u", transitory);
+ vlib_cli_output (vm, "total tcp transitory (WAIT-CLOSED) sessions: %u",
+ transitory_wait_closed);
+ vlib_cli_output (vm, "total tcp transitory (CLOSED) sessions: %u",
+ transitory_closed);
+ vlib_cli_output (vm, "total udp sessions: %u", udp_sessions);
+ vlib_cli_output (vm, "total icmp sessions: %u", icmp_sessions);
+ return 0;
+}
+