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, session_error_t err)
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); */
162 vnet_sw_interface_set_flags (vnet_get_main (), sw_if_index, 0);
166 session_test_basic (vlib_main_t * vm, unformat_input_t * input)
168 session_endpoint_cfg_t server_sep = SESSION_ENDPOINT_CFG_NULL;
169 u64 options[APP_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle;
173 clib_memset (options, 0, sizeof (options));
174 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
175 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
176 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
177 vnet_app_attach_args_t attach_args = {
178 .api_client_index = ~0,
181 .session_cb_vft = &dummy_session_cbs,
182 .name = format (0, "session_test"),
185 error = vnet_application_attach (&attach_args);
186 SESSION_TEST ((error == 0), "app attached");
187 server_index = attach_args.app_index;
188 vec_free (attach_args.name);
190 server_sep.is_ip4 = 1;
191 vnet_listen_args_t bind_args = {
192 .sep_ext = server_sep,
197 bind_args.app_index = server_index;
198 error = vnet_listen (&bind_args);
199 SESSION_TEST ((error == 0), "server bind4 should work");
200 bind4_handle = bind_args.handle;
202 error = vnet_listen (&bind_args);
203 SESSION_TEST ((error != 0), "double server bind4 should not work");
205 bind_args.sep.is_ip4 = 0;
206 error = vnet_listen (&bind_args);
207 SESSION_TEST ((error == 0), "server bind6 should work");
208 bind6_handle = bind_args.handle;
210 error = vnet_listen (&bind_args);
211 SESSION_TEST ((error != 0), "double server bind6 should not work");
213 vnet_unlisten_args_t unbind_args = {
214 .handle = bind4_handle,
215 .app_index = server_index,
217 error = vnet_unlisten (&unbind_args);
218 SESSION_TEST ((error == 0), "unbind4 should work");
220 unbind_args.handle = bind6_handle;
221 error = vnet_unlisten (&unbind_args);
222 SESSION_TEST ((error == 0), "unbind6 should work");
224 vnet_app_detach_args_t detach_args = {
225 .app_index = server_index,
226 .api_client_index = ~0,
228 vnet_application_detach (&detach_args);
233 session_add_del_route_via_lookup_in_table (u32 in_table_id, u32 via_table_id,
234 ip4_address_t * ip, u8 mask,
237 fib_route_path_t *rpaths = 0, *rpath;
238 u32 in_fib_index, via_fib_index;
240 fib_prefix_t prefix = {
241 .fp_addr.ip4.as_u32 = ip->as_u32,
243 .fp_proto = FIB_PROTOCOL_IP4,
246 via_fib_index = fib_table_find (FIB_PROTOCOL_IP4, via_table_id);
247 if (via_fib_index == ~0)
249 clib_warning ("couldn't resolve via table id to index");
252 in_fib_index = fib_table_find (FIB_PROTOCOL_IP4, in_table_id);
253 if (in_fib_index == ~0)
255 clib_warning ("couldn't resolve in table id to index");
259 vec_add2 (rpaths, rpath, 1);
260 clib_memset (rpath, 0, sizeof (*rpath));
261 rpath->frp_weight = 1;
262 rpath->frp_fib_index = via_fib_index;
263 rpath->frp_proto = DPO_PROTO_IP4;
264 rpath->frp_sw_if_index = ~0;
265 rpath->frp_flags |= FIB_ROUTE_PATH_DEAG;
268 fib_table_entry_path_add2 (in_fib_index, &prefix, FIB_SOURCE_CLI,
269 FIB_ENTRY_FLAG_NONE, rpath);
271 fib_table_entry_path_remove2 (in_fib_index, &prefix, FIB_SOURCE_CLI,
277 session_test_endpoint_cfg (vlib_main_t * vm, unformat_input_t * input)
279 session_endpoint_cfg_t client_sep = SESSION_ENDPOINT_CFG_NULL;
280 u32 server_index, client_index, sw_if_index[2], tries = 0;
281 u64 options[APP_OPTIONS_N_OPTIONS], dummy_secret = 1234;
282 u16 dummy_server_port = 1234, dummy_client_port = 5678;
283 session_endpoint_cfg_t server_sep = SESSION_ENDPOINT_CFG_NULL;
284 ip4_address_t intf_addr[3];
285 transport_connection_t *tc;
291 * Create the loopbacks
293 intf_addr[0].as_u32 = clib_host_to_net_u32 (0x01010101),
294 session_create_lookpback (0, &sw_if_index[0], &intf_addr[0]);
296 intf_addr[1].as_u32 = clib_host_to_net_u32 (0x02020202),
297 session_create_lookpback (1, &sw_if_index[1], &intf_addr[1]);
299 session_add_del_route_via_lookup_in_table (0, 1, &intf_addr[1], 32,
301 session_add_del_route_via_lookup_in_table (1, 0, &intf_addr[0], 32,
307 appns_id = format (0, "appns1");
308 vnet_app_namespace_add_del_args_t ns_args = {
310 .secret = dummy_secret,
311 .sw_if_index = sw_if_index[1],
315 error = vnet_app_namespace_add_del (&ns_args);
316 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
319 * Attach client/server
321 clib_memset (options, 0, sizeof (options));
322 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
323 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
325 vnet_app_attach_args_t attach_args = {
326 .api_client_index = ~0,
329 .session_cb_vft = &dummy_session_cbs,
330 .name = format (0, "session_test_client"),
333 error = vnet_application_attach (&attach_args);
334 SESSION_TEST ((error == 0), "client app attached");
335 client_index = attach_args.app_index;
336 vec_free (attach_args.name);
338 attach_args.name = format (0, "session_test_server");
339 attach_args.namespace_id = appns_id;
340 attach_args.options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
341 error = vnet_application_attach (&attach_args);
342 SESSION_TEST ((error == 0), "server app attached: %U", format_clib_error,
344 vec_free (attach_args.name);
345 server_index = attach_args.app_index;
347 server_sep.is_ip4 = 1;
348 server_sep.port = dummy_server_port;
349 vnet_listen_args_t bind_args = {
350 .sep_ext = server_sep,
351 .app_index = server_index,
353 error = vnet_listen (&bind_args);
354 SESSION_TEST ((error == 0), "server bind should work");
357 * Connect and force lcl ip
359 client_sep.is_ip4 = 1;
360 client_sep.ip.ip4.as_u32 = clib_host_to_net_u32 (0x02020202);
361 client_sep.port = dummy_server_port;
362 client_sep.peer.is_ip4 = 1;
363 client_sep.peer.ip.ip4.as_u32 = clib_host_to_net_u32 (0x01010101);
364 client_sep.peer.port = dummy_client_port;
365 client_sep.transport_proto = TRANSPORT_PROTO_TCP;
367 vnet_connect_args_t connect_args = {
368 .sep_ext = client_sep,
369 .app_index = client_index,
372 connected_session_index = connected_session_thread = ~0;
373 accepted_session_index = accepted_session_thread = ~0;
374 error = vnet_connect (&connect_args);
375 SESSION_TEST ((error == 0), "connect should work");
377 /* wait for stuff to happen */
378 while (connected_session_index == ~0 && ++tries < 100)
379 vlib_process_suspend (vm, 100e-3);
380 clib_warning ("waited %.1f seconds for connections", tries / 10.0);
381 SESSION_TEST ((connected_session_index != ~0), "session should exist");
382 SESSION_TEST ((connected_session_thread != ~0), "thread should exist");
383 SESSION_TEST ((accepted_session_index != ~0), "session should exist");
384 SESSION_TEST ((accepted_session_thread != ~0), "thread should exist");
385 s = session_get (connected_session_index, connected_session_thread);
386 tc = session_get_transport (s);
387 SESSION_TEST ((tc != 0), "transport should exist");
388 SESSION_TEST ((memcmp (&tc->lcl_ip, &client_sep.peer.ip,
389 sizeof (tc->lcl_ip)) == 0), "ips should be equal");
390 SESSION_TEST ((tc->lcl_port == dummy_client_port), "ports should be equal");
392 /* These sessions, because of the way they're established are pinned to
393 * main thread, even when we have workers and we avoid polling main thread,
394 * i.e., we can't cleanup pending disconnects, so force cleanup for both
396 session_transport_cleanup (s);
397 s = session_get (accepted_session_index, accepted_session_thread);
398 session_transport_cleanup (s);
400 vnet_app_detach_args_t detach_args = {
401 .app_index = server_index,
402 .api_client_index = ~0,
404 vnet_application_detach (&detach_args);
405 detach_args.app_index = client_index;
406 vnet_application_detach (&detach_args);
408 /* Allow the disconnects to finish before removing the routes. */
409 vlib_process_suspend (vm, 10e-3);
411 session_add_del_route_via_lookup_in_table (0, 1, &intf_addr[1], 32,
413 session_add_del_route_via_lookup_in_table (1, 0, &intf_addr[0], 32,
416 session_delete_loopback (sw_if_index[0]);
417 session_delete_loopback (sw_if_index[1]);
422 session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
424 u64 options[APP_OPTIONS_N_OPTIONS], dummy_secret = 1234;
425 u32 server_index, server_st_index, server_local_st_index;
426 u32 dummy_port = 1234, client_index, server_wrk_index;
427 u32 dummy_api_context = 4321, dummy_client_api_index = ~0;
428 u32 dummy_server_api_index = ~0, sw_if_index = 0;
429 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
430 session_endpoint_t client_sep = SESSION_ENDPOINT_NULL;
431 session_endpoint_t intf_sep = SESSION_ENDPOINT_NULL;
432 u8 *ns_id, *server_name, *client_name;
433 app_namespace_t *app_ns;
434 application_t *server;
439 ns_id = format (0, "appns1");
440 server_name = format (0, "session_test");
441 client_name = format (0, "session_test_client");
443 server_sep.is_ip4 = 1;
444 server_sep.port = dummy_port;
445 client_sep.is_ip4 = 1;
446 client_sep.port = dummy_port;
447 clib_memset (options, 0, sizeof (options));
449 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
450 vnet_app_attach_args_t attach_args = {
451 .api_client_index = ~0,
454 .session_cb_vft = &dummy_session_cbs,
458 vnet_listen_args_t bind_args = {
463 vnet_connect_args_t connect_args = {
467 clib_memcpy (&connect_args.sep, &client_sep, sizeof (client_sep));
469 vnet_unlisten_args_t unbind_args = {
470 .handle = bind_args.handle,
474 vnet_app_detach_args_t detach_args = {
476 .api_client_index = ~0,
479 ip4_address_t intf_addr = {
480 .as_u32 = clib_host_to_net_u32 (0x07000105),
483 intf_sep.ip.ip4 = intf_addr;
485 intf_sep.port = dummy_port;
488 * Insert namespace and lookup
491 vnet_app_namespace_add_del_args_t ns_args = {
493 .secret = dummy_secret,
494 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
497 error = vnet_app_namespace_add_del (&ns_args);
498 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
500 app_ns = app_namespace_get_from_id (ns_id);
501 SESSION_TEST ((app_ns != 0), "should find ns %v status", ns_id);
502 SESSION_TEST ((app_ns->ns_secret == dummy_secret), "secret should be %d",
504 SESSION_TEST ((app_ns->sw_if_index == APP_NAMESPACE_INVALID_INDEX),
505 "sw_if_index should be invalid");
508 * Try application attach with wrong secret
511 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
512 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
513 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret - 1;
514 attach_args.namespace_id = ns_id;
515 attach_args.api_client_index = dummy_server_api_index;
517 error = vnet_application_attach (&attach_args);
518 SESSION_TEST ((error != 0), "app attachment should fail");
519 SESSION_TEST ((error == VNET_API_ERROR_APP_WRONG_NS_SECRET),
520 "code should be wrong ns secret: %d", error);
523 * Attach server with global default scope
525 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
526 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
527 options[APP_OPTIONS_NAMESPACE_SECRET] = 0;
528 attach_args.namespace_id = 0;
529 attach_args.api_client_index = dummy_server_api_index;
530 error = vnet_application_attach (&attach_args);
531 SESSION_TEST ((error == 0), "server attachment should work");
532 server_index = attach_args.app_index;
533 server = application_get (server_index);
534 server_wrk_index = application_get_default_worker (server)->wrk_index;
535 SESSION_TEST ((server->ns_index == 0),
536 "server should be in the default ns");
538 bind_args.app_index = server_index;
539 error = vnet_listen (&bind_args);
540 SESSION_TEST ((error == 0), "server bind should work");
542 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
543 s = session_lookup_listener (server_st_index, &server_sep);
544 SESSION_TEST ((s != 0), "listener should exist in global table");
545 SESSION_TEST ((s->app_wrk_index == server_wrk_index), "app_index should be"
546 " that of the server");
547 server_local_st_index = application_local_session_table (server);
548 SESSION_TEST ((server_local_st_index == APP_INVALID_INDEX),
549 "server shouldn't have access to local table");
551 unbind_args.app_index = server_index;
552 unbind_args.handle = bind_args.handle;
553 error = vnet_unlisten (&unbind_args);
554 SESSION_TEST ((error == 0), "unbind should work");
556 s = session_lookup_listener (server_st_index, &server_sep);
557 SESSION_TEST ((s == 0), "listener should not exist in global table");
559 detach_args.app_index = server_index;
560 vnet_application_detach (&detach_args);
563 * Attach server with local and global scope
565 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
566 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
567 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
568 attach_args.namespace_id = ns_id;
569 attach_args.api_client_index = dummy_server_api_index;
570 error = vnet_application_attach (&attach_args);
571 SESSION_TEST ((error == 0), "server attachment should work");
572 server_index = attach_args.app_index;
573 server = application_get (server_index);
574 server_wrk_index = application_get_default_worker (server)->wrk_index;
575 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
576 "server should be in the right ns");
578 bind_args.app_index = server_index;
579 error = vnet_listen (&bind_args);
580 SESSION_TEST ((error == 0), "bind should work");
581 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
582 s = session_lookup_listener (server_st_index, &server_sep);
583 SESSION_TEST ((s != 0), "listener should exist in global table");
584 SESSION_TEST ((s->app_wrk_index == server_wrk_index), "app_index should be"
585 " that of the server");
586 server_local_st_index = application_local_session_table (server);
587 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
588 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
589 "listener should exist in local table");
592 * Try client connect with 1) local scope 2) global scope
594 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
595 attach_args.name = client_name;
596 attach_args.api_client_index = dummy_client_api_index;
597 error = vnet_application_attach (&attach_args);
598 SESSION_TEST ((error == 0), "client attachment should work");
599 client_index = attach_args.app_index;
600 connect_args.api_context = dummy_api_context;
601 connect_args.app_index = client_index;
602 error = vnet_connect (&connect_args);
603 SESSION_TEST ((error != 0), "client connect should return error code");
604 SESSION_TEST ((error == SESSION_E_INVALID_RMT_IP),
605 "error code should be invalid value (zero ip)");
606 SESSION_TEST ((dummy_segment_count == 0),
607 "shouldn't have received request to map new segment");
608 connect_args.sep.ip.ip4.as_u8[0] = 127;
609 error = vnet_connect (&connect_args);
610 SESSION_TEST ((error == 0), "client connect should not return error code");
611 SESSION_TEST ((dummy_segment_count == 1),
612 "should've received request to map new segment");
613 SESSION_TEST ((dummy_accept == 1), "should've received accept request");
614 detach_args.app_index = client_index;
615 vnet_application_detach (&detach_args);
617 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
618 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
619 attach_args.api_client_index = dummy_client_api_index;
620 error = vnet_application_attach (&attach_args);
621 SESSION_TEST ((error == 0), "client attachment should work");
622 error = vnet_connect (&connect_args);
623 SESSION_TEST ((error != 0), "client connect should return error code");
624 SESSION_TEST ((error == SESSION_E_NOINTF),
625 "error code should be connect (nothing in local scope)");
626 detach_args.app_index = client_index;
627 vnet_application_detach (&detach_args);
630 * Unbind and detach server and then re-attach with local scope only
632 unbind_args.handle = bind_args.handle;
633 unbind_args.app_index = server_index;
634 error = vnet_unlisten (&unbind_args);
635 SESSION_TEST ((error == 0), "unbind should work");
637 s = session_lookup_listener (server_st_index, &server_sep);
638 SESSION_TEST ((s == 0), "listener should not exist in global table");
639 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
640 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
641 "listener should not exist in local table");
643 detach_args.app_index = server_index;
644 vnet_application_detach (&detach_args);
646 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
647 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
648 attach_args.api_client_index = dummy_server_api_index;
649 attach_args.name = server_name;
650 error = vnet_application_attach (&attach_args);
651 SESSION_TEST ((error == 0), "app attachment should work");
652 server_index = attach_args.app_index;
653 server = application_get (server_index);
654 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
655 "app should be in the right ns");
657 bind_args.app_index = server_index;
658 error = vnet_listen (&bind_args);
659 SESSION_TEST ((error == 0), "bind should work");
661 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
662 s = session_lookup_listener (server_st_index, &server_sep);
663 SESSION_TEST ((s == 0), "listener should not exist in global table");
664 server_local_st_index = application_local_session_table (server);
665 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
666 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
667 "listener should exist in local table");
669 unbind_args.handle = bind_args.handle;
670 error = vnet_unlisten (&unbind_args);
671 SESSION_TEST ((error == 0), "unbind should work");
673 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
674 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
675 "listener should not exist in local table");
678 * Client attach + connect in default ns with local scope
680 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
681 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
682 attach_args.namespace_id = 0;
683 attach_args.api_client_index = dummy_client_api_index;
684 attach_args.name = client_name;
685 vnet_application_attach (&attach_args);
686 error = vnet_connect (&connect_args);
687 SESSION_TEST ((error != 0), "client connect should return error code");
688 SESSION_TEST ((error == SESSION_E_NOROUTE),
689 "error code should be noroute (not in same ns)");
690 detach_args.app_index = client_index;
691 vnet_application_detach (&detach_args);
696 detach_args.app_index = server_index;
697 vnet_application_detach (&detach_args);
700 * Create loopback interface
702 session_create_lookpback (0, &sw_if_index, &intf_addr);
705 * Update namespace with interface
707 ns_args.sw_if_index = sw_if_index;
708 error = vnet_app_namespace_add_del (&ns_args);
709 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
712 * Attach server with local and global scope
714 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
715 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
716 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
717 attach_args.namespace_id = ns_id;
718 attach_args.api_client_index = dummy_server_api_index;
719 attach_args.name = server_name;
720 error = vnet_application_attach (&attach_args);
721 SESSION_TEST ((error == 0), "server attachment should work");
722 server_index = attach_args.app_index;
723 server = application_get (server_index);
724 server_wrk_index = application_get_default_worker (server)->wrk_index;
726 bind_args.app_index = server_index;
727 error = vnet_listen (&bind_args);
728 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
729 s = session_lookup_listener (server_st_index, &server_sep);
730 SESSION_TEST ((s == 0), "zero listener should not exist in global table");
732 s = session_lookup_listener (server_st_index, &intf_sep);
733 SESSION_TEST ((s != 0), "intf listener should exist in global table");
734 SESSION_TEST ((s->app_wrk_index == server_wrk_index), "app_index should be "
735 "that of the server");
736 server_local_st_index = application_local_session_table (server);
737 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
738 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
739 "zero listener should exist in local table");
740 detach_args.app_index = server_index;
741 vnet_application_detach (&detach_args);
746 vec_free (server_name);
747 vec_free (client_name);
749 session_delete_loopback (sw_if_index);
754 session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
756 session_rules_table_t _srt, *srt = &_srt;
757 u16 lcl_port = 1234, rmt_port = 4321;
758 u32 action_index = 1, res;
759 ip4_address_t lcl_lkup, rmt_lkup;
760 int verbose = 0, error;
762 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
764 if (unformat (input, "verbose"))
768 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
774 clib_memset (srt, 0, sizeof (*srt));
775 session_rules_table_init (srt);
777 ip4_address_t lcl_ip = {
778 .as_u32 = clib_host_to_net_u32 (0x01020304),
780 ip4_address_t rmt_ip = {
781 .as_u32 = clib_host_to_net_u32 (0x05060708),
783 ip4_address_t lcl_ip2 = {
784 .as_u32 = clib_host_to_net_u32 (0x02020202),
786 ip4_address_t rmt_ip2 = {
787 .as_u32 = clib_host_to_net_u32 (0x06060606),
789 ip4_address_t lcl_ip3 = {
790 .as_u32 = clib_host_to_net_u32 (0x03030303),
792 ip4_address_t rmt_ip3 = {
793 .as_u32 = clib_host_to_net_u32 (0x07070707),
795 fib_prefix_t lcl_pref = {
796 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
798 .fp_proto = FIB_PROTOCOL_IP4,
800 fib_prefix_t rmt_pref = {
801 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
803 .fp_proto = FIB_PROTOCOL_IP4,
806 session_rule_table_add_del_args_t args = {
809 .lcl_port = lcl_port,
810 .rmt_port = rmt_port,
811 .action_index = action_index++,
814 error = session_rules_table_add_del (srt, &args);
815 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
819 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
820 SESSION_TEST ((res == 1),
821 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
825 * 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
827 args.lcl.fp_addr.ip4 = lcl_ip;
828 args.lcl.fp_len = 24;
829 args.action_index = action_index++;
830 error = session_rules_table_add_del (srt, &args);
831 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/16 4321 action %d",
833 args.rmt.fp_addr.ip4 = rmt_ip;
834 args.rmt.fp_len = 24;
835 args.action_index = action_index++;
836 error = session_rules_table_add_del (srt, &args);
837 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/24 4321 action %d",
841 * 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
843 args.lcl.fp_addr.ip4 = lcl_ip2;
844 args.lcl.fp_len = 24;
845 args.rmt.fp_addr.ip4 = rmt_ip2;
846 args.rmt.fp_len = 16;
847 args.action_index = action_index++;
848 error = session_rules_table_add_del (srt, &args);
849 SESSION_TEST ((error == 0), "Add 2.2.2.2/24 1234 6.6.6.6/16 4321 action %d",
851 args.lcl.fp_addr.ip4 = lcl_ip3;
852 args.rmt.fp_addr.ip4 = rmt_ip3;
853 args.action_index = action_index++;
854 error = session_rules_table_add_del (srt, &args);
855 SESSION_TEST ((error == 0), "Add 3.3.3.3/24 1234 7.7.7.7/16 4321 action %d",
859 * Add again 3.3.3.3/24 1234 7.7.7.7/16 4321
861 args.lcl.fp_addr.ip4 = lcl_ip3;
862 args.rmt.fp_addr.ip4 = rmt_ip3;
863 args.action_index = action_index++;
864 error = session_rules_table_add_del (srt, &args);
865 SESSION_TEST ((error == 0), "overwrite 3.3.3.3/24 1234 7.7.7.7/16 4321 "
866 "action %d", action_index - 1);
869 * 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
870 * and 3.3.3.3 1234 7.7.7.7 4321
873 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
874 SESSION_TEST ((res == 3),
875 "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
878 lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
879 rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
881 session_rules_table_lookup4 (srt, &lcl_lkup,
882 &rmt_lkup, lcl_port, rmt_port);
883 SESSION_TEST ((res == 1),
884 "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
888 session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
889 SESSION_TEST ((res == 6),
890 "Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
891 "should be 6 (updated): %d", res);
894 * Add 1.2.3.4/24 * 5.6.7.8/24 *
895 * Lookup 1.2.3.4 1234 5.6.7.8 4321 and 1.2.3.4 1235 5.6.7.8 4321
897 args.lcl.fp_addr.ip4 = lcl_ip;
898 args.rmt.fp_addr.ip4 = rmt_ip;
899 args.lcl.fp_len = 24;
900 args.rmt.fp_len = 24;
903 args.action_index = action_index++;
904 error = session_rules_table_add_del (srt, &args);
905 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
908 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
909 SESSION_TEST ((res == 7),
910 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
911 " be 7 (lpm dst): %d", res);
913 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
914 lcl_port + 1, rmt_port);
915 SESSION_TEST ((res == 7),
916 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
920 * Del 1.2.3.4/24 * 5.6.7.8/24 *
921 * Add 1.2.3.4/16 * 5.6.7.8/16 * and 1.2.3.4/24 1235 5.6.7.8/24 4321
922 * Lookup 1.2.3.4 1234 5.6.7.8 4321, 1.2.3.4 1235 5.6.7.8 4321 and
923 * 1.2.3.4 1235 5.6.7.8 4322
926 error = session_rules_table_add_del (srt, &args);
927 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 * 5.6.7.8/24 *");
929 args.lcl.fp_addr.ip4 = lcl_ip;
930 args.rmt.fp_addr.ip4 = rmt_ip;
931 args.lcl.fp_len = 16;
932 args.rmt.fp_len = 16;
935 args.action_index = action_index++;
937 error = session_rules_table_add_del (srt, &args);
938 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 * action %d",
941 args.lcl.fp_addr.ip4 = lcl_ip;
942 args.rmt.fp_addr.ip4 = rmt_ip;
943 args.lcl.fp_len = 24;
944 args.rmt.fp_len = 24;
945 args.lcl_port = lcl_port + 1;
946 args.rmt_port = rmt_port;
947 args.action_index = action_index++;
949 error = session_rules_table_add_del (srt, &args);
950 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1235 5.6.7.8/24 4321 action %d",
954 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
957 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
958 SESSION_TEST ((res == 3),
959 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
962 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
963 lcl_port + 1, rmt_port);
964 SESSION_TEST ((res == 9),
965 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
968 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
969 lcl_port + 1, rmt_port + 1);
970 SESSION_TEST ((res == 8),
971 "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
975 * Delete 1.2.0.0/16 1234 5.6.0.0/16 4321 and 1.2.0.0/16 * 5.6.0.0/16 *
976 * Lookup 1.2.3.4 1234 5.6.7.8 4321
978 args.lcl_port = 1234;
979 args.rmt_port = 4321;
980 args.lcl.fp_len = 16;
981 args.rmt.fp_len = 16;
983 error = session_rules_table_add_del (srt, &args);
984 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
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",
994 error = session_rules_table_add_del (srt, &args);
995 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
997 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
998 SESSION_TEST ((res == 3),
999 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
1003 * Delete 1.2.3.4/24 1234 5.6.7.5/24
1005 args.lcl.fp_addr.ip4 = lcl_ip;
1006 args.rmt.fp_addr.ip4 = rmt_ip;
1007 args.lcl.fp_len = 24;
1008 args.rmt.fp_len = 24;
1009 args.lcl_port = 1234;
1010 args.rmt_port = 4321;
1012 error = session_rules_table_add_del (srt, &args);
1013 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
1015 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
1016 SESSION_TEST ((res == 2), "Action should be 2: %d", res);
1022 session_test_rules (vlib_main_t * vm, unformat_input_t * input)
1024 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
1025 u64 options[APP_OPTIONS_N_OPTIONS];
1026 u16 lcl_port = 1234, rmt_port = 4321;
1027 u32 server_index, server_index2;
1028 u32 dummy_server_api_index = ~0;
1029 transport_connection_t *tc;
1030 u32 dummy_port = 1111;
1031 u8 is_filtered = 0, *ns_id = format (0, "appns1");
1032 session_t *listener, *s;
1033 app_namespace_t *default_ns = app_namespace_get_default ();
1034 u32 local_ns_index = default_ns->local_table_index;
1036 app_namespace_t *app_ns;
1041 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1043 if (unformat (input, "verbose"))
1047 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1053 server_sep.is_ip4 = 1;
1054 server_sep.port = dummy_port;
1055 clib_memset (options, 0, sizeof (options));
1057 vnet_app_attach_args_t attach_args = {
1058 .api_client_index = ~0,
1061 .session_cb_vft = &dummy_session_cbs,
1062 .name = format (0, "session_test"),
1065 vnet_listen_args_t bind_args = {
1071 * Attach server with global and local default scope
1073 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
1074 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1075 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1076 attach_args.namespace_id = 0;
1077 attach_args.api_client_index = dummy_server_api_index;
1078 error = vnet_application_attach (&attach_args);
1079 SESSION_TEST ((error == 0), "server attached");
1080 server_index = attach_args.app_index;
1082 bind_args.app_index = server_index;
1083 error = vnet_listen (&bind_args);
1084 SESSION_TEST ((error == 0), "server bound to %U/%d", format_ip46_address,
1085 &server_sep.ip, 1, server_sep.port);
1086 al = app_listener_get_w_handle (bind_args.handle);
1087 listener = app_listener_get_session (al);
1088 ip4_address_t lcl_ip = {
1089 .as_u32 = clib_host_to_net_u32 (0x01020304),
1091 ip4_address_t rmt_ip = {
1092 .as_u32 = clib_host_to_net_u32 (0x05060708),
1094 fib_prefix_t lcl_pref = {
1095 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
1097 .fp_proto = FIB_PROTOCOL_IP4,
1099 fib_prefix_t rmt_pref = {
1100 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1102 .fp_proto = FIB_PROTOCOL_IP4,
1105 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1106 &rmt_pref.fp_addr.ip4, lcl_port,
1107 rmt_port, TRANSPORT_PROTO_TCP, 0,
1109 SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
1112 * Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action server_index
1114 session_rule_add_del_args_t args = {
1115 .table_args.lcl = lcl_pref,
1116 .table_args.rmt = rmt_pref,
1117 .table_args.lcl_port = lcl_port,
1118 .table_args.rmt_port = rmt_port,
1119 .table_args.action_index = server_index,
1120 .table_args.is_add = 1,
1123 error = vnet_session_rule_add_del (&args);
1124 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
1125 args.table_args.action_index);
1127 tc = session_lookup_connection4 (0, &lcl_pref.fp_addr.ip4,
1128 &rmt_pref.fp_addr.ip4, lcl_port, rmt_port,
1129 TRANSPORT_PROTO_TCP);
1130 SESSION_TEST ((tc->c_index == listener->connection_index),
1131 "optimized lookup should return the listener");
1132 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1133 &rmt_pref.fp_addr.ip4, lcl_port,
1134 rmt_port, TRANSPORT_PROTO_TCP, 0,
1136 SESSION_TEST ((tc->c_index == listener->connection_index),
1137 "lookup should return the listener");
1138 s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
1139 lcl_port, rmt_port, TRANSPORT_PROTO_TCP);
1140 SESSION_TEST ((s->connection_index == listener->connection_index),
1141 "safe lookup should return the listener");
1142 session_endpoint_t sep = {
1143 .ip = rmt_pref.fp_addr,
1146 .transport_proto = TRANSPORT_PROTO_TCP,
1148 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1149 SESSION_TEST ((handle != server_index), "local session endpoint lookup "
1150 "should not work (global scope)");
1152 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1153 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1154 rmt_port, TRANSPORT_PROTO_TCP, 0,
1156 SESSION_TEST ((tc == 0),
1157 "optimized lookup for wrong lcl port + 1 should not work");
1160 * Add 1.2.3.4/16 * 5.6.7.8/16 4321
1162 args.table_args.lcl_port = 0;
1163 args.scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
1164 error = vnet_session_rule_add_del (&args);
1165 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 4321 action %d",
1166 args.table_args.action_index);
1167 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1168 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1169 rmt_port, TRANSPORT_PROTO_TCP, 0,
1171 SESSION_TEST ((tc->c_index == listener->connection_index),
1172 "optimized lookup for lcl port + 1 should work");
1173 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1174 SESSION_TEST ((handle == server_index), "local session endpoint lookup "
1175 "should work (lcl ip was zeroed)");
1178 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
1180 args.table_args.lcl_port = 1234;
1181 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1182 args.table_args.lcl.fp_len = 30;
1183 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1184 args.table_args.rmt.fp_len = 30;
1185 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1186 error = vnet_session_rule_add_del (&args);
1187 SESSION_TEST ((error == 0), "Add 1.2.3.4/30 1234 5.6.7.8/30 4321 action %d",
1188 args.table_args.action_index);
1192 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1193 TRANSPORT_PROTO_TCP);
1194 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1195 TRANSPORT_PROTO_TCP);
1198 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1199 &rmt_pref.fp_addr.ip4, lcl_port,
1200 rmt_port, TRANSPORT_PROTO_TCP, 0,
1202 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
1203 "should fail (deny rule)");
1204 SESSION_TEST ((is_filtered == SESSION_LOOKUP_RESULT_FILTERED),
1205 "lookup should be filtered (deny)");
1207 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1208 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1209 "5.6.7.8/16 4321 in local table should return deny");
1211 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1212 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1213 rmt_port, TRANSPORT_PROTO_TCP, 0,
1215 SESSION_TEST ((tc->c_index == listener->connection_index),
1216 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should work");
1219 * "Mask" deny rule with more specific allow:
1220 * Add allow rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -3 (allow)
1222 args.table_args.is_add = 1;
1223 args.table_args.lcl_port = 1234;
1224 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1225 args.table_args.lcl.fp_len = 32;
1226 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1227 args.table_args.rmt.fp_len = 32;
1228 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1229 error = vnet_session_rule_add_del (&args);
1230 SESSION_TEST ((error == 0), "Add masking rule 1.2.3.4/30 1234 5.6.7.8/32 "
1231 "4321 action %d", args.table_args.action_index);
1234 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1235 &rmt_pref.fp_addr.ip4, lcl_port,
1236 rmt_port, TRANSPORT_PROTO_TCP, 0,
1238 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
1239 "should fail (allow without app)");
1240 SESSION_TEST ((is_filtered == 0), "lookup should NOT be filtered");
1242 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1243 SESSION_TEST ((handle == SESSION_INVALID_HANDLE), "lookup for 1.2.3.4/32 "
1244 "1234 5.6.7.8/32 4321 in local table should return invalid");
1248 vlib_cli_output (vm, "Local rules");
1249 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1250 TRANSPORT_PROTO_TCP);
1253 sep.ip.ip4.as_u32 += 1 << 24;
1254 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1255 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234"
1256 " 5.6.7.9/32 4321 in local table should return deny");
1258 vnet_connect_args_t connect_args = {
1259 .app_index = attach_args.app_index,
1262 clib_memcpy (&connect_args.sep, &sep, sizeof (sep));
1264 /* Try connecting */
1265 error = vnet_connect (&connect_args);
1266 SESSION_TEST ((error != 0), "connect should fail");
1267 SESSION_TEST ((error == SESSION_E_FILTERED), "connect should be filtered");
1269 sep.ip.ip4.as_u32 -= 1 << 24;
1272 * Delete masking rule: 1.2.3.4/32 1234 5.6.7.8/32 4321 allow
1274 args.table_args.is_add = 0;
1275 args.table_args.lcl_port = 1234;
1276 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1277 args.table_args.lcl.fp_len = 32;
1278 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1279 args.table_args.rmt.fp_len = 32;
1280 error = vnet_session_rule_add_del (&args);
1281 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 allow");
1285 * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
1287 args.table_args.is_add = 1;
1288 args.table_args.lcl_port = 0;
1289 args.table_args.lcl.fp_len = 0;
1290 args.table_args.rmt.fp_len = 16;
1291 args.table_args.action_index = -1;
1292 error = vnet_session_rule_add_del (&args);
1293 SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d",
1294 args.table_args.action_index);
1298 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1299 TRANSPORT_PROTO_TCP);
1300 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1301 TRANSPORT_PROTO_TCP);
1304 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1305 SESSION_TEST ((handle == SESSION_DROP_HANDLE),
1306 "local session endpoint lookup should return deny");
1309 * Delete 1.2.3.4/32 1234 5.6.7.8/32 4321 deny
1311 args.table_args.is_add = 0;
1312 args.table_args.lcl_port = 1234;
1313 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1314 args.table_args.lcl.fp_len = 30;
1315 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1316 args.table_args.rmt.fp_len = 30;
1317 error = vnet_session_rule_add_del (&args);
1318 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1320 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1321 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
1322 "local session endpoint lookup should return invalid");
1325 * Delete 0/0 * 5.6.7.8/16 4321, 1.2.3.4/16 * 5.6.7.8/16 4321 and
1326 * 1.2.3.4/16 1234 5.6.7.8/16 4321
1328 args.table_args.is_add = 0;
1329 args.table_args.lcl_port = 0;
1330 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1331 args.table_args.lcl.fp_len = 0;
1332 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1333 args.table_args.rmt.fp_len = 16;
1334 args.table_args.rmt_port = 4321;
1335 error = vnet_session_rule_add_del (&args);
1336 SESSION_TEST ((error == 0), "Del 0/0 * 5.6.7.8/16 4321");
1337 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1338 SESSION_TEST ((handle != server_index), "local session endpoint lookup "
1339 "should not work (removed)");
1341 args.table_args.is_add = 0;
1342 args.table_args.lcl = lcl_pref;
1344 args.table_args.is_add = 0;
1345 args.table_args.lcl_port = 0;
1346 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1347 args.table_args.lcl.fp_len = 16;
1348 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1349 args.table_args.rmt.fp_len = 16;
1350 args.table_args.rmt_port = 4321;
1351 error = vnet_session_rule_add_del (&args);
1352 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
1353 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1354 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1355 rmt_port, TRANSPORT_PROTO_TCP, 0,
1357 SESSION_TEST ((tc == 0),
1358 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should not "
1361 args.table_args.is_add = 0;
1362 args.table_args.lcl_port = 1234;
1363 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1364 args.table_args.lcl.fp_len = 16;
1365 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1366 args.table_args.rmt.fp_len = 16;
1367 args.table_args.rmt_port = 4321;
1368 error = vnet_session_rule_add_del (&args);
1369 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
1370 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1371 &rmt_pref.fp_addr.ip4, lcl_port,
1372 rmt_port, TRANSPORT_PROTO_TCP, 0,
1374 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should "
1375 "not work (del + deny)");
1377 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1378 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1379 &rmt_pref.fp_addr.ip4, lcl_port,
1380 rmt_port, TRANSPORT_PROTO_TCP, 0,
1382 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should"
1383 " not work (no-rule)");
1386 * Test tags. Add/overwrite/del rule with tag
1388 args.table_args.is_add = 1;
1389 args.table_args.lcl_port = 1234;
1390 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1391 args.table_args.lcl.fp_len = 16;
1392 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1393 args.table_args.rmt.fp_len = 16;
1394 args.table_args.rmt_port = 4321;
1395 args.table_args.tag = format (0, "test_rule");
1396 args.table_args.action_index = server_index;
1397 error = vnet_session_rule_add_del (&args);
1398 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 deny "
1402 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1403 TRANSPORT_PROTO_TCP);
1404 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1405 TRANSPORT_PROTO_TCP);
1407 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1408 &rmt_pref.fp_addr.ip4, lcl_port,
1409 rmt_port, TRANSPORT_PROTO_TCP, 0,
1411 SESSION_TEST ((tc->c_index == listener->connection_index),
1412 "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should work");
1414 vec_free (args.table_args.tag);
1415 args.table_args.lcl_port = 1234;
1416 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1417 args.table_args.lcl.fp_len = 16;
1418 args.table_args.tag = format (0, "test_rule_overwrite");
1419 error = vnet_session_rule_add_del (&args);
1420 SESSION_TEST ((error == 0),
1421 "Overwrite 1.2.3.4/16 1234 5.6.7.8/16 4321 deny tag test_rule"
1425 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1426 TRANSPORT_PROTO_TCP);
1427 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1428 TRANSPORT_PROTO_TCP);
1431 args.table_args.is_add = 0;
1432 args.table_args.lcl_port += 1;
1433 error = vnet_session_rule_add_del (&args);
1434 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny "
1435 "tag %v", args.table_args.tag);
1438 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1439 TRANSPORT_PROTO_TCP);
1440 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1441 TRANSPORT_PROTO_TCP);
1443 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1444 &rmt_pref.fp_addr.ip4, lcl_port,
1445 rmt_port, TRANSPORT_PROTO_TCP, 0,
1447 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/32 4321 should not"
1452 * Test local rules with multiple namespaces
1456 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1458 args.table_args.is_add = 1;
1459 args.table_args.lcl_port = 1234;
1460 args.table_args.rmt_port = 0;
1461 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1462 args.table_args.lcl.fp_len = 32;
1463 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1464 args.table_args.rmt.fp_len = 32;
1465 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1466 args.table_args.tag = 0;
1467 args.scope = SESSION_RULE_SCOPE_LOCAL;
1468 error = vnet_session_rule_add_del (&args);
1469 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
1470 args.table_args.action_index);
1472 * Add 'white' rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
1474 args.table_args.is_add = 1;
1475 args.table_args.lcl_port = 1234;
1476 args.table_args.rmt_port = 4321;
1477 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1478 args.table_args.lcl.fp_len = 32;
1479 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1480 args.table_args.rmt.fp_len = 32;
1481 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1482 error = vnet_session_rule_add_del (&args);
1486 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1487 TRANSPORT_PROTO_TCP);
1490 vnet_app_namespace_add_del_args_t ns_args = {
1493 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
1496 error = vnet_app_namespace_add_del (&ns_args);
1497 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d", error);
1498 app_ns = app_namespace_get_from_id (ns_id);
1500 attach_args.namespace_id = ns_id;
1501 attach_args.api_client_index = dummy_server_api_index;
1502 vec_free (attach_args.name);
1503 attach_args.name = format (0, "server_test2");
1504 error = vnet_application_attach (&attach_args);
1505 SESSION_TEST ((error == 0), "server2 attached");
1506 server_index2 = attach_args.app_index;
1509 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1511 args.table_args.lcl_port = 1234;
1512 args.table_args.rmt_port = 0;
1513 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1514 args.table_args.lcl.fp_len = 32;
1515 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1516 args.table_args.rmt.fp_len = 32;
1517 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1518 args.appns_index = app_namespace_index (app_ns);
1520 error = vnet_session_rule_add_del (&args);
1521 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d "
1522 "in test namespace", args.table_args.action_index);
1524 * Lookup default namespace
1526 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1527 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
1528 "lookup for 1.2.3.4/32 1234 5.6.7.8/32 4321 in local table "
1529 "should return allow (invalid)");
1532 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1533 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1534 "5.6.7.8/16 432*2* in local table should return deny");
1537 connect_args.app_index = server_index;
1538 clib_memcpy (&connect_args.sep, &sep, sizeof (sep));
1540 error = vnet_connect (&connect_args);
1541 SESSION_TEST ((error != 0), "connect should fail");
1542 SESSION_TEST ((error == SESSION_E_FILTERED), "connect should be filtered");
1545 * Lookup test namespace
1547 handle = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1548 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1549 "5.6.7.8/16 4321 in local table should return deny");
1551 connect_args.app_index = server_index;
1552 error = vnet_connect (&connect_args);
1553 SESSION_TEST ((error != 0), "connect should fail");
1554 SESSION_TEST ((error == SESSION_E_FILTERED), "connect should be filtered");
1556 args.table_args.is_add = 0;
1557 vnet_session_rule_add_del (&args);
1559 args.appns_index = 0;
1560 args.table_args.is_add = 0;
1561 vnet_session_rule_add_del (&args);
1563 args.table_args.rmt_port = 4321;
1564 vnet_session_rule_add_del (&args);
1568 vec_free (args.table_args.tag);
1569 vnet_app_detach_args_t detach_args = {
1570 .app_index = server_index,
1571 .api_client_index = ~0,
1573 vnet_application_detach (&detach_args);
1575 detach_args.app_index = server_index2;
1576 vnet_application_detach (&detach_args);
1579 vec_free (attach_args.name);
1584 session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
1586 u64 options[APP_OPTIONS_N_OPTIONS];
1587 char *show_listeners = "sh session listeners tcp verbose";
1588 char *show_local_listeners = "sh app ns table default";
1589 unformat_input_t tmp_input;
1590 u32 server_index, app_index;
1591 u32 dummy_server_api_index = ~0, sw_if_index = 0;
1594 transport_connection_t *tc;
1595 u16 lcl_port = 1234, rmt_port = 4321;
1596 app_namespace_t *app_ns;
1597 int verbose = 0, error = 0;
1599 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1601 if (unformat (input, "verbose"))
1605 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1611 ip4_address_t lcl_ip = {
1612 .as_u32 = clib_host_to_net_u32 (0x01020304),
1614 ip4_address_t rmt_ip = {
1615 .as_u32 = clib_host_to_net_u32 (0x05060708),
1617 fib_prefix_t rmt_pref = {
1618 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1620 .fp_proto = FIB_PROTOCOL_IP4,
1622 session_endpoint_t sep = {
1623 .ip = rmt_pref.fp_addr,
1626 .transport_proto = TRANSPORT_PROTO_TCP,
1630 * Create loopback interface
1632 session_create_lookpback (0, &sw_if_index, &lcl_ip);
1634 app_ns = app_namespace_get_default ();
1635 app_ns->sw_if_index = sw_if_index;
1637 clib_memset (options, 0, sizeof (options));
1638 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
1639 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
1640 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_IS_PROXY;
1641 options[APP_OPTIONS_PROXY_TRANSPORT] = 1 << TRANSPORT_PROTO_TCP;
1642 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1643 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1644 vnet_app_attach_args_t attach_args = {
1645 .api_client_index = ~0,
1648 .session_cb_vft = &dummy_session_cbs,
1649 .name = format (0, "session_test"),
1652 attach_args.api_client_index = dummy_server_api_index;
1653 error = vnet_application_attach (&attach_args);
1654 SESSION_TEST ((error == 0), "server attachment should work");
1655 server_index = attach_args.app_index;
1659 unformat_init_string (&tmp_input, show_listeners,
1660 strlen (show_listeners));
1661 vlib_cli_input (vm, &tmp_input, 0, 0);
1662 unformat_init_string (&tmp_input, show_local_listeners,
1663 strlen (show_local_listeners));
1664 vlib_cli_input (vm, &tmp_input, 0, 0);
1667 tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
1668 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1669 SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
1671 s = listen_session_get (tc->s_index);
1672 SESSION_TEST ((s->app_index == server_index), "lookup should return"
1675 tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
1676 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1677 SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
1680 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1681 SESSION_TEST ((app_index == server_index), "local session endpoint lookup"
1684 vnet_app_detach_args_t detach_args = {
1685 .app_index = server_index,
1686 .api_client_index = ~0,
1688 vnet_application_detach (&detach_args);
1692 unformat_init_string (&tmp_input, show_listeners,
1693 strlen (show_listeners));
1694 vlib_cli_input (vm, &tmp_input, 0, 0);
1695 unformat_init_string (&tmp_input, show_local_listeners,
1696 strlen (show_local_listeners));
1697 vlib_cli_input (vm, &tmp_input, 0, 0);
1700 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1701 SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
1702 "local session endpoint lookup should not work after detach");
1704 unformat_free (&tmp_input);
1705 vec_free (attach_args.name);
1706 session_delete_loopback (sw_if_index);
1711 wait_for_event (svm_msg_q_t * mq, int fd, int epfd, u8 use_eventfd)
1715 svm_msg_q_lock (mq);
1716 while (svm_msg_q_is_empty (mq))
1717 svm_msg_q_wait (mq);
1721 int __clib_unused n_read, rv;
1722 struct epoll_event ep_evt;
1727 rv = epoll_wait (epfd, &ep_evt, 1, -1);
1730 ST_DBG ("epoll error");
1733 else if (rv > 0 && (ep_evt.events & EPOLLIN))
1735 n_read = read (fd, &buf, sizeof (buf));
1740 if (!svm_msg_q_is_empty (mq))
1742 svm_msg_q_lock (mq);
1750 session_test_mq_speed (vlib_main_t * vm, unformat_input_t * input)
1752 int error, __clib_unused verbose, use_eventfd = 0;
1753 u64 i, n_test_msgs = 1 << 10, *counter;
1754 u64 options[APP_OPTIONS_N_OPTIONS];
1755 int epfd = -1, rv, prod_fd = -1;
1756 svm_fifo_t *rx_fifo, *tx_fifo;
1757 vl_api_registration_t *reg;
1758 struct epoll_event ep_evt;
1759 u32 app_index, api_index;
1760 app_worker_t *app_wrk;
1761 segment_manager_t *sm;
1762 svm_msg_q_msg_t msg;
1770 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1772 if (unformat (input, "verbose"))
1774 else if (unformat (input, "%d", &n_test_msgs))
1776 else if (unformat (input, "use-eventfd"))
1780 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1786 q = clib_mem_alloc (sizeof (*q));
1787 api_index = vl_api_memclnt_create_internal ("session_mq_test_api", q);
1789 clib_memset (options, 0, sizeof (options));
1790 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1791 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1792 options[APP_OPTIONS_EVT_QUEUE_SIZE] = 2048;
1794 reg = vl_api_client_index_to_registration (api_index);
1795 /* Shut up coverity */
1798 if (!session_main.evt_qs_use_memfd_seg)
1799 reg->clib_file_index = VL_API_INVALID_FI;
1801 vnet_app_attach_args_t attach_args = {
1802 .api_client_index = api_index,
1805 .session_cb_vft = &dummy_session_cbs,
1806 .name = format (0, "session_mq_test"),
1808 error = vnet_application_attach (&attach_args);
1809 SESSION_TEST ((error == 0), "server attachment should work");
1811 app_index = attach_args.app_index;
1813 app = application_get (app_index);
1814 app_wrk = application_get_worker (app, 0);
1815 mq = app_wrk->event_queue;
1818 svm_msg_q_alloc_producer_eventfd (mq);
1819 svm_msg_q_alloc_consumer_eventfd (mq);
1820 prod_fd = svm_msg_q_get_producer_eventfd (mq);
1821 SESSION_TEST (prod_fd != -1, "mq producer eventd valid %u", prod_fd);
1824 sm = app_worker_get_or_alloc_connect_segment_manager (app_wrk);
1825 segment_manager_alloc_session_fifos (sm, 0, &rx_fifo, &tx_fifo);
1826 s.rx_fifo = rx_fifo;
1827 s.tx_fifo = tx_fifo;
1828 s.session_state = SESSION_STATE_READY;
1829 counter = (u64 *) rx_fifo->head_chunk->data;
1830 start = vlib_time_now (vm);
1834 SESSION_TEST (0, "fork failed");
1840 epfd = epoll_create1 (0);
1841 SESSION_TEST (epfd != -1, "epfd created");
1842 ep_evt.events = EPOLLIN;
1843 ep_evt.data.u64 = prod_fd;
1844 rv = epoll_ctl (epfd, EPOLL_CTL_ADD, prod_fd, &ep_evt);
1845 SESSION_TEST (rv == 0, "epoll returned %d", rv);
1848 for (i = 0; i < n_test_msgs; i++)
1850 wait_for_event (mq, prod_fd, epfd, use_eventfd);
1851 svm_msg_q_sub_w_lock (mq, &msg);
1852 svm_msg_q_free_msg (mq, &msg);
1853 svm_msg_q_unlock (mq);
1854 *counter = *counter + 1;
1855 svm_fifo_unset_event (rx_fifo);
1861 ST_DBG ("client pid %u", pid);
1862 for (i = 0; i < n_test_msgs; i++)
1864 while (svm_fifo_has_event (rx_fifo))
1866 app_worker_lock_and_send_event (app_wrk, &s, SESSION_IO_EVT_RX);
1870 diff = vlib_time_now (vm) - start;
1871 ST_DBG ("done %u events in %.2f sec: %f evts/s", *counter,
1872 diff, *counter / diff);
1874 vnet_app_detach_args_t detach_args = {
1875 .app_index = app_index,
1876 .api_client_index = ~0,
1878 vnet_application_detach (&detach_args);
1883 session_test_mq_basic (vlib_main_t * vm, unformat_input_t * input)
1885 svm_msg_q_cfg_t _cfg, *cfg = &_cfg;
1886 svm_msg_q_msg_t msg1, msg2, msg[12];
1887 int __clib_unused verbose, i, rv;
1889 svm_msg_q_ring_t *ring;
1892 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1894 if (unformat (input, "verbose"))
1898 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1904 svm_msg_q_ring_cfg_t rc[2] = { {8, 8, 0}
1907 cfg->consumer_pid = ~0;
1910 cfg->ring_cfgs = rc;
1912 mq = svm_msg_q_alloc (cfg);
1913 SESSION_TEST (mq != 0, "svm_msg_q_alloc");
1914 SESSION_TEST (vec_len (mq->rings) == 2, "ring allocation");
1915 rings_ptr = (u8 *) mq->rings + vec_bytes (mq->rings);
1916 vec_foreach (ring, mq->rings)
1918 SESSION_TEST (ring->data == rings_ptr, "ring data");
1919 rings_ptr += (uword) ring->nitems * ring->elsize;
1922 msg1 = svm_msg_q_alloc_msg (mq, 8);
1923 rv = (mq->rings[0].cursize != 1
1924 || msg1.ring_index != 0 || msg1.elt_index != 0);
1925 SESSION_TEST (rv == 0, "msg alloc1");
1927 msg2 = svm_msg_q_alloc_msg (mq, 15);
1928 rv = (mq->rings[1].cursize != 1
1929 || msg2.ring_index != 1 || msg2.elt_index != 0);
1930 SESSION_TEST (rv == 0, "msg alloc2");
1932 svm_msg_q_free_msg (mq, &msg1);
1933 SESSION_TEST (mq->rings[0].cursize == 0, "free msg");
1935 for (i = 0; i < 12; i++)
1937 msg[i] = svm_msg_q_alloc_msg (mq, 7);
1938 *(u32 *) svm_msg_q_msg_data (mq, &msg[i]) = i;
1941 rv = (mq->rings[0].cursize != 8 || mq->rings[1].cursize != 5);
1942 SESSION_TEST (rv == 0, "msg alloc3");
1944 *(u32 *) svm_msg_q_msg_data (mq, &msg2) = 123;
1945 svm_msg_q_add (mq, &msg2, SVM_Q_NOWAIT);
1946 for (i = 0; i < 12; i++)
1947 svm_msg_q_add (mq, &msg[i], SVM_Q_NOWAIT);
1949 rv = svm_msg_q_sub (mq, &msg2, SVM_Q_NOWAIT, 0);
1950 SESSION_TEST (rv == 0, "dequeue1");
1952 SESSION_TEST (msg2.ring_index == 1 && msg2.elt_index == 0,
1954 rv = (*(u32 *) svm_msg_q_msg_data (mq, &msg2) == 123);
1955 SESSION_TEST (rv, "dequeue 1 data");
1957 svm_msg_q_free_msg (mq, &msg2);
1959 for (i = 0; i < 12; i++)
1961 if (svm_msg_q_sub (mq, &msg[i], SVM_Q_NOWAIT, 0))
1962 SESSION_TEST (0, "dequeue2");
1965 if (msg[i].ring_index != 0 || msg[i].elt_index != (i + 1) % 8)
1966 SESSION_TEST (0, "dequeue2 result2");
1970 if (msg[i].ring_index != 1 || msg[i].elt_index != (i - 8) + 1)
1971 SESSION_TEST (0, "dequeue2 result3");
1973 if (*(u32 *) svm_msg_q_msg_data (mq, &msg[i]) != i)
1974 SESSION_TEST (0, "dequeue2 wrong data");
1975 svm_msg_q_free_msg (mq, &msg[i]);
1977 rv = (mq->rings[0].cursize == 0 && mq->rings[1].cursize == 0);
1978 SESSION_TEST (rv, "post dequeue");
1983 static clib_error_t *
1984 session_test (vlib_main_t * vm,
1985 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
1989 vnet_session_enable_disable (vm, 1);
1991 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1993 if (unformat (input, "basic"))
1994 res = session_test_basic (vm, input);
1995 else if (unformat (input, "namespace"))
1996 res = session_test_namespace (vm, input);
1997 else if (unformat (input, "rules-table"))
1998 res = session_test_rule_table (vm, input);
1999 else if (unformat (input, "rules"))
2000 res = session_test_rules (vm, input);
2001 else if (unformat (input, "proxy"))
2002 res = session_test_proxy (vm, input);
2003 else if (unformat (input, "endpt-cfg"))
2004 res = session_test_endpoint_cfg (vm, input);
2005 else if (unformat (input, "mq-speed"))
2006 res = session_test_mq_speed (vm, input);
2007 else if (unformat (input, "mq-basic"))
2008 res = session_test_mq_basic (vm, input);
2009 else if (unformat (input, "all"))
2011 if ((res = session_test_basic (vm, input)))
2013 if ((res = session_test_namespace (vm, input)))
2015 if ((res = session_test_rule_table (vm, input)))
2017 if ((res = session_test_rules (vm, input)))
2019 if ((res = session_test_proxy (vm, input)))
2021 if ((res = session_test_endpoint_cfg (vm, input)))
2023 if ((res = session_test_mq_speed (vm, input)))
2025 if ((res = session_test_mq_basic (vm, input)))
2034 return clib_error_return (0, "Session unit test failed");
2039 VLIB_CLI_COMMAND (tcp_test_command, static) =
2041 .path = "test session",
2042 .short_help = "internal session unit tests",
2043 .function = session_test,
2048 * fd.io coding-style-patch-verification: ON
2051 * eval: (c-set-style "gnu")