blob: 9f3d217cf61fe17e71530a330d0153deb9596c4a [file] [log] [blame]
Dave Barach68b0fb02017-02-28 15:15:56 -05001/*
2 * Copyright (c) 2017 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include <vnet/session/application.h>
16#include <vnet/session/session.h>
17
Florin Coras93992a92017-05-24 18:03:56 -070018u8 *
19format_stream_session_fifos (u8 * s, va_list * args)
20{
21 stream_session_t *ss = va_arg (*args, stream_session_t *);
Florin Coras6534b7a2017-07-18 05:38:03 -040022 int verbose = va_arg (*args, int);
23 session_fifo_event_t _e, *e = &_e;
24 u8 found;
25
Florin Coras93992a92017-05-24 18:03:56 -070026 s = format (s, " Rx fifo: %U", format_svm_fifo, ss->server_rx_fifo, 1);
Florin Coras6534b7a2017-07-18 05:38:03 -040027 if (verbose > 2 && ss->server_rx_fifo->has_event)
28 {
29 found = session_node_lookup_fifo_event (ss->server_rx_fifo, e);
30 s = format (s, " session node event: %s\n",
31 found ? "found" : "not found");
32 }
Florin Coras93992a92017-05-24 18:03:56 -070033 s = format (s, " Tx fifo: %U", format_svm_fifo, ss->server_tx_fifo, 1);
Florin Coras6534b7a2017-07-18 05:38:03 -040034 if (verbose > 2 && ss->server_tx_fifo->has_event)
35 {
36 found = session_node_lookup_fifo_event (ss->server_tx_fifo, e);
37 s = format (s, " session node event: %s\n",
38 found ? "found" : "not found");
39 }
Florin Coras93992a92017-05-24 18:03:56 -070040 return s;
41}
42
Dave Barach68b0fb02017-02-28 15:15:56 -050043/**
44 * Format stream session as per the following format
45 *
46 * verbose:
47 * "Connection", "Rx fifo", "Tx fifo", "Session Index"
48 * non-verbose:
49 * "Connection"
50 */
51u8 *
52format_stream_session (u8 * s, va_list * args)
53{
54 stream_session_t *ss = va_arg (*args, stream_session_t *);
55 int verbose = va_arg (*args, int);
56 transport_proto_vft_t *tp_vft;
57 u8 *str = 0;
Dave Barach68b0fb02017-02-28 15:15:56 -050058 tp_vft = session_get_transport_vft (ss->session_type);
59
Florin Coras68810622017-07-24 17:40:28 -070060 if (verbose == 1 && ss->session_state >= SESSION_STATE_ACCEPTING)
Florin Corasbb292f42017-05-19 09:49:19 -070061 str = format (0, "%-10u%-10u%-10lld",
62 svm_fifo_max_dequeue (ss->server_rx_fifo),
63 svm_fifo_max_enqueue (ss->server_tx_fifo),
64 stream_session_get_index (ss));
Dave Barach68b0fb02017-02-28 15:15:56 -050065
Dave Barach2c25a622017-06-26 11:35:07 -040066 if (ss->session_state == SESSION_STATE_READY
67 || ss->session_state == SESSION_STATE_ACCEPTING)
Dave Barach68b0fb02017-02-28 15:15:56 -050068 {
Florin Corasbb292f42017-05-19 09:49:19 -070069 s = format (s, "%U", tp_vft->format_connection, ss->connection_index,
70 ss->thread_index, verbose);
71 if (verbose == 1)
72 s = format (s, "%v", str);
Florin Coras93992a92017-05-24 18:03:56 -070073 if (verbose > 1)
Florin Coras6534b7a2017-07-18 05:38:03 -040074 s = format (s, "%U", format_stream_session_fifos, ss, verbose);
Dave Barach68b0fb02017-02-28 15:15:56 -050075 }
76 else if (ss->session_state == SESSION_STATE_LISTENING)
77 {
78 s = format (s, "%-40U%v", tp_vft->format_listener, ss->connection_index,
79 str);
80 }
Florin Corasbb292f42017-05-19 09:49:19 -070081 else if (ss->session_state == SESSION_STATE_CONNECTING)
Dave Barach68b0fb02017-02-28 15:15:56 -050082 {
Florin Corasbb292f42017-05-19 09:49:19 -070083 s = format (s, "%-40U%v", tp_vft->format_half_open,
84 ss->connection_index, str);
Dave Barach68b0fb02017-02-28 15:15:56 -050085 }
86 else if (ss->session_state == SESSION_STATE_CLOSED)
87 {
Dave Barach2c25a622017-06-26 11:35:07 -040088 s =
89 format (s, "[CL] %U", tp_vft->format_connection, ss->connection_index,
90 ss->thread_index, verbose);
Florin Coras93992a92017-05-24 18:03:56 -070091 if (verbose == 1)
92 s = format (s, "%v", str);
93 if (verbose > 1)
Florin Coras6534b7a2017-07-18 05:38:03 -040094 s = format (s, "%U", format_stream_session_fifos, ss, verbose);
Dave Barach68b0fb02017-02-28 15:15:56 -050095 }
96 else
97 {
Florin Corase04c2992017-03-01 08:17:34 -080098 clib_warning ("Session in state: %d!", ss->session_state);
Dave Barach68b0fb02017-02-28 15:15:56 -050099 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500100 vec_free (str);
101
102 return s;
103}
104
Florin Coras3eb50622017-07-13 01:24:57 -0400105uword
106unformat_stream_session_id (unformat_input_t * input, va_list * args)
107{
108 u8 *proto = va_arg (*args, u8 *);
109 ip46_address_t *lcl = va_arg (*args, ip46_address_t *);
110 ip46_address_t *rmt = va_arg (*args, ip46_address_t *);
111 u16 *lcl_port = va_arg (*args, u16 *);
112 u16 *rmt_port = va_arg (*args, u16 *);
113 u8 *is_ip4 = va_arg (*args, u8 *);
114 u8 tuple_is_set = 0;
115
116 memset (lcl, 0, sizeof (*lcl));
117 memset (rmt, 0, sizeof (*rmt));
118
119 if (unformat (input, "tcp"))
120 {
121 *proto = TRANSPORT_PROTO_TCP;
122 }
123 if (unformat (input, "udp"))
124 {
125 *proto = TRANSPORT_PROTO_UDP;
126 }
127 else if (unformat (input, "%U:%d->%U:%d", unformat_ip4_address, &lcl->ip4,
128 lcl_port, unformat_ip4_address, &rmt->ip4, rmt_port))
129 {
130 *is_ip4 = 1;
131 tuple_is_set = 1;
132 }
133 else if (unformat (input, "%U:%d->%U:%d", unformat_ip6_address, &lcl->ip6,
134 lcl_port, unformat_ip6_address, &rmt->ip6, rmt_port))
135 {
136 *is_ip4 = 0;
137 tuple_is_set = 1;
138 }
139 else
140 return 0;
141
142 if (tuple_is_set)
143 return 1;
144
145 return 0;
146}
147
148uword
149unformat_stream_session (unformat_input_t * input, va_list * args)
150{
151 stream_session_t **result = va_arg (*args, stream_session_t **);
152 stream_session_t *s;
153 u8 proto = ~0;
154 ip46_address_t lcl, rmt;
155 u32 lcl_port = 0, rmt_port = 0;
156 u8 is_ip4 = 0, s_type = ~0, id_is_set = 0;
157
158 if (unformat (input, "%U", unformat_stream_session_id, &proto, &lcl, &rmt,
159 &lcl_port, &rmt_port, &is_ip4))
160 {
161 id_is_set = 1;
162 }
163 else
164 return 0;
165
166 if (!id_is_set)
167 {
168 return 0;
169 }
170
171 s_type = session_type_from_proto_and_ip (proto, is_ip4);
172 if (is_ip4)
173 s = stream_session_lookup4 (&lcl.ip4, &rmt.ip4,
174 clib_host_to_net_u16 (lcl_port),
175 clib_host_to_net_u16 (rmt_port), s_type);
176 else
177 s = stream_session_lookup6 (&lcl.ip6, &rmt.ip6,
178 clib_host_to_net_u16 (lcl_port),
179 clib_host_to_net_u16 (rmt_port), s_type);
180 if (s)
181 {
182 *result = s;
183 return 1;
184 }
185 return 0;
186}
187
188uword
189unformat_transport_connection (unformat_input_t * input, va_list * args)
190{
191 transport_connection_t **result = va_arg (*args, transport_connection_t **);
192 u32 suggested_proto = va_arg (*args, u32);
193 transport_connection_t *tc;
194 u8 proto = ~0;
195 ip46_address_t lcl, rmt;
196 u32 lcl_port = 0, rmt_port = 0;
197 u8 is_ip4 = 0, s_type = ~0, id_is_set = 0;
198
199 if (unformat (input, "%U", unformat_stream_session_id, &proto, &lcl, &rmt,
200 &lcl_port, &rmt_port, &is_ip4))
201 {
202 id_is_set = 1;
203 }
204 else
205 return 0;
206
207 if (!id_is_set)
208 {
209 return 0;
210 }
211
212 proto = (proto == (u8) ~ 0) ? suggested_proto : proto;
213 if (proto == (u8) ~ 0)
214 return 0;
215 s_type = session_type_from_proto_and_ip (proto, is_ip4);
216 if (is_ip4)
217 tc = stream_session_lookup_transport4 (&lcl.ip4, &rmt.ip4,
218 clib_host_to_net_u16 (lcl_port),
219 clib_host_to_net_u16 (rmt_port),
220 s_type);
221 else
222 tc = stream_session_lookup_transport6 (&lcl.ip6, &rmt.ip6,
223 clib_host_to_net_u16 (lcl_port),
224 clib_host_to_net_u16 (rmt_port),
225 s_type);
226
227 if (tc)
228 {
229 *result = tc;
230 return 1;
231 }
232 return 0;
233}
234
Dave Barach68b0fb02017-02-28 15:15:56 -0500235static clib_error_t *
236show_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
237 vlib_cli_command_t * cmd)
238{
239 session_manager_main_t *smm = &session_manager_main;
240 int verbose = 0, i;
241 stream_session_t *pool;
242 stream_session_t *s;
Florin Coras3eb50622017-07-13 01:24:57 -0400243 u8 *str = 0, one_session = 0;
Dave Barach68b0fb02017-02-28 15:15:56 -0500244
Florin Corase04c2992017-03-01 08:17:34 -0800245 if (!smm->is_enabled)
246 {
flyingeagle23e2125062017-04-20 20:01:14 +0800247 return clib_error_return (0, "session layer is not enabled");
Florin Corase04c2992017-03-01 08:17:34 -0800248 }
249
Dave Barach68b0fb02017-02-28 15:15:56 -0500250 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
251 {
Florin Corasbb292f42017-05-19 09:49:19 -0700252 if (unformat (input, "verbose %d", &verbose))
253 ;
254 else if (unformat (input, "verbose"))
Dave Barach68b0fb02017-02-28 15:15:56 -0500255 verbose = 1;
Florin Coras3eb50622017-07-13 01:24:57 -0400256 else if (unformat (input, "%U", unformat_stream_session, &s))
Dave Barach2c25a622017-06-26 11:35:07 -0400257 {
258 one_session = 1;
Dave Barach2c25a622017-06-26 11:35:07 -0400259 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500260 else
Florin Coras3eb50622017-07-13 01:24:57 -0400261 return clib_error_return (0, "unknown input `%U'",
262 format_unformat_error, input);
Dave Barach68b0fb02017-02-28 15:15:56 -0500263 }
264
Dave Barach2c25a622017-06-26 11:35:07 -0400265 if (one_session)
266 {
Florin Coras6534b7a2017-07-18 05:38:03 -0400267 vlib_cli_output (vm, "%U", format_stream_session, s, 3);
Dave Barach2c25a622017-06-26 11:35:07 -0400268 return 0;
269 }
270
Dave Barach68b0fb02017-02-28 15:15:56 -0500271 for (i = 0; i < vec_len (smm->sessions); i++)
272 {
273 u32 once_per_pool;
274 pool = smm->sessions[i];
275
276 once_per_pool = 1;
277
278 if (pool_elts (pool))
279 {
280
281 vlib_cli_output (vm, "Thread %d: %d active sessions",
282 i, pool_elts (pool));
283 if (verbose)
284 {
Florin Corasbb292f42017-05-19 09:49:19 -0700285 if (once_per_pool && verbose == 1)
Dave Barach68b0fb02017-02-28 15:15:56 -0500286 {
Florin Corasbb292f42017-05-19 09:49:19 -0700287 str =
288 format (str, "%-50s%-15s%-10s%-10s%-10s", "Connection",
289 "State", "Rx-f", "Tx-f", "S-idx");
Dave Barach68b0fb02017-02-28 15:15:56 -0500290 vlib_cli_output (vm, "%v", str);
291 vec_reset_length (str);
292 once_per_pool = 0;
293 }
294
295 /* *INDENT-OFF* */
296 pool_foreach (s, pool,
297 ({
Florin Corasbb292f42017-05-19 09:49:19 -0700298 vec_reset_length (str);
299 str = format (str, "%U", format_stream_session, s, verbose);
Florin Corasbb292f42017-05-19 09:49:19 -0700300 vlib_cli_output (vm, "%v", str);
Dave Barach68b0fb02017-02-28 15:15:56 -0500301 }));
302 /* *INDENT-ON* */
303 }
304 }
305 else
306 vlib_cli_output (vm, "Thread %d: no active sessions", i);
Dave Barach2c25a622017-06-26 11:35:07 -0400307 vec_reset_length (str);
Dave Barach68b0fb02017-02-28 15:15:56 -0500308 }
309 vec_free (str);
310
311 return 0;
312}
313
Florin Corase04c2992017-03-01 08:17:34 -0800314/* *INDENT-OFF* */
Florin Coras66b11312017-07-31 17:18:03 -0700315VLIB_CLI_COMMAND (vlib_cli_show_session_command) =
Dave Barach68b0fb02017-02-28 15:15:56 -0500316{
Florin Corase04c2992017-03-01 08:17:34 -0800317 .path = "show session",
318 .short_help = "show session [verbose]",
319 .function = show_session_command_fn,
320};
321/* *INDENT-ON* */
Dave Barach68b0fb02017-02-28 15:15:56 -0500322
Dave Barach2c25a622017-06-26 11:35:07 -0400323static int
324clear_session (stream_session_t * s)
325{
326 application_t *server = application_get (s->app_index);
327 server->cb_fns.session_disconnect_callback (s);
328 return 0;
329}
330
Dave Barach68b0fb02017-02-28 15:15:56 -0500331static clib_error_t *
332clear_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
333 vlib_cli_command_t * cmd)
334{
335 session_manager_main_t *smm = &session_manager_main;
Dave Barach2c25a622017-06-26 11:35:07 -0400336 u32 thread_index = 0, clear_all = 0;
Dave Barach68b0fb02017-02-28 15:15:56 -0500337 u32 session_index = ~0;
Dave Barach2c25a622017-06-26 11:35:07 -0400338 stream_session_t **pool, *session;
Dave Barach68b0fb02017-02-28 15:15:56 -0500339
Florin Corase04c2992017-03-01 08:17:34 -0800340 if (!smm->is_enabled)
341 {
flyingeagle23e2125062017-04-20 20:01:14 +0800342 return clib_error_return (0, "session layer is not enabled");
Florin Corase04c2992017-03-01 08:17:34 -0800343 }
344
Dave Barach68b0fb02017-02-28 15:15:56 -0500345 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
346 {
347 if (unformat (input, "thread %d", &thread_index))
348 ;
349 else if (unformat (input, "session %d", &session_index))
350 ;
Dave Barach2c25a622017-06-26 11:35:07 -0400351 else if (unformat (input, "all"))
352 clear_all = 1;
Dave Barach68b0fb02017-02-28 15:15:56 -0500353 else
354 return clib_error_return (0, "unknown input `%U'",
355 format_unformat_error, input);
356 }
357
Dave Barach2c25a622017-06-26 11:35:07 -0400358 if (!clear_all && session_index == ~0)
Dave Barach68b0fb02017-02-28 15:15:56 -0500359 return clib_error_return (0, "session <nn> required, but not set.");
360
Dave Barach2c25a622017-06-26 11:35:07 -0400361 if (session_index != ~0)
362 {
363 session = stream_session_get_if_valid (session_index, thread_index);
364 if (!session)
365 return clib_error_return (0, "no session %d on thread %d",
366 session_index, thread_index);
367 clear_session (session);
368 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500369
Dave Barach2c25a622017-06-26 11:35:07 -0400370 if (clear_all)
371 {
372 /* *INDENT-OFF* */
373 vec_foreach (pool, smm->sessions)
374 {
375 pool_foreach(session, *pool, ({
376 clear_session (session);
377 }));
378 };
379 /* *INDENT-ON* */
380 }
Dave Barach68b0fb02017-02-28 15:15:56 -0500381
382 return 0;
383}
384
Florin Corase04c2992017-03-01 08:17:34 -0800385/* *INDENT-OFF* */
386VLIB_CLI_COMMAND (clear_session_command, static) =
Dave Barach68b0fb02017-02-28 15:15:56 -0500387{
Florin Corase04c2992017-03-01 08:17:34 -0800388 .path = "clear session",
389 .short_help = "clear session thread <thread> session <index>",
390 .function = clear_session_command_fn,
391};
392/* *INDENT-ON* */
393
394static clib_error_t *
Florin Coras3eb50622017-07-13 01:24:57 -0400395show_session_fifo_trace_command_fn (vlib_main_t * vm,
396 unformat_input_t * input,
397 vlib_cli_command_t * cmd)
398{
399 stream_session_t *s = 0;
400 u8 is_rx = 0, *str = 0;
401
402 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
403 {
404 if (unformat (input, "%U", unformat_stream_session, &s))
405 ;
406 else if (unformat (input, "rx"))
407 is_rx = 1;
408 else if (unformat (input, "tx"))
409 is_rx = 0;
410 else
411 return clib_error_return (0, "unknown input `%U'",
412 format_unformat_error, input);
413 }
414
415 if (!SVM_FIFO_TRACE)
416 {
417 vlib_cli_output (vm, "fifo tracing not enabled");
418 return 0;
419 }
420
421 if (!s)
422 {
423 vlib_cli_output (vm, "could not find session");
424 return 0;
425 }
426
427 str = is_rx ?
428 svm_fifo_dump_trace (str, s->server_rx_fifo) :
429 svm_fifo_dump_trace (str, s->server_tx_fifo);
430
431 vlib_cli_output (vm, "%v", str);
432 return 0;
433}
434
435/* *INDENT-OFF* */
436VLIB_CLI_COMMAND (show_session_fifo_trace_command, static) =
437{
438 .path = "show session fifo trace",
439 .short_help = "show session fifo trace <session>",
440 .function = show_session_fifo_trace_command_fn,
441};
442/* *INDENT-ON* */
443
444static clib_error_t *
445session_replay_fifo_command_fn (vlib_main_t * vm, unformat_input_t * input,
446 vlib_cli_command_t * cmd)
447{
448 stream_session_t *s = 0;
449 u8 is_rx = 0, *str = 0;
450
451 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
452 {
453 if (unformat (input, "%U", unformat_stream_session, &s))
454 ;
455 else if (unformat (input, "rx"))
456 is_rx = 1;
457 else
458 return clib_error_return (0, "unknown input `%U'",
459 format_unformat_error, input);
460 }
461
462 if (!SVM_FIFO_TRACE)
463 {
464 vlib_cli_output (vm, "fifo tracing not enabled");
465 return 0;
466 }
467
468 if (!s)
469 {
470 vlib_cli_output (vm, "could not find session");
471 return 0;
472 }
473
474 str = is_rx ?
475 svm_fifo_replay (str, s->server_rx_fifo, 0, 1) :
476 svm_fifo_replay (str, s->server_tx_fifo, 0, 1);
477
478 vlib_cli_output (vm, "%v", str);
479 return 0;
480}
481
482/* *INDENT-OFF* */
483VLIB_CLI_COMMAND (session_replay_fifo_trace_command, static) =
484{
485 .path = "session replay fifo",
486 .short_help = "session replay fifo <session>",
487 .function = session_replay_fifo_command_fn,
488};
489/* *INDENT-ON* */
490
491static clib_error_t *
Florin Corase04c2992017-03-01 08:17:34 -0800492session_enable_disable_fn (vlib_main_t * vm, unformat_input_t * input,
493 vlib_cli_command_t * cmd)
494{
495 u8 is_en = 1;
496
497 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
498 {
499 if (unformat (input, "enable"))
500 is_en = 1;
501 else if (unformat (input, "disable"))
502 is_en = 0;
503 else
504 return clib_error_return (0, "unknown input `%U'",
505 format_unformat_error, input);
506 }
507
508 return vnet_session_enable_disable (vm, is_en);
509}
510
511/* *INDENT-OFF* */
512VLIB_CLI_COMMAND (session_enable_disable_command, static) =
513{
514 .path = "session",
515 .short_help = "session [enable|disable]",
516 .function = session_enable_disable_fn,
517};
518/* *INDENT-ON* */
Dave Barach68b0fb02017-02-28 15:15:56 -0500519
520/*
521 * fd.io coding-style-patch-verification: ON
522 *
523 * Local Variables:
524 * eval: (c-set-style "gnu")
525 * End:
526 */