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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <vnet/session/application_namespace.h>
17 #include <vnet/session/application_interface.h>
18 #include <vnet/session/application.h>
19 #include <vnet/session/session.h>
20 #include <vnet/session/session_rules_table.h>
21 #include <vnet/tcp/tcp.h>
22 #include <sys/epoll.h>
24 #define SESSION_TEST_I(_cond, _comment, _args...) \
26 int _evald = (_cond); \
28 fformat(stderr, "FAIL:%d: " _comment "\n", \
31 fformat(stderr, "PASS:%d: " _comment "\n", \
37 #define SESSION_TEST(_cond, _comment, _args...) \
39 if (!SESSION_TEST_I(_cond, _comment, ##_args)) { \
44 #define ST_DBG(_comment, _args...) \
45 fformat(stderr, _comment "\n", ##_args); \
48 dummy_session_reset_callback (session_t * s)
50 clib_warning ("called...");
53 volatile u32 connected_session_index = ~0;
54 volatile u32 connected_session_thread = ~0;
56 dummy_session_connected_callback (u32 app_index, u32 api_context,
57 session_t * s, u8 is_fail)
61 connected_session_index = s->session_index;
62 connected_session_thread = s->thread_index;
67 static u32 dummy_segment_count;
70 dummy_add_segment_callback (u32 client_index, u64 segment_handle)
72 dummy_segment_count = 1;
77 dummy_del_segment_callback (u32 client_index, u64 segment_handle)
79 dummy_segment_count = 0;
84 dummy_session_disconnect_callback (session_t * s)
86 clib_warning ("called...");
89 static u32 dummy_accept;
90 volatile u32 accepted_session_index;
91 volatile u32 accepted_session_thread;
94 dummy_session_accept_callback (session_t * s)
97 accepted_session_index = s->session_index;
98 accepted_session_thread = s->thread_index;
99 s->session_state = SESSION_STATE_READY;
104 dummy_server_rx_callback (session_t * s)
106 clib_warning ("called...");
111 static session_cb_vft_t dummy_session_cbs = {
112 .session_reset_callback = dummy_session_reset_callback,
113 .session_connected_callback = dummy_session_connected_callback,
114 .session_accept_callback = dummy_session_accept_callback,
115 .session_disconnect_callback = dummy_session_disconnect_callback,
116 .builtin_app_rx_callback = dummy_server_rx_callback,
117 .add_segment_callback = dummy_add_segment_callback,
118 .del_segment_callback = dummy_del_segment_callback,
123 session_create_lookpback (u32 table_id, u32 * sw_if_index,
124 ip4_address_t * intf_addr)
128 clib_memset (intf_mac, 0, sizeof (intf_mac));
130 if (vnet_create_loopback_interface (sw_if_index, intf_mac, 0, 0))
132 clib_warning ("couldn't create loopback. stopping the test!");
138 ip_table_create (FIB_PROTOCOL_IP4, table_id, 0, 0);
139 ip_table_bind (FIB_PROTOCOL_IP4, *sw_if_index, table_id, 0);
142 vnet_sw_interface_set_flags (vnet_get_main (), *sw_if_index,
143 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
145 if (ip4_add_del_interface_address (vlib_get_main (), *sw_if_index,
148 clib_warning ("couldn't assign loopback ip %U", format_ip4_address,
157 session_delete_loopback (u32 sw_if_index)
159 /* fails spectacularly */
160 /* vnet_delete_loopback_interface (sw_if_index); */
164 session_test_basic (vlib_main_t * vm, unformat_input_t * input)
166 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
167 u64 options[APP_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle;
171 clib_memset (options, 0, sizeof (options));
172 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
173 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
174 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
175 vnet_app_attach_args_t attach_args = {
176 .api_client_index = ~0,
179 .session_cb_vft = &dummy_session_cbs,
180 .name = format (0, "session_test"),
183 error = vnet_application_attach (&attach_args);
184 SESSION_TEST ((error == 0), "app attached");
185 server_index = attach_args.app_index;
186 vec_free (attach_args.name);
188 server_sep.is_ip4 = 1;
189 vnet_listen_args_t bind_args = {
194 bind_args.app_index = server_index;
195 error = vnet_listen (&bind_args);
196 SESSION_TEST ((error == 0), "server bind4 should work");
197 bind4_handle = bind_args.handle;
199 error = vnet_listen (&bind_args);
200 SESSION_TEST ((error != 0), "double server bind4 should not work");
202 bind_args.sep.is_ip4 = 0;
203 error = vnet_listen (&bind_args);
204 SESSION_TEST ((error == 0), "server bind6 should work");
205 bind6_handle = bind_args.handle;
207 error = vnet_listen (&bind_args);
208 SESSION_TEST ((error != 0), "double server bind6 should not work");
210 vnet_unlisten_args_t unbind_args = {
211 .handle = bind4_handle,
212 .app_index = server_index,
214 error = vnet_unlisten (&unbind_args);
215 SESSION_TEST ((error == 0), "unbind4 should work");
217 unbind_args.handle = bind6_handle;
218 error = vnet_unlisten (&unbind_args);
219 SESSION_TEST ((error == 0), "unbind6 should work");
221 vnet_app_detach_args_t detach_args = {
222 .app_index = server_index,
223 .api_client_index = ~0,
225 vnet_application_detach (&detach_args);
230 session_add_del_route_via_lookup_in_table (u32 in_table_id, u32 via_table_id,
231 ip4_address_t * ip, u8 mask,
234 fib_route_path_t *rpaths = 0, *rpath;
235 u32 in_fib_index, via_fib_index;
237 fib_prefix_t prefix = {
238 .fp_addr.ip4.as_u32 = ip->as_u32,
240 .fp_proto = FIB_PROTOCOL_IP4,
243 via_fib_index = fib_table_find (FIB_PROTOCOL_IP4, via_table_id);
244 if (via_fib_index == ~0)
246 clib_warning ("couldn't resolve via table id to index");
249 in_fib_index = fib_table_find (FIB_PROTOCOL_IP4, in_table_id);
250 if (in_fib_index == ~0)
252 clib_warning ("couldn't resolve in table id to index");
256 vec_add2 (rpaths, rpath, 1);
257 clib_memset (rpath, 0, sizeof (*rpath));
258 rpath->frp_weight = 1;
259 rpath->frp_fib_index = via_fib_index;
260 rpath->frp_proto = DPO_PROTO_IP4;
261 rpath->frp_sw_if_index = ~0;
262 rpath->frp_flags |= FIB_ROUTE_PATH_DEAG;
265 fib_table_entry_path_add2 (in_fib_index, &prefix, FIB_SOURCE_CLI,
266 FIB_ENTRY_FLAG_NONE, rpath);
268 fib_table_entry_path_remove2 (in_fib_index, &prefix, FIB_SOURCE_CLI,
274 session_test_endpoint_cfg (vlib_main_t * vm, unformat_input_t * input)
276 session_endpoint_cfg_t client_sep = SESSION_ENDPOINT_CFG_NULL;
277 u32 server_index, client_index, sw_if_index[2], tries = 0;
278 u64 options[APP_OPTIONS_N_OPTIONS], dummy_secret = 1234;
279 u16 dummy_server_port = 1234, dummy_client_port = 5678;
280 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
281 ip4_address_t intf_addr[3];
282 transport_connection_t *tc;
288 * Create the loopbacks
290 intf_addr[0].as_u32 = clib_host_to_net_u32 (0x01010101),
291 session_create_lookpback (0, &sw_if_index[0], &intf_addr[0]);
293 intf_addr[1].as_u32 = clib_host_to_net_u32 (0x02020202),
294 session_create_lookpback (1, &sw_if_index[1], &intf_addr[1]);
296 session_add_del_route_via_lookup_in_table (0, 1, &intf_addr[1], 32,
298 session_add_del_route_via_lookup_in_table (1, 0, &intf_addr[0], 32,
304 appns_id = format (0, "appns1");
305 vnet_app_namespace_add_del_args_t ns_args = {
307 .secret = dummy_secret,
308 .sw_if_index = sw_if_index[1],
312 error = vnet_app_namespace_add_del (&ns_args);
313 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
316 * Attach client/server
318 clib_memset (options, 0, sizeof (options));
319 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
320 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
322 vnet_app_attach_args_t attach_args = {
323 .api_client_index = ~0,
326 .session_cb_vft = &dummy_session_cbs,
327 .name = format (0, "session_test_client"),
330 error = vnet_application_attach (&attach_args);
331 SESSION_TEST ((error == 0), "client app attached");
332 client_index = attach_args.app_index;
333 vec_free (attach_args.name);
335 attach_args.name = format (0, "session_test_server");
336 attach_args.namespace_id = appns_id;
337 attach_args.options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
338 error = vnet_application_attach (&attach_args);
339 SESSION_TEST ((error == 0), "server app attached: %U", format_clib_error,
341 vec_free (attach_args.name);
342 server_index = attach_args.app_index;
344 server_sep.is_ip4 = 1;
345 server_sep.port = dummy_server_port;
346 vnet_listen_args_t bind_args = {
348 .app_index = server_index,
350 error = vnet_listen (&bind_args);
351 SESSION_TEST ((error == 0), "server bind should work");
354 * Connect and force lcl ip
356 client_sep.is_ip4 = 1;
357 client_sep.ip.ip4.as_u32 = clib_host_to_net_u32 (0x02020202);
358 client_sep.port = dummy_server_port;
359 client_sep.peer.is_ip4 = 1;
360 client_sep.peer.ip.ip4.as_u32 = clib_host_to_net_u32 (0x01010101);
361 client_sep.peer.port = dummy_client_port;
362 client_sep.transport_proto = TRANSPORT_PROTO_TCP;
364 vnet_connect_args_t connect_args = {
365 .sep_ext = client_sep,
366 .app_index = client_index,
369 connected_session_index = connected_session_thread = ~0;
370 accepted_session_index = accepted_session_thread = ~0;
371 error = vnet_connect (&connect_args);
372 SESSION_TEST ((error == 0), "connect should work");
374 /* wait for stuff to happen */
375 while ((connected_session_index == ~0
376 || vec_len (tcp_main.wrk_ctx[0].pending_acks)) && ++tries < 100)
377 vlib_process_suspend (vm, 100e-3);
378 clib_warning ("waited %.1f seconds for connections", tries / 10.0);
379 SESSION_TEST ((connected_session_index != ~0), "session should exist");
380 SESSION_TEST ((connected_session_thread != ~0), "thread should exist");
381 SESSION_TEST ((accepted_session_index != ~0), "session should exist");
382 SESSION_TEST ((accepted_session_thread != ~0), "thread should exist");
383 s = session_get (connected_session_index, connected_session_thread);
384 tc = session_get_transport (s);
385 SESSION_TEST ((tc != 0), "transport should exist");
386 SESSION_TEST ((memcmp (&tc->lcl_ip, &client_sep.peer.ip,
387 sizeof (tc->lcl_ip)) == 0), "ips should be equal");
388 SESSION_TEST ((tc->lcl_port == dummy_client_port), "ports should be equal");
390 /* These sessions, because of the way they're established are pinned to
391 * main thread, even when we have workers and we avoid polling main thread,
392 * i.e., we can't cleanup pending disconnects, so force cleanup for both
394 session_transport_cleanup (s);
395 s = session_get (accepted_session_index, accepted_session_thread);
396 session_transport_cleanup (s);
398 vnet_app_detach_args_t detach_args = {
399 .app_index = server_index,
400 .api_client_index = ~0,
402 vnet_application_detach (&detach_args);
403 detach_args.app_index = client_index;
404 vnet_application_detach (&detach_args);
406 /* Allow the disconnects to finish before removing the routes. */
407 vlib_process_suspend (vm, 10e-3);
409 session_add_del_route_via_lookup_in_table (0, 1, &intf_addr[1], 32,
411 session_add_del_route_via_lookup_in_table (1, 0, &intf_addr[0], 32,
414 session_delete_loopback (sw_if_index[0]);
415 session_delete_loopback (sw_if_index[1]);
420 session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
422 u64 options[APP_OPTIONS_N_OPTIONS], dummy_secret = 1234;
423 u32 server_index, server_st_index, server_local_st_index;
424 u32 dummy_port = 1234, client_index, server_wrk_index;
425 u32 dummy_api_context = 4321, dummy_client_api_index = ~0;
426 u32 dummy_server_api_index = ~0, sw_if_index = 0;
427 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
428 session_endpoint_t client_sep = SESSION_ENDPOINT_NULL;
429 session_endpoint_t intf_sep = SESSION_ENDPOINT_NULL;
430 u8 *ns_id = format (0, "appns1");
431 app_namespace_t *app_ns;
432 application_t *server;
437 server_sep.is_ip4 = 1;
438 server_sep.port = dummy_port;
439 client_sep.is_ip4 = 1;
440 client_sep.port = dummy_port;
441 clib_memset (options, 0, sizeof (options));
443 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
444 vnet_app_attach_args_t attach_args = {
445 .api_client_index = ~0,
448 .session_cb_vft = &dummy_session_cbs,
449 .name = format (0, "session_test"),
452 vnet_listen_args_t bind_args = {
457 vnet_connect_args_t connect_args = {
461 clib_memcpy (&connect_args.sep, &client_sep, sizeof (client_sep));
463 vnet_unlisten_args_t unbind_args = {
464 .handle = bind_args.handle,
468 vnet_app_detach_args_t detach_args = {
470 .api_client_index = ~0,
473 ip4_address_t intf_addr = {
474 .as_u32 = clib_host_to_net_u32 (0x07000105),
477 intf_sep.ip.ip4 = intf_addr;
479 intf_sep.port = dummy_port;
482 * Insert namespace and lookup
485 vnet_app_namespace_add_del_args_t ns_args = {
487 .secret = dummy_secret,
488 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
491 error = vnet_app_namespace_add_del (&ns_args);
492 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
494 app_ns = app_namespace_get_from_id (ns_id);
495 SESSION_TEST ((app_ns != 0), "should find ns %v status", ns_id);
496 SESSION_TEST ((app_ns->ns_secret == dummy_secret), "secret should be %d",
498 SESSION_TEST ((app_ns->sw_if_index == APP_NAMESPACE_INVALID_INDEX),
499 "sw_if_index should be invalid");
502 * Try application attach with wrong secret
505 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
506 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
507 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret - 1;
508 attach_args.namespace_id = ns_id;
509 attach_args.api_client_index = dummy_server_api_index;
511 error = vnet_application_attach (&attach_args);
512 SESSION_TEST ((error != 0), "app attachment should fail");
513 SESSION_TEST ((error == VNET_API_ERROR_APP_WRONG_NS_SECRET),
514 "code should be wrong ns secret: %d", error);
517 * Attach server with global default scope
519 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
520 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
521 options[APP_OPTIONS_NAMESPACE_SECRET] = 0;
522 attach_args.namespace_id = 0;
523 attach_args.api_client_index = dummy_server_api_index;
524 error = vnet_application_attach (&attach_args);
525 SESSION_TEST ((error == 0), "server attachment should work");
526 server_index = attach_args.app_index;
527 server = application_get (server_index);
528 server_wrk_index = application_get_default_worker (server)->wrk_index;
529 SESSION_TEST ((server->ns_index == 0),
530 "server should be in the default ns");
532 bind_args.app_index = server_index;
533 error = vnet_listen (&bind_args);
534 SESSION_TEST ((error == 0), "server bind should work");
536 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
537 s = session_lookup_listener (server_st_index, &server_sep);
538 SESSION_TEST ((s != 0), "listener should exist in global table");
539 SESSION_TEST ((s->app_wrk_index == server_wrk_index), "app_index should be"
540 " that of the server");
541 server_local_st_index = application_local_session_table (server);
542 SESSION_TEST ((server_local_st_index == APP_INVALID_INDEX),
543 "server shouldn't have access to local table");
545 unbind_args.app_index = server_index;
546 unbind_args.handle = bind_args.handle;
547 error = vnet_unlisten (&unbind_args);
548 SESSION_TEST ((error == 0), "unbind should work");
550 s = session_lookup_listener (server_st_index, &server_sep);
551 SESSION_TEST ((s == 0), "listener should not exist in global table");
553 detach_args.app_index = server_index;
554 vnet_application_detach (&detach_args);
557 * Attach server with local and global scope
559 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
560 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
561 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
562 attach_args.namespace_id = ns_id;
563 attach_args.api_client_index = dummy_server_api_index;
564 error = vnet_application_attach (&attach_args);
565 SESSION_TEST ((error == 0), "server attachment should work");
566 server_index = attach_args.app_index;
567 server = application_get (server_index);
568 server_wrk_index = application_get_default_worker (server)->wrk_index;
569 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
570 "server should be in the right ns");
572 bind_args.app_index = server_index;
573 error = vnet_listen (&bind_args);
574 SESSION_TEST ((error == 0), "bind should work");
575 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
576 s = session_lookup_listener (server_st_index, &server_sep);
577 SESSION_TEST ((s != 0), "listener should exist in global table");
578 SESSION_TEST ((s->app_wrk_index == server_wrk_index), "app_index should be"
579 " that of the server");
580 server_local_st_index = application_local_session_table (server);
581 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
582 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
583 "listener should exist in local table");
586 * Try client connect with 1) local scope 2) global scope
588 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
589 attach_args.api_client_index = dummy_client_api_index;
590 error = vnet_application_attach (&attach_args);
591 SESSION_TEST ((error == 0), "client attachment should work");
592 client_index = attach_args.app_index;
593 connect_args.api_context = dummy_api_context;
594 connect_args.app_index = client_index;
595 error = vnet_connect (&connect_args);
596 SESSION_TEST ((error != 0), "client connect should return error code");
597 SESSION_TEST ((error == VNET_API_ERROR_INVALID_VALUE),
598 "error code should be invalid value (zero ip)");
599 SESSION_TEST ((dummy_segment_count == 0),
600 "shouldn't have received request to map new segment");
601 connect_args.sep.ip.ip4.as_u8[0] = 127;
602 error = vnet_connect (&connect_args);
603 SESSION_TEST ((error == 0), "client connect should not return error code");
604 SESSION_TEST ((dummy_segment_count == 1),
605 "should've received request to map new segment");
606 SESSION_TEST ((dummy_accept == 1), "should've received accept request");
607 detach_args.app_index = client_index;
608 vnet_application_detach (&detach_args);
610 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
611 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
612 attach_args.api_client_index = dummy_client_api_index;
613 error = vnet_application_attach (&attach_args);
614 SESSION_TEST ((error == 0), "client attachment should work");
615 error = vnet_connect (&connect_args);
616 SESSION_TEST ((error != 0), "client connect should return error code");
617 SESSION_TEST ((error == VNET_API_ERROR_SESSION_CONNECT),
618 "error code should be connect (nothing in local scope)");
619 detach_args.app_index = client_index;
620 vnet_application_detach (&detach_args);
623 * Unbind and detach server and then re-attach with local scope only
625 unbind_args.handle = bind_args.handle;
626 unbind_args.app_index = server_index;
627 error = vnet_unlisten (&unbind_args);
628 SESSION_TEST ((error == 0), "unbind should work");
630 s = session_lookup_listener (server_st_index, &server_sep);
631 SESSION_TEST ((s == 0), "listener should not exist in global table");
632 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
633 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
634 "listener should not exist in local table");
636 detach_args.app_index = server_index;
637 vnet_application_detach (&detach_args);
639 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
640 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
641 attach_args.api_client_index = dummy_server_api_index;
642 error = vnet_application_attach (&attach_args);
643 SESSION_TEST ((error == 0), "app attachment should work");
644 server_index = attach_args.app_index;
645 server = application_get (server_index);
646 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
647 "app should be in the right ns");
649 bind_args.app_index = server_index;
650 error = vnet_listen (&bind_args);
651 SESSION_TEST ((error == 0), "bind should work");
653 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
654 s = session_lookup_listener (server_st_index, &server_sep);
655 SESSION_TEST ((s == 0), "listener should not exist in global table");
656 server_local_st_index = application_local_session_table (server);
657 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
658 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
659 "listener should exist in local table");
661 unbind_args.handle = bind_args.handle;
662 error = vnet_unlisten (&unbind_args);
663 SESSION_TEST ((error == 0), "unbind should work");
665 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
666 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
667 "listener should not exist in local table");
670 * Client attach + connect in default ns with local scope
672 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
673 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
674 attach_args.namespace_id = 0;
675 attach_args.api_client_index = dummy_client_api_index;
676 vnet_application_attach (&attach_args);
677 error = vnet_connect (&connect_args);
678 SESSION_TEST ((error != 0), "client connect should return error code");
679 SESSION_TEST ((error == VNET_API_ERROR_SESSION_CONNECT),
680 "error code should be connect (not in same ns)");
681 detach_args.app_index = client_index;
682 vnet_application_detach (&detach_args);
687 detach_args.app_index = server_index;
688 vnet_application_detach (&detach_args);
691 * Create loopback interface
693 session_create_lookpback (0, &sw_if_index, &intf_addr);
696 * Update namespace with interface
698 ns_args.sw_if_index = sw_if_index;
699 error = vnet_app_namespace_add_del (&ns_args);
700 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
703 * Attach server with local and global scope
705 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
706 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
707 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
708 attach_args.namespace_id = ns_id;
709 attach_args.api_client_index = dummy_server_api_index;
710 error = vnet_application_attach (&attach_args);
711 SESSION_TEST ((error == 0), "server attachment should work");
712 server_index = attach_args.app_index;
713 server = application_get (server_index);
714 server_wrk_index = application_get_default_worker (server)->wrk_index;
716 bind_args.app_index = server_index;
717 error = vnet_listen (&bind_args);
718 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
719 s = session_lookup_listener (server_st_index, &server_sep);
720 SESSION_TEST ((s == 0), "zero listener should not exist in global table");
722 s = session_lookup_listener (server_st_index, &intf_sep);
723 SESSION_TEST ((s != 0), "intf listener should exist in global table");
724 SESSION_TEST ((s->app_wrk_index == server_wrk_index), "app_index should be "
725 "that of the server");
726 server_local_st_index = application_local_session_table (server);
727 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
728 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
729 "zero listener should exist in local table");
730 detach_args.app_index = server_index;
731 vnet_application_detach (&detach_args);
736 vec_free (attach_args.name);
738 session_delete_loopback (sw_if_index);
743 session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
745 session_rules_table_t _srt, *srt = &_srt;
746 u16 lcl_port = 1234, rmt_port = 4321;
747 u32 action_index = 1, res;
748 ip4_address_t lcl_lkup, rmt_lkup;
749 int verbose = 0, error;
751 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
753 if (unformat (input, "verbose"))
757 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
763 clib_memset (srt, 0, sizeof (*srt));
764 session_rules_table_init (srt);
766 ip4_address_t lcl_ip = {
767 .as_u32 = clib_host_to_net_u32 (0x01020304),
769 ip4_address_t rmt_ip = {
770 .as_u32 = clib_host_to_net_u32 (0x05060708),
772 ip4_address_t lcl_ip2 = {
773 .as_u32 = clib_host_to_net_u32 (0x02020202),
775 ip4_address_t rmt_ip2 = {
776 .as_u32 = clib_host_to_net_u32 (0x06060606),
778 ip4_address_t lcl_ip3 = {
779 .as_u32 = clib_host_to_net_u32 (0x03030303),
781 ip4_address_t rmt_ip3 = {
782 .as_u32 = clib_host_to_net_u32 (0x07070707),
784 fib_prefix_t lcl_pref = {
785 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
787 .fp_proto = FIB_PROTOCOL_IP4,
789 fib_prefix_t rmt_pref = {
790 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
792 .fp_proto = FIB_PROTOCOL_IP4,
795 session_rule_table_add_del_args_t args = {
798 .lcl_port = lcl_port,
799 .rmt_port = rmt_port,
800 .action_index = action_index++,
803 error = session_rules_table_add_del (srt, &args);
804 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
808 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
809 SESSION_TEST ((res == 1),
810 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
814 * Add 1.2.3.4/24 1234 5.6.7.8/16 4321 and 1.2.3.4/24 1234 5.6.7.8/24 4321
816 args.lcl.fp_addr.ip4 = lcl_ip;
817 args.lcl.fp_len = 24;
818 args.action_index = action_index++;
819 error = session_rules_table_add_del (srt, &args);
820 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/16 4321 action %d",
822 args.rmt.fp_addr.ip4 = rmt_ip;
823 args.rmt.fp_len = 24;
824 args.action_index = action_index++;
825 error = session_rules_table_add_del (srt, &args);
826 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/24 4321 action %d",
830 * Add 2.2.2.2/24 1234 6.6.6.6/16 4321 and 3.3.3.3/24 1234 7.7.7.7/16 4321
832 args.lcl.fp_addr.ip4 = lcl_ip2;
833 args.lcl.fp_len = 24;
834 args.rmt.fp_addr.ip4 = rmt_ip2;
835 args.rmt.fp_len = 16;
836 args.action_index = action_index++;
837 error = session_rules_table_add_del (srt, &args);
838 SESSION_TEST ((error == 0), "Add 2.2.2.2/24 1234 6.6.6.6/16 4321 action %d",
840 args.lcl.fp_addr.ip4 = lcl_ip3;
841 args.rmt.fp_addr.ip4 = rmt_ip3;
842 args.action_index = action_index++;
843 error = session_rules_table_add_del (srt, &args);
844 SESSION_TEST ((error == 0), "Add 3.3.3.3/24 1234 7.7.7.7/16 4321 action %d",
848 * Add again 3.3.3.3/24 1234 7.7.7.7/16 4321
850 args.lcl.fp_addr.ip4 = lcl_ip3;
851 args.rmt.fp_addr.ip4 = rmt_ip3;
852 args.action_index = action_index++;
853 error = session_rules_table_add_del (srt, &args);
854 SESSION_TEST ((error == 0), "overwrite 3.3.3.3/24 1234 7.7.7.7/16 4321 "
855 "action %d", action_index - 1);
858 * Lookup 1.2.3.4/32 1234 5.6.7.8/32 4321, 1.2.2.4/32 1234 5.6.7.9/32 4321
859 * and 3.3.3.3 1234 7.7.7.7 4321
862 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
863 SESSION_TEST ((res == 3),
864 "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
867 lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
868 rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
870 session_rules_table_lookup4 (srt, &lcl_lkup,
871 &rmt_lkup, lcl_port, rmt_port);
872 SESSION_TEST ((res == 1),
873 "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
877 session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
878 SESSION_TEST ((res == 6),
879 "Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
880 "should be 6 (updated): %d", res);
883 * Add 1.2.3.4/24 * 5.6.7.8/24 *
884 * Lookup 1.2.3.4 1234 5.6.7.8 4321 and 1.2.3.4 1235 5.6.7.8 4321
886 args.lcl.fp_addr.ip4 = lcl_ip;
887 args.rmt.fp_addr.ip4 = rmt_ip;
888 args.lcl.fp_len = 24;
889 args.rmt.fp_len = 24;
892 args.action_index = action_index++;
893 error = session_rules_table_add_del (srt, &args);
894 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
897 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
898 SESSION_TEST ((res == 7),
899 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
900 " be 7 (lpm dst): %d", res);
902 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
903 lcl_port + 1, rmt_port);
904 SESSION_TEST ((res == 7),
905 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
909 * Del 1.2.3.4/24 * 5.6.7.8/24 *
910 * Add 1.2.3.4/16 * 5.6.7.8/16 * and 1.2.3.4/24 1235 5.6.7.8/24 4321
911 * Lookup 1.2.3.4 1234 5.6.7.8 4321, 1.2.3.4 1235 5.6.7.8 4321 and
912 * 1.2.3.4 1235 5.6.7.8 4322
915 error = session_rules_table_add_del (srt, &args);
916 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 * 5.6.7.8/24 *");
918 args.lcl.fp_addr.ip4 = lcl_ip;
919 args.rmt.fp_addr.ip4 = rmt_ip;
920 args.lcl.fp_len = 16;
921 args.rmt.fp_len = 16;
924 args.action_index = action_index++;
926 error = session_rules_table_add_del (srt, &args);
927 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 * action %d",
930 args.lcl.fp_addr.ip4 = lcl_ip;
931 args.rmt.fp_addr.ip4 = rmt_ip;
932 args.lcl.fp_len = 24;
933 args.rmt.fp_len = 24;
934 args.lcl_port = lcl_port + 1;
935 args.rmt_port = rmt_port;
936 args.action_index = action_index++;
938 error = session_rules_table_add_del (srt, &args);
939 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1235 5.6.7.8/24 4321 action %d",
943 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
946 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
947 SESSION_TEST ((res == 3),
948 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
951 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
952 lcl_port + 1, rmt_port);
953 SESSION_TEST ((res == 9),
954 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
957 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
958 lcl_port + 1, rmt_port + 1);
959 SESSION_TEST ((res == 8),
960 "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
964 * Delete 1.2.0.0/16 1234 5.6.0.0/16 4321 and 1.2.0.0/16 * 5.6.0.0/16 *
965 * Lookup 1.2.3.4 1234 5.6.7.8 4321
967 args.lcl_port = 1234;
968 args.rmt_port = 4321;
969 args.lcl.fp_len = 16;
970 args.rmt.fp_len = 16;
972 error = session_rules_table_add_del (srt, &args);
973 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
975 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
976 SESSION_TEST ((res == 3),
977 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
983 error = session_rules_table_add_del (srt, &args);
984 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
986 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
987 SESSION_TEST ((res == 3),
988 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
992 * Delete 1.2.3.4/24 1234 5.6.7.5/24
994 args.lcl.fp_addr.ip4 = lcl_ip;
995 args.rmt.fp_addr.ip4 = rmt_ip;
996 args.lcl.fp_len = 24;
997 args.rmt.fp_len = 24;
998 args.lcl_port = 1234;
999 args.rmt_port = 4321;
1001 error = session_rules_table_add_del (srt, &args);
1002 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
1004 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
1005 SESSION_TEST ((res == 2), "Action should be 2: %d", res);
1011 session_test_rules (vlib_main_t * vm, unformat_input_t * input)
1013 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
1014 u64 options[APP_OPTIONS_N_OPTIONS];
1015 u16 lcl_port = 1234, rmt_port = 4321;
1016 u32 server_index, server_index2;
1017 u32 dummy_server_api_index = ~0;
1018 transport_connection_t *tc;
1019 u32 dummy_port = 1111;
1020 u8 is_filtered = 0, *ns_id = format (0, "appns1");
1021 session_t *listener, *s;
1022 app_namespace_t *default_ns = app_namespace_get_default ();
1023 u32 local_ns_index = default_ns->local_table_index;
1025 app_namespace_t *app_ns;
1030 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1032 if (unformat (input, "verbose"))
1036 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1042 server_sep.is_ip4 = 1;
1043 server_sep.port = dummy_port;
1044 clib_memset (options, 0, sizeof (options));
1046 vnet_app_attach_args_t attach_args = {
1047 .api_client_index = ~0,
1050 .session_cb_vft = &dummy_session_cbs,
1051 .name = format (0, "session_test"),
1054 vnet_listen_args_t bind_args = {
1060 * Attach server with global and local default scope
1062 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
1063 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1064 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1065 attach_args.namespace_id = 0;
1066 attach_args.api_client_index = dummy_server_api_index;
1067 error = vnet_application_attach (&attach_args);
1068 SESSION_TEST ((error == 0), "server attached");
1069 server_index = attach_args.app_index;
1071 bind_args.app_index = server_index;
1072 error = vnet_listen (&bind_args);
1073 SESSION_TEST ((error == 0), "server bound to %U/%d", format_ip46_address,
1074 &server_sep.ip, 1, server_sep.port);
1075 al = app_listener_get_w_handle (bind_args.handle);
1076 listener = app_listener_get_session (al);
1077 ip4_address_t lcl_ip = {
1078 .as_u32 = clib_host_to_net_u32 (0x01020304),
1080 ip4_address_t rmt_ip = {
1081 .as_u32 = clib_host_to_net_u32 (0x05060708),
1083 fib_prefix_t lcl_pref = {
1084 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
1086 .fp_proto = FIB_PROTOCOL_IP4,
1088 fib_prefix_t rmt_pref = {
1089 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1091 .fp_proto = FIB_PROTOCOL_IP4,
1094 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1095 &rmt_pref.fp_addr.ip4, lcl_port,
1096 rmt_port, TRANSPORT_PROTO_TCP, 0,
1098 SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
1101 * Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action server_index
1103 session_rule_add_del_args_t args = {
1104 .table_args.lcl = lcl_pref,
1105 .table_args.rmt = rmt_pref,
1106 .table_args.lcl_port = lcl_port,
1107 .table_args.rmt_port = rmt_port,
1108 .table_args.action_index = server_index,
1109 .table_args.is_add = 1,
1112 error = vnet_session_rule_add_del (&args);
1113 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
1114 args.table_args.action_index);
1116 tc = session_lookup_connection4 (0, &lcl_pref.fp_addr.ip4,
1117 &rmt_pref.fp_addr.ip4, lcl_port, rmt_port,
1118 TRANSPORT_PROTO_TCP);
1119 SESSION_TEST ((tc->c_index == listener->connection_index),
1120 "optimized lookup should return the listener");
1121 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1122 &rmt_pref.fp_addr.ip4, lcl_port,
1123 rmt_port, TRANSPORT_PROTO_TCP, 0,
1125 SESSION_TEST ((tc->c_index == listener->connection_index),
1126 "lookup should return the listener");
1127 s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
1128 lcl_port, rmt_port, TRANSPORT_PROTO_TCP);
1129 SESSION_TEST ((s->connection_index == listener->connection_index),
1130 "safe lookup should return the listener");
1131 session_endpoint_t sep = {
1132 .ip = rmt_pref.fp_addr,
1135 .transport_proto = TRANSPORT_PROTO_TCP,
1137 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1138 SESSION_TEST ((handle != server_index), "local session endpoint lookup "
1139 "should not work (global scope)");
1141 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1142 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1143 rmt_port, TRANSPORT_PROTO_TCP, 0,
1145 SESSION_TEST ((tc == 0),
1146 "optimized lookup for wrong lcl port + 1 should not work");
1149 * Add 1.2.3.4/16 * 5.6.7.8/16 4321
1151 args.table_args.lcl_port = 0;
1152 args.scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
1153 error = vnet_session_rule_add_del (&args);
1154 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 4321 action %d",
1155 args.table_args.action_index);
1156 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1157 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1158 rmt_port, TRANSPORT_PROTO_TCP, 0,
1160 SESSION_TEST ((tc->c_index == listener->connection_index),
1161 "optimized lookup for lcl port + 1 should work");
1162 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1163 SESSION_TEST ((handle == server_index), "local session endpoint lookup "
1164 "should work (lcl ip was zeroed)");
1167 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
1169 args.table_args.lcl_port = 1234;
1170 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1171 args.table_args.lcl.fp_len = 30;
1172 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1173 args.table_args.rmt.fp_len = 30;
1174 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1175 error = vnet_session_rule_add_del (&args);
1176 SESSION_TEST ((error == 0), "Add 1.2.3.4/30 1234 5.6.7.8/30 4321 action %d",
1177 args.table_args.action_index);
1181 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1182 TRANSPORT_PROTO_TCP);
1183 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1184 TRANSPORT_PROTO_TCP);
1187 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1188 &rmt_pref.fp_addr.ip4, lcl_port,
1189 rmt_port, TRANSPORT_PROTO_TCP, 0,
1191 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
1192 "should fail (deny rule)");
1193 SESSION_TEST ((is_filtered == SESSION_LOOKUP_RESULT_FILTERED),
1194 "lookup should be filtered (deny)");
1196 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1197 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1198 "5.6.7.8/16 4321 in local table should return deny");
1200 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1201 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1202 rmt_port, TRANSPORT_PROTO_TCP, 0,
1204 SESSION_TEST ((tc->c_index == listener->connection_index),
1205 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should work");
1208 * "Mask" deny rule with more specific allow:
1209 * Add allow rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -3 (allow)
1211 args.table_args.is_add = 1;
1212 args.table_args.lcl_port = 1234;
1213 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1214 args.table_args.lcl.fp_len = 32;
1215 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1216 args.table_args.rmt.fp_len = 32;
1217 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1218 error = vnet_session_rule_add_del (&args);
1219 SESSION_TEST ((error == 0), "Add masking rule 1.2.3.4/30 1234 5.6.7.8/32 "
1220 "4321 action %d", args.table_args.action_index);
1223 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1224 &rmt_pref.fp_addr.ip4, lcl_port,
1225 rmt_port, TRANSPORT_PROTO_TCP, 0,
1227 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
1228 "should fail (allow without app)");
1229 SESSION_TEST ((is_filtered == 0), "lookup should NOT be filtered");
1231 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1232 SESSION_TEST ((handle == SESSION_INVALID_HANDLE), "lookup for 1.2.3.4/32 "
1233 "1234 5.6.7.8/32 4321 in local table should return invalid");
1237 vlib_cli_output (vm, "Local rules");
1238 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1239 TRANSPORT_PROTO_TCP);
1242 sep.ip.ip4.as_u32 += 1 << 24;
1243 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1244 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234"
1245 " 5.6.7.9/32 4321 in local table should return deny");
1247 vnet_connect_args_t connect_args = {
1248 .app_index = attach_args.app_index,
1251 clib_memcpy (&connect_args.sep, &sep, sizeof (sep));
1253 /* Try connecting */
1254 error = vnet_connect (&connect_args);
1255 SESSION_TEST ((error != 0), "connect should fail");
1256 SESSION_TEST ((error == VNET_API_ERROR_APP_CONNECT_FILTERED),
1257 "connect should be filtered");
1259 sep.ip.ip4.as_u32 -= 1 << 24;
1262 * Delete masking rule: 1.2.3.4/32 1234 5.6.7.8/32 4321 allow
1264 args.table_args.is_add = 0;
1265 args.table_args.lcl_port = 1234;
1266 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1267 args.table_args.lcl.fp_len = 32;
1268 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1269 args.table_args.rmt.fp_len = 32;
1270 error = vnet_session_rule_add_del (&args);
1271 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 allow");
1275 * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
1277 args.table_args.is_add = 1;
1278 args.table_args.lcl_port = 0;
1279 args.table_args.lcl.fp_len = 0;
1280 args.table_args.rmt.fp_len = 16;
1281 args.table_args.action_index = -1;
1282 error = vnet_session_rule_add_del (&args);
1283 SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d",
1284 args.table_args.action_index);
1288 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1289 TRANSPORT_PROTO_TCP);
1290 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1291 TRANSPORT_PROTO_TCP);
1294 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1295 SESSION_TEST ((handle == SESSION_DROP_HANDLE),
1296 "local session endpoint lookup should return deny");
1299 * Delete 1.2.3.4/32 1234 5.6.7.8/32 4321 deny
1301 args.table_args.is_add = 0;
1302 args.table_args.lcl_port = 1234;
1303 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1304 args.table_args.lcl.fp_len = 30;
1305 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1306 args.table_args.rmt.fp_len = 30;
1307 error = vnet_session_rule_add_del (&args);
1308 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1310 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1311 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
1312 "local session endpoint lookup should return invalid");
1315 * Delete 0/0 * 5.6.7.8/16 4321, 1.2.3.4/16 * 5.6.7.8/16 4321 and
1316 * 1.2.3.4/16 1234 5.6.7.8/16 4321
1318 args.table_args.is_add = 0;
1319 args.table_args.lcl_port = 0;
1320 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1321 args.table_args.lcl.fp_len = 0;
1322 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1323 args.table_args.rmt.fp_len = 16;
1324 args.table_args.rmt_port = 4321;
1325 error = vnet_session_rule_add_del (&args);
1326 SESSION_TEST ((error == 0), "Del 0/0 * 5.6.7.8/16 4321");
1327 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1328 SESSION_TEST ((handle != server_index), "local session endpoint lookup "
1329 "should not work (removed)");
1331 args.table_args.is_add = 0;
1332 args.table_args.lcl = lcl_pref;
1334 args.table_args.is_add = 0;
1335 args.table_args.lcl_port = 0;
1336 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1337 args.table_args.lcl.fp_len = 16;
1338 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1339 args.table_args.rmt.fp_len = 16;
1340 args.table_args.rmt_port = 4321;
1341 error = vnet_session_rule_add_del (&args);
1342 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
1343 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1344 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1345 rmt_port, TRANSPORT_PROTO_TCP, 0,
1347 SESSION_TEST ((tc == 0),
1348 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should not "
1351 args.table_args.is_add = 0;
1352 args.table_args.lcl_port = 1234;
1353 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1354 args.table_args.lcl.fp_len = 16;
1355 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1356 args.table_args.rmt.fp_len = 16;
1357 args.table_args.rmt_port = 4321;
1358 error = vnet_session_rule_add_del (&args);
1359 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
1360 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1361 &rmt_pref.fp_addr.ip4, lcl_port,
1362 rmt_port, TRANSPORT_PROTO_TCP, 0,
1364 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should "
1365 "not work (del + deny)");
1367 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1368 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1369 &rmt_pref.fp_addr.ip4, lcl_port,
1370 rmt_port, TRANSPORT_PROTO_TCP, 0,
1372 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should"
1373 " not work (no-rule)");
1376 * Test tags. Add/overwrite/del rule with tag
1378 args.table_args.is_add = 1;
1379 args.table_args.lcl_port = 1234;
1380 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1381 args.table_args.lcl.fp_len = 16;
1382 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1383 args.table_args.rmt.fp_len = 16;
1384 args.table_args.rmt_port = 4321;
1385 args.table_args.tag = format (0, "test_rule");
1386 args.table_args.action_index = server_index;
1387 error = vnet_session_rule_add_del (&args);
1388 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 deny "
1392 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1393 TRANSPORT_PROTO_TCP);
1394 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1395 TRANSPORT_PROTO_TCP);
1397 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1398 &rmt_pref.fp_addr.ip4, lcl_port,
1399 rmt_port, TRANSPORT_PROTO_TCP, 0,
1401 SESSION_TEST ((tc->c_index == listener->connection_index),
1402 "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should work");
1404 vec_free (args.table_args.tag);
1405 args.table_args.lcl_port = 1234;
1406 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1407 args.table_args.lcl.fp_len = 16;
1408 args.table_args.tag = format (0, "test_rule_overwrite");
1409 error = vnet_session_rule_add_del (&args);
1410 SESSION_TEST ((error == 0),
1411 "Overwrite 1.2.3.4/16 1234 5.6.7.8/16 4321 deny tag test_rule"
1415 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1416 TRANSPORT_PROTO_TCP);
1417 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1418 TRANSPORT_PROTO_TCP);
1421 args.table_args.is_add = 0;
1422 args.table_args.lcl_port += 1;
1423 error = vnet_session_rule_add_del (&args);
1424 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny "
1425 "tag %v", args.table_args.tag);
1428 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1429 TRANSPORT_PROTO_TCP);
1430 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1431 TRANSPORT_PROTO_TCP);
1433 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1434 &rmt_pref.fp_addr.ip4, lcl_port,
1435 rmt_port, TRANSPORT_PROTO_TCP, 0,
1437 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/32 4321 should not"
1442 * Test local rules with multiple namespaces
1446 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1448 args.table_args.is_add = 1;
1449 args.table_args.lcl_port = 1234;
1450 args.table_args.rmt_port = 0;
1451 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1452 args.table_args.lcl.fp_len = 32;
1453 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1454 args.table_args.rmt.fp_len = 32;
1455 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1456 args.table_args.tag = 0;
1457 args.scope = SESSION_RULE_SCOPE_LOCAL;
1458 error = vnet_session_rule_add_del (&args);
1459 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
1460 args.table_args.action_index);
1462 * Add 'white' rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
1464 args.table_args.is_add = 1;
1465 args.table_args.lcl_port = 1234;
1466 args.table_args.rmt_port = 4321;
1467 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1468 args.table_args.lcl.fp_len = 32;
1469 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1470 args.table_args.rmt.fp_len = 32;
1471 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1472 error = vnet_session_rule_add_del (&args);
1476 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1477 TRANSPORT_PROTO_TCP);
1480 vnet_app_namespace_add_del_args_t ns_args = {
1483 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
1486 error = vnet_app_namespace_add_del (&ns_args);
1487 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
1488 app_ns = app_namespace_get_from_id (ns_id);
1490 attach_args.namespace_id = ns_id;
1491 attach_args.api_client_index = dummy_server_api_index;
1492 error = vnet_application_attach (&attach_args);
1493 SESSION_TEST ((error == 0), "server2 attached");
1494 server_index2 = attach_args.app_index;
1497 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1499 args.table_args.lcl_port = 1234;
1500 args.table_args.rmt_port = 0;
1501 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1502 args.table_args.lcl.fp_len = 32;
1503 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1504 args.table_args.rmt.fp_len = 32;
1505 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1506 args.appns_index = app_namespace_index (app_ns);
1508 error = vnet_session_rule_add_del (&args);
1509 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d "
1510 "in test namespace", args.table_args.action_index);
1512 * Lookup default namespace
1514 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1515 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
1516 "lookup for 1.2.3.4/32 1234 5.6.7.8/32 4321 in local table "
1517 "should return allow (invalid)");
1520 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1521 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1522 "5.6.7.8/16 432*2* in local table should return deny");
1525 connect_args.app_index = server_index;
1526 clib_memcpy (&connect_args.sep, &sep, sizeof (sep));
1528 error = vnet_connect (&connect_args);
1529 SESSION_TEST ((error != 0), "connect should fail");
1530 SESSION_TEST ((error == VNET_API_ERROR_APP_CONNECT_FILTERED),
1531 "connect should be filtered");
1534 * Lookup test namespace
1536 handle = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1537 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1538 "5.6.7.8/16 4321 in local table should return deny");
1540 connect_args.app_index = server_index;
1541 error = vnet_connect (&connect_args);
1542 SESSION_TEST ((error != 0), "connect should fail");
1543 SESSION_TEST ((error == VNET_API_ERROR_APP_CONNECT_FILTERED),
1544 "connect should be filtered");
1546 args.table_args.is_add = 0;
1547 vnet_session_rule_add_del (&args);
1549 args.appns_index = 0;
1550 args.table_args.is_add = 0;
1551 vnet_session_rule_add_del (&args);
1553 args.table_args.rmt_port = 4321;
1554 vnet_session_rule_add_del (&args);
1558 vec_free (args.table_args.tag);
1559 vnet_app_detach_args_t detach_args = {
1560 .app_index = server_index,
1561 .api_client_index = ~0,
1563 vnet_application_detach (&detach_args);
1565 detach_args.app_index = server_index2;
1566 vnet_application_detach (&detach_args);
1569 vec_free (attach_args.name);
1574 session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
1576 u64 options[APP_OPTIONS_N_OPTIONS];
1577 char *show_listeners = "sh session listeners tcp verbose";
1578 char *show_local_listeners = "sh app ns table default";
1579 unformat_input_t tmp_input;
1580 u32 server_index, app_index;
1581 u32 dummy_server_api_index = ~0, sw_if_index = 0;
1584 transport_connection_t *tc;
1585 u16 lcl_port = 1234, rmt_port = 4321;
1586 app_namespace_t *app_ns;
1587 int verbose = 0, error = 0;
1589 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1591 if (unformat (input, "verbose"))
1595 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1601 ip4_address_t lcl_ip = {
1602 .as_u32 = clib_host_to_net_u32 (0x01020304),
1604 ip4_address_t rmt_ip = {
1605 .as_u32 = clib_host_to_net_u32 (0x05060708),
1607 fib_prefix_t rmt_pref = {
1608 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1610 .fp_proto = FIB_PROTOCOL_IP4,
1612 session_endpoint_t sep = {
1613 .ip = rmt_pref.fp_addr,
1616 .transport_proto = TRANSPORT_PROTO_TCP,
1620 * Create loopback interface
1622 session_create_lookpback (0, &sw_if_index, &lcl_ip);
1624 app_ns = app_namespace_get_default ();
1625 app_ns->sw_if_index = sw_if_index;
1627 clib_memset (options, 0, sizeof (options));
1628 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
1629 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
1630 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_IS_PROXY;
1631 options[APP_OPTIONS_PROXY_TRANSPORT] = 1 << TRANSPORT_PROTO_TCP;
1632 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1633 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1634 vnet_app_attach_args_t attach_args = {
1635 .api_client_index = ~0,
1638 .session_cb_vft = &dummy_session_cbs,
1639 .name = format (0, "session_test"),
1642 attach_args.api_client_index = dummy_server_api_index;
1643 error = vnet_application_attach (&attach_args);
1644 SESSION_TEST ((error == 0), "server attachment should work");
1645 server_index = attach_args.app_index;
1649 unformat_init_string (&tmp_input, show_listeners,
1650 strlen (show_listeners));
1651 vlib_cli_input (vm, &tmp_input, 0, 0);
1652 unformat_init_string (&tmp_input, show_local_listeners,
1653 strlen (show_local_listeners));
1654 vlib_cli_input (vm, &tmp_input, 0, 0);
1657 tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
1658 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1659 SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
1661 s = listen_session_get (tc->s_index);
1662 SESSION_TEST ((s->app_index == server_index), "lookup should return"
1665 tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
1666 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1667 SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
1670 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1671 SESSION_TEST ((app_index == server_index), "local session endpoint lookup"
1674 vnet_app_detach_args_t detach_args = {
1675 .app_index = server_index,
1676 .api_client_index = ~0,
1678 vnet_application_detach (&detach_args);
1682 unformat_init_string (&tmp_input, show_listeners,
1683 strlen (show_listeners));
1684 vlib_cli_input (vm, &tmp_input, 0, 0);
1685 unformat_init_string (&tmp_input, show_local_listeners,
1686 strlen (show_local_listeners));
1687 vlib_cli_input (vm, &tmp_input, 0, 0);
1690 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1691 SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
1692 "local session endpoint lookup should not work after detach");
1694 unformat_free (&tmp_input);
1695 vec_free (attach_args.name);
1700 wait_for_event (svm_msg_q_t * mq, int fd, int epfd, u8 use_eventfd)
1704 svm_msg_q_lock (mq);
1705 while (svm_msg_q_is_empty (mq))
1706 svm_msg_q_wait (mq);
1710 int __clib_unused n_read, rv;
1711 struct epoll_event ep_evt;
1716 rv = epoll_wait (epfd, &ep_evt, 1, -1);
1719 ST_DBG ("epoll error");
1722 else if (rv > 0 && (ep_evt.events & EPOLLIN))
1724 n_read = read (fd, &buf, sizeof (buf));
1729 if (!svm_msg_q_is_empty (mq))
1731 svm_msg_q_lock (mq);
1739 session_test_mq (vlib_main_t * vm, unformat_input_t * input)
1741 int error, __clib_unused verbose, use_eventfd = 0;
1742 u64 i, n_test_msgs = 1 << 10, *counter;
1743 u64 options[APP_OPTIONS_N_OPTIONS];
1744 int epfd = -1, rv, prod_fd = -1;
1745 svm_fifo_t *rx_fifo, *tx_fifo;
1746 vl_api_registration_t *reg;
1747 struct epoll_event ep_evt;
1748 u32 app_index, api_index;
1749 u32 fifo_segment_index;
1750 app_worker_t *app_wrk;
1751 segment_manager_t *sm;
1752 svm_msg_q_msg_t msg;
1760 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1762 if (unformat (input, "verbose"))
1764 else if (unformat (input, "%d", &n_test_msgs))
1766 else if (unformat (input, "use-eventfd"))
1770 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1776 q = clib_mem_alloc (sizeof (*q));
1777 api_index = vl_api_memclnt_create_internal ("session_mq_test_api", q);
1779 clib_memset (options, 0, sizeof (options));
1780 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1781 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1782 options[APP_OPTIONS_EVT_QUEUE_SIZE] = 2048;
1784 reg = vl_api_client_index_to_registration (api_index);
1785 /* Shut up coverity */
1788 if (!session_main.evt_qs_use_memfd_seg)
1789 reg->clib_file_index = VL_API_INVALID_FI;
1791 vnet_app_attach_args_t attach_args = {
1792 .api_client_index = api_index,
1795 .session_cb_vft = &dummy_session_cbs,
1796 .name = format (0, "session_mq_test"),
1798 error = vnet_application_attach (&attach_args);
1799 SESSION_TEST ((error == 0), "server attachment should work");
1801 app_index = attach_args.app_index;
1803 app = application_get (app_index);
1804 app_wrk = application_get_worker (app, 0);
1805 mq = app_wrk->event_queue;
1808 svm_msg_q_alloc_producer_eventfd (mq);
1809 svm_msg_q_alloc_consumer_eventfd (mq);
1810 prod_fd = svm_msg_q_get_producer_eventfd (mq);
1811 SESSION_TEST (prod_fd != -1, "mq producer eventd valid %u", prod_fd);
1814 sm = app_worker_get_or_alloc_connect_segment_manager (app_wrk);
1815 segment_manager_alloc_session_fifos (sm, &rx_fifo, &tx_fifo,
1816 &fifo_segment_index);
1817 s.rx_fifo = rx_fifo;
1818 s.tx_fifo = tx_fifo;
1819 s.session_state = SESSION_STATE_READY;
1820 counter = (u64 *) rx_fifo->data;
1821 start = vlib_time_now (vm);
1825 SESSION_TEST (0, "fork failed");
1831 epfd = epoll_create1 (0);
1832 SESSION_TEST (epfd != -1, "epfd created");
1833 ep_evt.events = EPOLLIN;
1834 ep_evt.data.u64 = prod_fd;
1835 rv = epoll_ctl (epfd, EPOLL_CTL_ADD, prod_fd, &ep_evt);
1836 SESSION_TEST (rv == 0, "epoll returned %d", rv);
1839 for (i = 0; i < n_test_msgs; i++)
1841 wait_for_event (mq, prod_fd, epfd, use_eventfd);
1842 svm_msg_q_sub_w_lock (mq, &msg);
1843 svm_msg_q_free_msg (mq, &msg);
1844 svm_msg_q_unlock (mq);
1845 *counter = *counter + 1;
1846 svm_fifo_unset_event (rx_fifo);
1852 ST_DBG ("client pid %u", pid);
1853 for (i = 0; i < n_test_msgs; i++)
1855 while (svm_fifo_has_event (rx_fifo))
1857 app_worker_lock_and_send_event (app_wrk, &s, SESSION_IO_EVT_RX);
1861 diff = vlib_time_now (vm) - start;
1862 ST_DBG ("done %u events in %.2f sec: %f evts/s", *counter,
1863 diff, *counter / diff);
1865 vnet_app_detach_args_t detach_args = {
1866 .app_index = app_index,
1867 .api_client_index = ~0,
1869 vnet_application_detach (&detach_args);
1873 static clib_error_t *
1874 session_test (vlib_main_t * vm,
1875 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
1879 vnet_session_enable_disable (vm, 1);
1881 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1883 if (unformat (input, "basic"))
1884 res = session_test_basic (vm, input);
1885 else if (unformat (input, "namespace"))
1886 res = session_test_namespace (vm, input);
1887 else if (unformat (input, "rules-table"))
1888 res = session_test_rule_table (vm, input);
1889 else if (unformat (input, "rules"))
1890 res = session_test_rules (vm, input);
1891 else if (unformat (input, "proxy"))
1892 res = session_test_proxy (vm, input);
1893 else if (unformat (input, "endpt-cfg"))
1894 res = session_test_endpoint_cfg (vm, input);
1895 else if (unformat (input, "mq"))
1896 res = session_test_mq (vm, input);
1897 else if (unformat (input, "all"))
1899 if ((res = session_test_basic (vm, input)))
1901 if ((res = session_test_namespace (vm, input)))
1903 if ((res = session_test_rule_table (vm, input)))
1905 if ((res = session_test_rules (vm, input)))
1907 if ((res = session_test_proxy (vm, input)))
1909 if ((res = session_test_endpoint_cfg (vm, input)))
1911 if ((res = session_test_mq (vm, input)))
1920 return clib_error_return (0, "Session unit test failed");
1925 VLIB_CLI_COMMAND (tcp_test_command, static) =
1927 .path = "test session",
1928 .short_help = "internal session unit tests",
1929 .function = session_test,
1934 * fd.io coding-style-patch-verification: ON
1937 * eval: (c-set-style "gnu")