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>
22 #define SESSION_TEST_I(_cond, _comment, _args...) \
24 int _evald = (_cond); \
26 fformat(stderr, "FAIL:%d: " _comment "\n", \
29 fformat(stderr, "PASS:%d: " _comment "\n", \
35 #define SESSION_TEST(_cond, _comment, _args...) \
37 if (!SESSION_TEST_I(_cond, _comment, ##_args)) { \
43 dummy_session_reset_callback (stream_session_t * s)
45 clib_warning ("called...");
49 dummy_session_connected_callback (u32 app_index, u32 api_context,
50 stream_session_t * s, u8 is_fail)
52 clib_warning ("called...");
57 dummy_add_segment_callback (u32 client_index, const u8 * seg_name,
60 clib_warning ("called...");
65 dummy_redirect_connect_callback (u32 client_index, void *mp)
67 return VNET_API_ERROR_SESSION_REDIRECT;
71 dummy_session_disconnect_callback (stream_session_t * s)
73 clib_warning ("called...");
77 dummy_session_accept_callback (stream_session_t * s)
79 clib_warning ("called...");
84 dummy_server_rx_callback (stream_session_t * s)
86 clib_warning ("called...");
91 static session_cb_vft_t dummy_session_cbs = {
92 .session_reset_callback = dummy_session_reset_callback,
93 .session_connected_callback = dummy_session_connected_callback,
94 .session_accept_callback = dummy_session_accept_callback,
95 .session_disconnect_callback = dummy_session_disconnect_callback,
96 .builtin_server_rx_callback = dummy_server_rx_callback,
97 .redirect_connect_callback = dummy_redirect_connect_callback,
102 session_create_lookpback (u32 table_id, u32 * sw_if_index,
103 ip4_address_t * intf_addr)
107 memset (intf_mac, 0, sizeof (intf_mac));
109 if (vnet_create_loopback_interface (sw_if_index, intf_mac, 0, 0))
111 clib_warning ("couldn't create loopback. stopping the test!");
116 ip_table_bind (FIB_PROTOCOL_IP4, *sw_if_index, table_id, 0);
118 vnet_sw_interface_set_flags (vnet_get_main (), *sw_if_index,
119 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
121 if (ip4_add_del_interface_address (vlib_get_main (), *sw_if_index,
124 clib_warning ("couldn't assign loopback ip %U", format_ip4_address,
133 session_delete_loopback (u32 sw_if_index)
135 /* fails spectacularly */
136 /* vnet_delete_loopback_interface (sw_if_index); */
140 session_test_basic (vlib_main_t * vm, unformat_input_t * input)
142 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
143 u64 options[APP_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle;
144 clib_error_t *error = 0;
147 memset (options, 0, sizeof (options));
148 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
149 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
150 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
151 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
152 vnet_app_attach_args_t attach_args = {
153 .api_client_index = ~0,
156 .session_cb_vft = &dummy_session_cbs,
159 error = vnet_application_attach (&attach_args);
160 SESSION_TEST ((error == 0), "app attached");
161 server_index = attach_args.app_index;
163 server_sep.is_ip4 = 1;
164 vnet_bind_args_t bind_args = {
169 bind_args.app_index = server_index;
170 error = vnet_bind (&bind_args);
171 SESSION_TEST ((error == 0), "server bind4 should work");
172 bind4_handle = bind_args.handle;
174 error = vnet_bind (&bind_args);
175 SESSION_TEST ((error != 0), "double server bind4 should not work");
177 bind_args.sep.is_ip4 = 0;
178 error = vnet_bind (&bind_args);
179 SESSION_TEST ((error == 0), "server bind6 should work");
180 bind6_handle = bind_args.handle;
182 error = vnet_bind (&bind_args);
183 SESSION_TEST ((error != 0), "double server bind6 should not work");
185 vnet_unbind_args_t unbind_args = {
186 .handle = bind4_handle,
187 .app_index = server_index,
189 error = vnet_unbind (&unbind_args);
190 SESSION_TEST ((error == 0), "unbind4 should work");
192 unbind_args.handle = bind6_handle;
193 error = vnet_unbind (&unbind_args);
194 SESSION_TEST ((error == 0), "unbind6 should work");
196 vnet_app_detach_args_t detach_args = {
197 .app_index = server_index,
199 vnet_application_detach (&detach_args);
204 session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
206 u64 options[APP_OPTIONS_N_OPTIONS], dummy_secret = 1234;
207 u32 server_index, server_st_index, server_local_st_index;
208 u32 dummy_port = 1234, local_listener, client_index;
209 u32 dummy_api_context = 4321, dummy_client_api_index = 1234;
210 u32 dummy_server_api_index = ~0, sw_if_index = 0;
211 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
212 session_endpoint_t client_sep = SESSION_ENDPOINT_NULL;
213 session_endpoint_t intf_sep = SESSION_ENDPOINT_NULL;
214 clib_error_t *error = 0;
215 u8 *ns_id = format (0, "appns1");
216 app_namespace_t *app_ns;
217 application_t *server;
221 server_sep.is_ip4 = 1;
222 server_sep.port = dummy_port;
223 client_sep.is_ip4 = 1;
224 client_sep.port = dummy_port;
225 memset (options, 0, sizeof (options));
227 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
228 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
229 vnet_app_attach_args_t attach_args = {
230 .api_client_index = ~0,
233 .session_cb_vft = &dummy_session_cbs,
236 vnet_bind_args_t bind_args = {
241 vnet_connect_args_t connect_args = {
247 vnet_unbind_args_t unbind_args = {
248 .handle = bind_args.handle,
252 vnet_app_detach_args_t detach_args = {
256 ip4_address_t intf_addr = {
257 .as_u32 = clib_host_to_net_u32 (0x06000105),
260 intf_sep.ip.ip4 = intf_addr;
262 intf_sep.port = dummy_port;
265 * Insert namespace and lookup
268 vnet_app_namespace_add_del_args_t ns_args = {
270 .secret = dummy_secret,
271 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
274 error = vnet_app_namespace_add_del (&ns_args);
275 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
276 clib_error_get_code (error));
278 app_ns = app_namespace_get_from_id (ns_id);
279 SESSION_TEST ((app_ns != 0), "should find ns %v status", ns_id);
280 SESSION_TEST ((app_ns->ns_secret == dummy_secret), "secret should be %d",
282 SESSION_TEST ((app_ns->sw_if_index == APP_NAMESPACE_INVALID_INDEX),
283 "sw_if_index should be invalid");
286 * Try application attach with wrong secret
289 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
290 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
291 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret - 1;
292 attach_args.namespace_id = ns_id;
293 attach_args.api_client_index = dummy_server_api_index;
295 error = vnet_application_attach (&attach_args);
296 SESSION_TEST ((error != 0), "app attachment should fail");
297 code = clib_error_get_code (error);
298 SESSION_TEST ((code == VNET_API_ERROR_APP_WRONG_NS_SECRET),
299 "code should be wrong ns secret: %d", code);
302 * Attach server with global default scope
304 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
305 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
306 options[APP_OPTIONS_NAMESPACE_SECRET] = 0;
307 attach_args.namespace_id = 0;
308 attach_args.api_client_index = dummy_server_api_index;
309 error = vnet_application_attach (&attach_args);
310 SESSION_TEST ((error == 0), "server attachment should work");
311 server_index = attach_args.app_index;
312 server = application_get (server_index);
313 SESSION_TEST ((server->ns_index == 0),
314 "server should be in the default ns");
316 bind_args.app_index = server_index;
317 error = vnet_bind (&bind_args);
318 SESSION_TEST ((error == 0), "server bind should work");
320 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
321 s = session_lookup_listener (server_st_index, &server_sep);
322 SESSION_TEST ((s != 0), "listener should exist in global table");
323 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
325 server_local_st_index = application_local_session_table (server);
326 SESSION_TEST ((server_local_st_index == APP_INVALID_INDEX),
327 "server shouldn't have access to local table");
329 unbind_args.app_index = server_index;
330 unbind_args.handle = bind_args.handle;
331 error = vnet_unbind (&unbind_args);
332 SESSION_TEST ((error == 0), "unbind should work");
334 s = session_lookup_listener (server_st_index, &server_sep);
335 SESSION_TEST ((s == 0), "listener should not exist in global table");
337 detach_args.app_index = server_index;
338 vnet_application_detach (&detach_args);
341 * Attach server with local and global scope
343 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
344 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
345 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
346 attach_args.namespace_id = ns_id;
347 attach_args.api_client_index = dummy_server_api_index;
348 error = vnet_application_attach (&attach_args);
349 SESSION_TEST ((error == 0), "server attachment should work");
350 server_index = attach_args.app_index;
351 server = application_get (server_index);
352 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
353 "server should be in the right ns");
355 bind_args.app_index = server_index;
356 error = vnet_bind (&bind_args);
357 SESSION_TEST ((error == 0), "bind should work");
358 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
359 s = session_lookup_listener (server_st_index, &server_sep);
360 SESSION_TEST ((s != 0), "listener should exist in global table");
361 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
363 server_local_st_index = application_local_session_table (server);
365 session_lookup_local_endpoint (server_local_st_index, &server_sep);
366 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
367 "listener should exist in local table");
370 * Try client connect with 1) local scope 2) global scope
372 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
373 attach_args.api_client_index = dummy_client_api_index;
374 error = vnet_application_attach (&attach_args);
375 SESSION_TEST ((error == 0), "client attachment should work");
376 client_index = attach_args.app_index;
377 connect_args.api_context = dummy_api_context;
378 connect_args.app_index = client_index;
379 error = vnet_connect (&connect_args);
380 SESSION_TEST ((error != 0), "client connect should return error code");
381 code = clib_error_get_code (error);
382 SESSION_TEST ((code == VNET_API_ERROR_INVALID_VALUE),
383 "error code should be invalid value (zero ip)");
384 connect_args.sep.ip.ip4.as_u8[0] = 127;
385 error = vnet_connect (&connect_args);
386 SESSION_TEST ((error != 0), "client connect should return error code");
387 code = clib_error_get_code (error);
388 SESSION_TEST ((code == VNET_API_ERROR_SESSION_REDIRECT),
389 "error code should be redirect");
390 detach_args.app_index = client_index;
391 vnet_application_detach (&detach_args);
393 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
394 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
395 attach_args.api_client_index = dummy_client_api_index;
396 error = vnet_application_attach (&attach_args);
397 SESSION_TEST ((error == 0), "client attachment should work");
398 error = vnet_connect (&connect_args);
399 SESSION_TEST ((error != 0), "client connect should return error code");
400 code = clib_error_get_code (error);
401 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
402 "error code should be connect (nothing in local scope)");
403 detach_args.app_index = client_index;
404 vnet_application_detach (&detach_args);
407 * Unbind and detach server and then re-attach with local scope only
409 unbind_args.handle = bind_args.handle;
410 unbind_args.app_index = server_index;
411 error = vnet_unbind (&unbind_args);
412 SESSION_TEST ((error == 0), "unbind should work");
414 s = session_lookup_listener (server_st_index, &server_sep);
415 SESSION_TEST ((s == 0), "listener should not exist in global table");
417 session_lookup_local_endpoint (server_local_st_index, &server_sep);
418 SESSION_TEST ((s == 0), "listener should not exist in local table");
420 detach_args.app_index = server_index;
421 vnet_application_detach (&detach_args);
423 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
424 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
425 attach_args.api_client_index = dummy_server_api_index;
426 error = vnet_application_attach (&attach_args);
427 SESSION_TEST ((error == 0), "app attachment should work");
428 server_index = attach_args.app_index;
429 server = application_get (server_index);
430 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
431 "app should be in the right ns");
433 bind_args.app_index = server_index;
434 error = vnet_bind (&bind_args);
435 SESSION_TEST ((error == 0), "bind should work");
437 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
438 s = session_lookup_listener (server_st_index, &server_sep);
439 SESSION_TEST ((s == 0), "listener should not exist in global table");
440 server_local_st_index = application_local_session_table (server);
442 session_lookup_local_endpoint (server_local_st_index, &server_sep);
443 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
444 "listener should exist in local table");
446 unbind_args.handle = bind_args.handle;
447 error = vnet_unbind (&unbind_args);
448 SESSION_TEST ((error == 0), "unbind should work");
451 session_lookup_local_endpoint (server_local_st_index, &server_sep);
452 SESSION_TEST ((local_listener == SESSION_INVALID_INDEX),
453 "listener should not exist in local table");
456 * Client attach + connect in default ns with local scope
458 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
459 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
460 attach_args.namespace_id = 0;
461 attach_args.api_client_index = dummy_client_api_index;
462 vnet_application_attach (&attach_args);
463 error = vnet_connect (&connect_args);
464 SESSION_TEST ((error != 0), "client connect should return error code");
465 code = clib_error_get_code (error);
466 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
467 "error code should be connect (not in same ns)");
468 detach_args.app_index = client_index;
469 vnet_application_detach (&detach_args);
474 detach_args.app_index = server_index;
475 vnet_application_detach (&detach_args);
478 * Create loopback interface
480 session_create_lookpback (0, &sw_if_index, &intf_addr);
485 ns_args.sw_if_index = sw_if_index;
486 error = vnet_app_namespace_add_del (&ns_args);
487 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
488 clib_error_get_code (error));
491 * Attach server with local and global scope
493 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
494 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
495 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
496 attach_args.namespace_id = ns_id;
497 attach_args.api_client_index = dummy_server_api_index;
498 error = vnet_application_attach (&attach_args);
499 SESSION_TEST ((error == 0), "server attachment should work");
500 server_index = attach_args.app_index;
502 bind_args.app_index = server_index;
503 error = vnet_bind (&bind_args);
504 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
505 s = session_lookup_listener (server_st_index, &server_sep);
506 SESSION_TEST ((s == 0), "zero listener should not exist in global table");
508 s = session_lookup_listener (server_st_index, &intf_sep);
509 SESSION_TEST ((s != 0), "intf listener should exist in global table");
510 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
512 server_local_st_index = application_local_session_table (server);
514 session_lookup_local_endpoint (server_local_st_index, &server_sep);
515 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
516 "zero listener should exist in local table");
517 detach_args.app_index = server_index;
518 vnet_application_detach (&detach_args);
524 session_delete_loopback (sw_if_index);
529 session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
531 session_rules_table_t _srt, *srt = &_srt;
532 u16 lcl_port = 1234, rmt_port = 4321;
533 u32 action_index = 1, res;
534 ip4_address_t lcl_lkup, rmt_lkup;
538 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
540 if (unformat (input, "verbose"))
544 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
550 memset (srt, 0, sizeof (*srt));
551 session_rules_table_init (srt);
553 ip4_address_t lcl_ip = {
554 .as_u32 = clib_host_to_net_u32 (0x01020304),
556 ip4_address_t rmt_ip = {
557 .as_u32 = clib_host_to_net_u32 (0x05060708),
559 ip4_address_t lcl_ip2 = {
560 .as_u32 = clib_host_to_net_u32 (0x02020202),
562 ip4_address_t rmt_ip2 = {
563 .as_u32 = clib_host_to_net_u32 (0x06060606),
565 ip4_address_t lcl_ip3 = {
566 .as_u32 = clib_host_to_net_u32 (0x03030303),
568 ip4_address_t rmt_ip3 = {
569 .as_u32 = clib_host_to_net_u32 (0x07070707),
571 fib_prefix_t lcl_pref = {
572 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
574 .fp_proto = FIB_PROTOCOL_IP4,
576 fib_prefix_t rmt_pref = {
577 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
579 .fp_proto = FIB_PROTOCOL_IP4,
582 session_rule_table_add_del_args_t args = {
585 .lcl_port = lcl_port,
586 .rmt_port = rmt_port,
587 .action_index = action_index++,
590 error = session_rules_table_add_del (srt, &args);
591 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
595 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
596 SESSION_TEST ((res == 1),
597 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
601 * 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
603 args.lcl.fp_addr.ip4 = lcl_ip;
604 args.lcl.fp_len = 24;
605 args.action_index = action_index++;
606 error = session_rules_table_add_del (srt, &args);
607 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/16 4321 action %d",
609 args.rmt.fp_addr.ip4 = rmt_ip;
610 args.rmt.fp_len = 24;
611 args.action_index = action_index++;
612 error = session_rules_table_add_del (srt, &args);
613 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/24 4321 action %d",
617 * 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
619 args.lcl.fp_addr.ip4 = lcl_ip2;
620 args.lcl.fp_len = 24;
621 args.rmt.fp_addr.ip4 = rmt_ip2;
622 args.rmt.fp_len = 16;
623 args.action_index = action_index++;
624 error = session_rules_table_add_del (srt, &args);
625 SESSION_TEST ((error == 0), "Add 2.2.2.2/24 1234 6.6.6.6/16 4321 action %d",
627 args.lcl.fp_addr.ip4 = lcl_ip3;
628 args.rmt.fp_addr.ip4 = rmt_ip3;
629 args.action_index = action_index++;
630 error = session_rules_table_add_del (srt, &args);
631 SESSION_TEST ((error == 0), "Add 3.3.3.3/24 1234 7.7.7.7/16 4321 action %d",
635 * Add again 3.3.3.3/24 1234 7.7.7.7/16 4321
637 args.lcl.fp_addr.ip4 = lcl_ip3;
638 args.rmt.fp_addr.ip4 = rmt_ip3;
639 args.action_index = action_index++;
640 error = session_rules_table_add_del (srt, &args);
641 SESSION_TEST ((error == 0), "overwrite 3.3.3.3/24 1234 7.7.7.7/16 4321 "
642 "action %d", action_index - 1);
645 * 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
646 * and 3.3.3.3 1234 7.7.7.7 4321
649 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
650 SESSION_TEST ((res == 3),
651 "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
654 lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
655 rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
657 session_rules_table_lookup4 (srt, &lcl_lkup,
658 &rmt_lkup, lcl_port, rmt_port);
659 SESSION_TEST ((res == 1),
660 "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
664 session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
665 SESSION_TEST ((res == 6),
666 "Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
667 "should be 6 (updated): %d", res);
670 * Add 1.2.3.4/24 * 5.6.7.8/24 *
671 * Lookup 1.2.3.4 1234 5.6.7.8 4321 and 1.2.3.4 1235 5.6.7.8 4321
673 args.lcl.fp_addr.ip4 = lcl_ip;
674 args.rmt.fp_addr.ip4 = rmt_ip;
675 args.lcl.fp_len = 24;
676 args.rmt.fp_len = 24;
679 args.action_index = action_index++;
680 error = session_rules_table_add_del (srt, &args);
681 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
684 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
685 SESSION_TEST ((res == 7),
686 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
687 " be 7 (lpm dst): %d", res);
689 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
690 lcl_port + 1, rmt_port);
691 SESSION_TEST ((res == 7),
692 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
696 * Del 1.2.3.4/24 * 5.6.7.8/24 *
697 * Add 1.2.3.4/16 * 5.6.7.8/16 * and 1.2.3.4/24 1235 5.6.7.8/24 4321
698 * Lookup 1.2.3.4 1234 5.6.7.8 4321, 1.2.3.4 1235 5.6.7.8 4321 and
699 * 1.2.3.4 1235 5.6.7.8 4322
702 error = session_rules_table_add_del (srt, &args);
703 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 * 5.6.7.8/24 *");
705 args.lcl.fp_addr.ip4 = lcl_ip;
706 args.rmt.fp_addr.ip4 = rmt_ip;
707 args.lcl.fp_len = 16;
708 args.rmt.fp_len = 16;
711 args.action_index = action_index++;
713 error = session_rules_table_add_del (srt, &args);
714 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 * action %d",
717 args.lcl.fp_addr.ip4 = lcl_ip;
718 args.rmt.fp_addr.ip4 = rmt_ip;
719 args.lcl.fp_len = 24;
720 args.rmt.fp_len = 24;
721 args.lcl_port = lcl_port + 1;
722 args.rmt_port = rmt_port;
723 args.action_index = action_index++;
725 error = session_rules_table_add_del (srt, &args);
726 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1235 5.6.7.8/24 4321 action %d",
730 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
733 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
734 SESSION_TEST ((res == 3),
735 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
738 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
739 lcl_port + 1, rmt_port);
740 SESSION_TEST ((res == 9),
741 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
744 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
745 lcl_port + 1, rmt_port + 1);
746 SESSION_TEST ((res == 8),
747 "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
751 * Delete 1.2.0.0/16 1234 5.6.0.0/16 4321 and 1.2.0.0/16 * 5.6.0.0/16 *
752 * Lookup 1.2.3.4 1234 5.6.7.8 4321
754 args.lcl_port = 1234;
755 args.rmt_port = 4321;
756 args.lcl.fp_len = 16;
757 args.rmt.fp_len = 16;
759 error = session_rules_table_add_del (srt, &args);
760 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
762 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
763 SESSION_TEST ((res == 3),
764 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
770 error = session_rules_table_add_del (srt, &args);
771 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
773 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
774 SESSION_TEST ((res == 3),
775 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
779 * Delete 1.2.3.4/24 1234 5.6.7.5/24
781 args.lcl.fp_addr.ip4 = lcl_ip;
782 args.rmt.fp_addr.ip4 = rmt_ip;
783 args.lcl.fp_len = 24;
784 args.rmt.fp_len = 24;
785 args.lcl_port = 1234;
786 args.rmt_port = 4321;
788 error = session_rules_table_add_del (srt, &args);
789 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
791 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
792 SESSION_TEST ((res == 2), "Action should be 2: %d", res);
798 session_test_rules (vlib_main_t * vm, unformat_input_t * input)
800 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
801 u64 options[APP_OPTIONS_N_OPTIONS];
802 u16 lcl_port = 1234, rmt_port = 4321;
803 u32 server_index, server_index2, app_index;
804 u32 dummy_server_api_index = ~0;
805 transport_connection_t *tc;
806 u32 dummy_port = 1111;
807 clib_error_t *error = 0;
808 u8 is_filtered = 0, *ns_id = format (0, "appns1");
809 stream_session_t *listener, *s;
810 app_namespace_t *default_ns = app_namespace_get_default ();
811 u32 local_ns_index = default_ns->local_table_index;
813 app_namespace_t *app_ns;
815 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
817 if (unformat (input, "verbose"))
821 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
827 server_sep.is_ip4 = 1;
828 server_sep.port = dummy_port;
829 memset (options, 0, sizeof (options));
831 vnet_app_attach_args_t attach_args = {
832 .api_client_index = ~0,
835 .session_cb_vft = &dummy_session_cbs,
838 vnet_bind_args_t bind_args = {
844 * Attach server with global and local default scope
846 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
847 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
848 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
849 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
850 attach_args.namespace_id = 0;
851 attach_args.api_client_index = dummy_server_api_index;
852 error = vnet_application_attach (&attach_args);
853 SESSION_TEST ((error == 0), "server attached");
854 server_index = attach_args.app_index;
856 bind_args.app_index = server_index;
857 error = vnet_bind (&bind_args);
858 SESSION_TEST ((error == 0), "server bound to %U/%d", format_ip46_address,
859 &server_sep.ip, 1, server_sep.port);
860 listener = listen_session_get_from_handle (bind_args.handle);
861 ip4_address_t lcl_ip = {
862 .as_u32 = clib_host_to_net_u32 (0x01020304),
864 ip4_address_t rmt_ip = {
865 .as_u32 = clib_host_to_net_u32 (0x05060708),
867 fib_prefix_t lcl_pref = {
868 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
870 .fp_proto = FIB_PROTOCOL_IP4,
872 fib_prefix_t rmt_pref = {
873 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
875 .fp_proto = FIB_PROTOCOL_IP4,
878 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
879 &rmt_pref.fp_addr.ip4, lcl_port,
880 rmt_port, TRANSPORT_PROTO_TCP, 0,
882 SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
885 * Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action server_index
887 session_rule_add_del_args_t args = {
888 .table_args.lcl = lcl_pref,
889 .table_args.rmt = rmt_pref,
890 .table_args.lcl_port = lcl_port,
891 .table_args.rmt_port = rmt_port,
892 .table_args.action_index = server_index,
893 .table_args.is_add = 1,
896 error = vnet_session_rule_add_del (&args);
897 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
898 args.table_args.action_index);
900 tc = session_lookup_connection4 (0, &lcl_pref.fp_addr.ip4,
901 &rmt_pref.fp_addr.ip4, lcl_port, rmt_port,
902 TRANSPORT_PROTO_TCP);
903 SESSION_TEST ((tc->c_index == listener->connection_index),
904 "optimized lookup should return the listener");
905 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
906 &rmt_pref.fp_addr.ip4, lcl_port,
907 rmt_port, TRANSPORT_PROTO_TCP, 0,
909 SESSION_TEST ((tc->c_index == listener->connection_index),
910 "lookup should return the listener");
911 s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
912 lcl_port, rmt_port, TRANSPORT_PROTO_TCP);
913 SESSION_TEST ((s->connection_index == listener->connection_index),
914 "safe lookup should return the listener");
915 session_endpoint_t sep = {
916 .ip = rmt_pref.fp_addr,
919 .transport_proto = TRANSPORT_PROTO_TCP,
921 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
922 SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
923 "should not work (global scope)");
925 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
926 &rmt_pref.fp_addr.ip4, lcl_port + 1,
927 rmt_port, TRANSPORT_PROTO_TCP, 0,
929 SESSION_TEST ((tc == 0),
930 "optimized lookup for wrong lcl port + 1 should not work");
933 * Add 1.2.3.4/16 * 5.6.7.8/16 4321
935 args.table_args.lcl_port = 0;
936 args.scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
937 error = vnet_session_rule_add_del (&args);
938 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 4321 action %d",
939 args.table_args.action_index);
940 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
941 &rmt_pref.fp_addr.ip4, lcl_port + 1,
942 rmt_port, TRANSPORT_PROTO_TCP, 0,
944 SESSION_TEST ((tc->c_index == listener->connection_index),
945 "optimized lookup for lcl port + 1 should work");
946 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
947 SESSION_TEST ((app_index == server_index), "local session endpoint lookup "
948 "should work (lcl ip was zeroed)");
951 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
953 args.table_args.lcl_port = 1234;
954 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
955 args.table_args.lcl.fp_len = 30;
956 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
957 args.table_args.rmt.fp_len = 30;
958 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
959 error = vnet_session_rule_add_del (&args);
960 SESSION_TEST ((error == 0), "Add 1.2.3.4/30 1234 5.6.7.8/30 4321 action %d",
961 args.table_args.action_index);
965 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
966 TRANSPORT_PROTO_TCP);
967 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
968 TRANSPORT_PROTO_TCP);
971 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
972 &rmt_pref.fp_addr.ip4, lcl_port,
973 rmt_port, TRANSPORT_PROTO_TCP, 0,
975 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
976 "should fail (deny rule)");
977 SESSION_TEST ((is_filtered == 1), "lookup should be filtered (deny)");
979 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
980 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
981 "5.6.7.8/16 4321 in local table should return deny");
983 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
984 &rmt_pref.fp_addr.ip4, lcl_port + 1,
985 rmt_port, TRANSPORT_PROTO_TCP, 0,
987 SESSION_TEST ((tc->c_index == listener->connection_index),
988 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should work");
991 * "Mask" deny rule with more specific allow:
992 * Add allow rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -3 (allow)
994 args.table_args.is_add = 1;
995 args.table_args.lcl_port = 1234;
996 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
997 args.table_args.lcl.fp_len = 32;
998 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
999 args.table_args.rmt.fp_len = 32;
1000 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1001 error = vnet_session_rule_add_del (&args);
1002 SESSION_TEST ((error == 0), "Add masking rule 1.2.3.4/30 1234 5.6.7.8/32 "
1003 "4321 action %d", args.table_args.action_index);
1006 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1007 &rmt_pref.fp_addr.ip4, lcl_port,
1008 rmt_port, TRANSPORT_PROTO_TCP, 0,
1010 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
1011 "should fail (allow without app)");
1012 SESSION_TEST ((is_filtered == 0), "lookup should NOT be filtered");
1014 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1015 SESSION_TEST ((app_index == APP_INVALID_INDEX), "lookup for 1.2.3.4/32 1234"
1016 " 5.6.7.8/32 4321 in local table should return invalid");
1020 vlib_cli_output (vm, "Local rules");
1021 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1022 TRANSPORT_PROTO_TCP);
1025 sep.ip.ip4.as_u32 += 1 << 24;
1026 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1027 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234"
1028 " 5.6.7.9/32 4321 in local table should return deny");
1030 vnet_connect_args_t connect_args = {
1032 .app_index = attach_args.app_index,
1036 /* Try connecting */
1037 error = vnet_connect (&connect_args);
1038 SESSION_TEST ((error != 0), "connect should fail");
1039 rv = clib_error_get_code (error);
1040 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1041 "connect should be filtered");
1043 sep.ip.ip4.as_u32 -= 1 << 24;
1046 * Delete masking rule: 1.2.3.4/32 1234 5.6.7.8/32 4321 allow
1048 args.table_args.is_add = 0;
1049 args.table_args.lcl_port = 1234;
1050 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1051 args.table_args.lcl.fp_len = 32;
1052 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1053 args.table_args.rmt.fp_len = 32;
1054 error = vnet_session_rule_add_del (&args);
1055 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 allow");
1059 * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
1061 args.table_args.is_add = 1;
1062 args.table_args.lcl_port = 0;
1063 args.table_args.lcl.fp_len = 0;
1064 args.table_args.rmt.fp_len = 16;
1065 args.table_args.action_index = -1;
1066 error = vnet_session_rule_add_del (&args);
1067 SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d",
1068 args.table_args.action_index);
1072 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1073 TRANSPORT_PROTO_TCP);
1074 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1075 TRANSPORT_PROTO_TCP);
1078 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1079 SESSION_TEST ((app_index == APP_DROP_INDEX),
1080 "local session endpoint lookup should return deny");
1083 * Delete 1.2.3.4/32 1234 5.6.7.8/32 4321 deny
1085 args.table_args.is_add = 0;
1086 args.table_args.lcl_port = 1234;
1087 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1088 args.table_args.lcl.fp_len = 30;
1089 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1090 args.table_args.rmt.fp_len = 30;
1091 error = vnet_session_rule_add_del (&args);
1092 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1094 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1095 SESSION_TEST ((app_index == APP_INVALID_INDEX),
1096 "local session endpoint lookup should return invalid");
1099 * Delete 0/0 * 5.6.7.8/16 4321, 1.2.3.4/16 * 5.6.7.8/16 4321 and
1100 * 1.2.3.4/16 1234 5.6.7.8/16 4321
1102 args.table_args.is_add = 0;
1103 args.table_args.lcl_port = 0;
1104 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1105 args.table_args.lcl.fp_len = 0;
1106 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1107 args.table_args.rmt.fp_len = 16;
1108 args.table_args.rmt_port = 4321;
1109 error = vnet_session_rule_add_del (&args);
1110 SESSION_TEST ((error == 0), "Del 0/0 * 5.6.7.8/16 4321");
1111 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1112 SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
1113 "should not work (removed)");
1115 args.table_args.is_add = 0;
1116 args.table_args.lcl = lcl_pref;
1118 args.table_args.is_add = 0;
1119 args.table_args.lcl_port = 0;
1120 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1121 args.table_args.lcl.fp_len = 16;
1122 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1123 args.table_args.rmt.fp_len = 16;
1124 args.table_args.rmt_port = 4321;
1125 error = vnet_session_rule_add_del (&args);
1126 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
1127 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1128 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1129 rmt_port, TRANSPORT_PROTO_TCP, 0,
1131 SESSION_TEST ((tc == 0),
1132 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should not "
1135 args.table_args.is_add = 0;
1136 args.table_args.lcl_port = 1234;
1137 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1138 args.table_args.lcl.fp_len = 16;
1139 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1140 args.table_args.rmt.fp_len = 16;
1141 args.table_args.rmt_port = 4321;
1142 error = vnet_session_rule_add_del (&args);
1143 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
1144 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1145 &rmt_pref.fp_addr.ip4, lcl_port,
1146 rmt_port, TRANSPORT_PROTO_TCP, 0,
1148 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should "
1149 "not work (del + deny)");
1151 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1152 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1153 &rmt_pref.fp_addr.ip4, lcl_port,
1154 rmt_port, TRANSPORT_PROTO_TCP, 0,
1156 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should"
1157 " not work (no-rule)");
1160 * Test tags. Add/overwrite/del rule with tag
1162 args.table_args.is_add = 1;
1163 args.table_args.lcl_port = 1234;
1164 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1165 args.table_args.lcl.fp_len = 16;
1166 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1167 args.table_args.rmt.fp_len = 16;
1168 args.table_args.rmt_port = 4321;
1169 args.table_args.tag = format (0, "test_rule");
1170 args.table_args.action_index = server_index;
1171 error = vnet_session_rule_add_del (&args);
1172 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 deny "
1176 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1177 TRANSPORT_PROTO_TCP);
1178 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1179 TRANSPORT_PROTO_TCP);
1181 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1182 &rmt_pref.fp_addr.ip4, lcl_port,
1183 rmt_port, TRANSPORT_PROTO_TCP, 0,
1185 SESSION_TEST ((tc->c_index == listener->connection_index),
1186 "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should work");
1188 vec_free (args.table_args.tag);
1189 args.table_args.lcl_port = 1234;
1190 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1191 args.table_args.lcl.fp_len = 16;
1192 args.table_args.tag = format (0, "test_rule_overwrite");
1193 error = vnet_session_rule_add_del (&args);
1194 SESSION_TEST ((error == 0),
1195 "Overwrite 1.2.3.4/16 1234 5.6.7.8/16 4321 deny tag test_rule"
1199 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1200 TRANSPORT_PROTO_TCP);
1201 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1202 TRANSPORT_PROTO_TCP);
1205 args.table_args.is_add = 0;
1206 args.table_args.lcl_port += 1;
1207 error = vnet_session_rule_add_del (&args);
1208 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny "
1209 "tag %v", args.table_args.tag);
1212 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1213 TRANSPORT_PROTO_TCP);
1214 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1215 TRANSPORT_PROTO_TCP);
1217 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1218 &rmt_pref.fp_addr.ip4, lcl_port,
1219 rmt_port, TRANSPORT_PROTO_TCP, 0,
1221 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/32 4321 should not"
1226 * Test local rules with multiple namespaces
1230 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1232 args.table_args.is_add = 1;
1233 args.table_args.lcl_port = 1234;
1234 args.table_args.rmt_port = 0;
1235 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1236 args.table_args.lcl.fp_len = 32;
1237 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1238 args.table_args.rmt.fp_len = 32;
1239 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1240 args.table_args.tag = 0;
1241 args.scope = SESSION_RULE_SCOPE_LOCAL;
1242 error = vnet_session_rule_add_del (&args);
1243 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
1244 args.table_args.action_index);
1246 * Add 'white' rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
1248 args.table_args.is_add = 1;
1249 args.table_args.lcl_port = 1234;
1250 args.table_args.rmt_port = 4321;
1251 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1252 args.table_args.lcl.fp_len = 32;
1253 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1254 args.table_args.rmt.fp_len = 32;
1255 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1256 error = vnet_session_rule_add_del (&args);
1260 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1261 TRANSPORT_PROTO_TCP);
1264 vnet_app_namespace_add_del_args_t ns_args = {
1267 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
1270 error = vnet_app_namespace_add_del (&ns_args);
1271 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
1272 clib_error_get_code (error));
1273 app_ns = app_namespace_get_from_id (ns_id);
1275 attach_args.namespace_id = ns_id;
1276 attach_args.api_client_index = dummy_server_api_index - 1;
1277 error = vnet_application_attach (&attach_args);
1278 SESSION_TEST ((error == 0), "server2 attached");
1279 server_index2 = attach_args.app_index;
1282 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1284 args.table_args.lcl_port = 1234;
1285 args.table_args.rmt_port = 0;
1286 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1287 args.table_args.lcl.fp_len = 32;
1288 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1289 args.table_args.rmt.fp_len = 32;
1290 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1291 args.appns_index = app_namespace_index (app_ns);
1293 error = vnet_session_rule_add_del (&args);
1294 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d "
1295 "in test namespace", args.table_args.action_index);
1297 * Lookup default namespace
1299 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1300 SESSION_TEST ((app_index == APP_INVALID_INDEX),
1301 "lookup for 1.2.3.4/32 1234 5.6.7.8/32 4321 in local table "
1302 "should return allow (invalid)");
1305 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1306 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
1307 "5.6.7.8/16 432*2* in local table should return deny");
1309 connect_args.app_index = server_index;
1310 connect_args.sep = sep;
1311 error = vnet_connect (&connect_args);
1312 SESSION_TEST ((error != 0), "connect should fail");
1313 rv = clib_error_get_code (error);
1314 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1315 "connect should be filtered");
1318 * Lookup test namespace
1320 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1321 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
1322 "5.6.7.8/16 4321 in local table should return deny");
1324 connect_args.app_index = server_index;
1325 error = vnet_connect (&connect_args);
1326 SESSION_TEST ((error != 0), "connect should fail");
1327 rv = clib_error_get_code (error);
1328 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1329 "connect should be filtered");
1331 args.table_args.is_add = 0;
1332 vnet_session_rule_add_del (&args);
1334 args.appns_index = 0;
1335 args.table_args.is_add = 0;
1336 vnet_session_rule_add_del (&args);
1338 args.table_args.rmt_port = 4321;
1339 vnet_session_rule_add_del (&args);
1343 vec_free (args.table_args.tag);
1344 vnet_app_detach_args_t detach_args = {
1345 .app_index = server_index,
1347 vnet_application_detach (&detach_args);
1349 detach_args.app_index = server_index2;
1350 vnet_application_detach (&detach_args);
1357 session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
1359 u64 options[APP_OPTIONS_N_OPTIONS];
1360 char *show_listeners = "sh session listeners tcp verbose";
1361 char *show_local_listeners = "sh app ns table default";
1362 unformat_input_t tmp_input;
1363 u32 server_index, app_index;
1364 u32 dummy_server_api_index = ~0, sw_if_index = 0;
1365 clib_error_t *error = 0;
1366 u8 sst, is_filtered = 0;
1367 stream_session_t *s;
1368 transport_connection_t *tc;
1369 u16 lcl_port = 1234, rmt_port = 4321;
1370 app_namespace_t *app_ns;
1373 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1375 if (unformat (input, "verbose"))
1379 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1385 ip4_address_t lcl_ip = {
1386 .as_u32 = clib_host_to_net_u32 (0x01020304),
1388 ip4_address_t rmt_ip = {
1389 .as_u32 = clib_host_to_net_u32 (0x05060708),
1391 fib_prefix_t rmt_pref = {
1392 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1394 .fp_proto = FIB_PROTOCOL_IP4,
1396 session_endpoint_t sep = {
1397 .ip = rmt_pref.fp_addr,
1400 .transport_proto = TRANSPORT_PROTO_TCP,
1404 * Create loopback interface
1406 session_create_lookpback (0, &sw_if_index, &lcl_ip);
1408 app_ns = app_namespace_get_default ();
1409 app_ns->sw_if_index = sw_if_index;
1411 memset (options, 0, sizeof (options));
1412 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
1413 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
1414 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_IS_PROXY;
1415 options[APP_OPTIONS_PROXY_TRANSPORT] = 1 << TRANSPORT_PROTO_TCP;
1416 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1417 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1418 vnet_app_attach_args_t attach_args = {
1419 .api_client_index = ~0,
1422 .session_cb_vft = &dummy_session_cbs,
1425 attach_args.api_client_index = dummy_server_api_index;
1426 error = vnet_application_attach (&attach_args);
1427 SESSION_TEST ((error == 0), "server attachment should work");
1428 server_index = attach_args.app_index;
1432 unformat_init_string (&tmp_input, show_listeners,
1433 strlen (show_listeners));
1434 vlib_cli_input (vm, &tmp_input, 0, 0);
1435 unformat_init_string (&tmp_input, show_local_listeners,
1436 strlen (show_local_listeners));
1437 vlib_cli_input (vm, &tmp_input, 0, 0);
1440 tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
1441 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1442 SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
1444 sst = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, 1);
1445 s = listen_session_get (sst, tc->s_index);
1446 SESSION_TEST ((s->app_index == server_index), "lookup should return the"
1449 tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
1450 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1451 SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
1454 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1455 SESSION_TEST ((app_index == server_index), "local session endpoint lookup"
1458 vnet_app_detach_args_t detach_args = {
1459 .app_index = server_index,
1461 vnet_application_detach (&detach_args);
1465 unformat_init_string (&tmp_input, show_listeners,
1466 strlen (show_listeners));
1467 vlib_cli_input (vm, &tmp_input, 0, 0);
1468 unformat_init_string (&tmp_input, show_local_listeners,
1469 strlen (show_local_listeners));
1470 vlib_cli_input (vm, &tmp_input, 0, 0);
1473 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1474 SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
1475 "local session endpoint lookup should not work after detach");
1477 unformat_free (&tmp_input);
1481 static clib_error_t *
1482 session_test (vlib_main_t * vm,
1483 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
1487 vnet_session_enable_disable (vm, 1);
1489 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1491 if (unformat (input, "basic"))
1492 res = session_test_basic (vm, input);
1493 else if (unformat (input, "namespace"))
1494 res = session_test_namespace (vm, input);
1495 else if (unformat (input, "rules-table"))
1496 res = session_test_rule_table (vm, input);
1497 else if (unformat (input, "rules"))
1498 res = session_test_rules (vm, input);
1499 else if (unformat (input, "proxy"))
1500 res = session_test_proxy (vm, input);
1501 else if (unformat (input, "all"))
1503 if ((res = session_test_basic (vm, input)))
1505 if ((res = session_test_namespace (vm, input)))
1507 if ((res = session_test_rule_table (vm, input)))
1509 if ((res = session_test_rules (vm, input)))
1511 if ((res = session_test_proxy (vm, input)))
1520 return clib_error_return (0, "Session unit test failed");
1525 VLIB_CLI_COMMAND (tcp_test_command, static) =
1527 .path = "test session",
1528 .short_help = "internal session unit tests",
1529 .function = session_test,
1534 * fd.io coding-style-patch-verification: ON
1537 * eval: (c-set-style "gnu")