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...");
56 static u32 dummy_segment_count;
59 dummy_add_segment_callback (u32 client_index, const ssvm_private_t * fs)
61 dummy_segment_count = 1;
66 dummy_del_segment_callback (u32 client_index, const ssvm_private_t * fs)
68 dummy_segment_count = 0;
73 dummy_redirect_connect_callback (u32 client_index, void *mp)
75 return VNET_API_ERROR_SESSION_REDIRECT;
79 dummy_session_disconnect_callback (stream_session_t * s)
81 clib_warning ("called...");
84 static u32 dummy_accept;
87 dummy_session_accept_callback (stream_session_t * s)
90 s->session_state = SESSION_STATE_READY;
95 dummy_server_rx_callback (stream_session_t * s)
97 clib_warning ("called...");
102 static session_cb_vft_t dummy_session_cbs = {
103 .session_reset_callback = dummy_session_reset_callback,
104 .session_connected_callback = dummy_session_connected_callback,
105 .session_accept_callback = dummy_session_accept_callback,
106 .session_disconnect_callback = dummy_session_disconnect_callback,
107 .builtin_server_rx_callback = dummy_server_rx_callback,
108 .add_segment_callback = dummy_add_segment_callback,
109 .del_segment_callback = dummy_del_segment_callback,
114 session_create_lookpback (u32 table_id, u32 * sw_if_index,
115 ip4_address_t * intf_addr)
119 memset (intf_mac, 0, sizeof (intf_mac));
121 if (vnet_create_loopback_interface (sw_if_index, intf_mac, 0, 0))
123 clib_warning ("couldn't create loopback. stopping the test!");
128 ip_table_bind (FIB_PROTOCOL_IP4, *sw_if_index, table_id, 0);
130 vnet_sw_interface_set_flags (vnet_get_main (), *sw_if_index,
131 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
133 if (ip4_add_del_interface_address (vlib_get_main (), *sw_if_index,
136 clib_warning ("couldn't assign loopback ip %U", format_ip4_address,
145 session_delete_loopback (u32 sw_if_index)
147 /* fails spectacularly */
148 /* vnet_delete_loopback_interface (sw_if_index); */
152 session_test_basic (vlib_main_t * vm, unformat_input_t * input)
154 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
155 u64 options[APP_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle;
156 clib_error_t *error = 0;
159 memset (options, 0, sizeof (options));
160 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
161 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
162 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
163 vnet_app_attach_args_t attach_args = {
164 .api_client_index = ~0,
167 .session_cb_vft = &dummy_session_cbs,
170 error = vnet_application_attach (&attach_args);
171 SESSION_TEST ((error == 0), "app attached");
172 server_index = attach_args.app_index;
174 server_sep.is_ip4 = 1;
175 vnet_bind_args_t bind_args = {
180 bind_args.app_index = server_index;
181 error = vnet_bind (&bind_args);
182 SESSION_TEST ((error == 0), "server bind4 should work");
183 bind4_handle = bind_args.handle;
185 error = vnet_bind (&bind_args);
186 SESSION_TEST ((error != 0), "double server bind4 should not work");
188 bind_args.sep.is_ip4 = 0;
189 error = vnet_bind (&bind_args);
190 SESSION_TEST ((error == 0), "server bind6 should work");
191 bind6_handle = bind_args.handle;
193 error = vnet_bind (&bind_args);
194 SESSION_TEST ((error != 0), "double server bind6 should not work");
196 vnet_unbind_args_t unbind_args = {
197 .handle = bind4_handle,
198 .app_index = server_index,
200 error = vnet_unbind (&unbind_args);
201 SESSION_TEST ((error == 0), "unbind4 should work");
203 unbind_args.handle = bind6_handle;
204 error = vnet_unbind (&unbind_args);
205 SESSION_TEST ((error == 0), "unbind6 should work");
207 vnet_app_detach_args_t detach_args = {
208 .app_index = server_index,
210 vnet_application_detach (&detach_args);
215 session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
217 u64 options[APP_OPTIONS_N_OPTIONS], dummy_secret = 1234;
218 u32 server_index, server_st_index, server_local_st_index;
219 u32 dummy_port = 1234, client_index;
220 u32 dummy_api_context = 4321, dummy_client_api_index = 1234;
221 u32 dummy_server_api_index = ~0, sw_if_index = 0;
222 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
223 session_endpoint_t client_sep = SESSION_ENDPOINT_NULL;
224 session_endpoint_t intf_sep = SESSION_ENDPOINT_NULL;
225 clib_error_t *error = 0;
226 u8 *ns_id = format (0, "appns1");
227 app_namespace_t *app_ns;
228 application_t *server;
233 server_sep.is_ip4 = 1;
234 server_sep.port = dummy_port;
235 client_sep.is_ip4 = 1;
236 client_sep.port = dummy_port;
237 memset (options, 0, sizeof (options));
239 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
240 vnet_app_attach_args_t attach_args = {
241 .api_client_index = ~0,
244 .session_cb_vft = &dummy_session_cbs,
247 vnet_bind_args_t bind_args = {
252 vnet_connect_args_t connect_args = {
258 vnet_unbind_args_t unbind_args = {
259 .handle = bind_args.handle,
263 vnet_app_detach_args_t detach_args = {
267 ip4_address_t intf_addr = {
268 .as_u32 = clib_host_to_net_u32 (0x06000105),
271 intf_sep.ip.ip4 = intf_addr;
273 intf_sep.port = dummy_port;
276 * Insert namespace and lookup
279 vnet_app_namespace_add_del_args_t ns_args = {
281 .secret = dummy_secret,
282 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
285 error = vnet_app_namespace_add_del (&ns_args);
286 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
287 clib_error_get_code (error));
289 app_ns = app_namespace_get_from_id (ns_id);
290 SESSION_TEST ((app_ns != 0), "should find ns %v status", ns_id);
291 SESSION_TEST ((app_ns->ns_secret == dummy_secret), "secret should be %d",
293 SESSION_TEST ((app_ns->sw_if_index == APP_NAMESPACE_INVALID_INDEX),
294 "sw_if_index should be invalid");
297 * Try application attach with wrong secret
300 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
301 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
302 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret - 1;
303 attach_args.namespace_id = ns_id;
304 attach_args.api_client_index = dummy_server_api_index;
306 error = vnet_application_attach (&attach_args);
307 SESSION_TEST ((error != 0), "app attachment should fail");
308 code = clib_error_get_code (error);
309 SESSION_TEST ((code == VNET_API_ERROR_APP_WRONG_NS_SECRET),
310 "code should be wrong ns secret: %d", code);
313 * Attach server with global default scope
315 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
316 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
317 options[APP_OPTIONS_NAMESPACE_SECRET] = 0;
318 attach_args.namespace_id = 0;
319 attach_args.api_client_index = dummy_server_api_index;
320 error = vnet_application_attach (&attach_args);
321 SESSION_TEST ((error == 0), "server attachment should work");
322 server_index = attach_args.app_index;
323 server = application_get (server_index);
324 SESSION_TEST ((server->ns_index == 0),
325 "server should be in the default ns");
327 bind_args.app_index = server_index;
328 error = vnet_bind (&bind_args);
329 SESSION_TEST ((error == 0), "server bind should work");
331 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
332 s = session_lookup_listener (server_st_index, &server_sep);
333 SESSION_TEST ((s != 0), "listener should exist in global table");
334 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
336 server_local_st_index = application_local_session_table (server);
337 SESSION_TEST ((server_local_st_index == APP_INVALID_INDEX),
338 "server shouldn't have access to local table");
340 unbind_args.app_index = server_index;
341 unbind_args.handle = bind_args.handle;
342 error = vnet_unbind (&unbind_args);
343 SESSION_TEST ((error == 0), "unbind should work");
345 s = session_lookup_listener (server_st_index, &server_sep);
346 SESSION_TEST ((s == 0), "listener should not exist in global table");
348 detach_args.app_index = server_index;
349 vnet_application_detach (&detach_args);
352 * Attach server with local and global scope
354 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
355 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
356 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
357 attach_args.namespace_id = ns_id;
358 attach_args.api_client_index = dummy_server_api_index;
359 error = vnet_application_attach (&attach_args);
360 SESSION_TEST ((error == 0), "server attachment should work");
361 server_index = attach_args.app_index;
362 server = application_get (server_index);
363 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
364 "server should be in the right ns");
366 bind_args.app_index = server_index;
367 error = vnet_bind (&bind_args);
368 SESSION_TEST ((error == 0), "bind should work");
369 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
370 s = session_lookup_listener (server_st_index, &server_sep);
371 SESSION_TEST ((s != 0), "listener should exist in global table");
372 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
374 server_local_st_index = application_local_session_table (server);
375 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
376 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
377 "listener should exist in local table");
380 * Try client connect with 1) local scope 2) global scope
382 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
383 attach_args.api_client_index = dummy_client_api_index;
384 error = vnet_application_attach (&attach_args);
385 SESSION_TEST ((error == 0), "client attachment should work");
386 client_index = attach_args.app_index;
387 connect_args.api_context = dummy_api_context;
388 connect_args.app_index = client_index;
389 error = vnet_connect (&connect_args);
390 SESSION_TEST ((error != 0), "client connect should return error code");
391 code = clib_error_get_code (error);
392 SESSION_TEST ((code == VNET_API_ERROR_INVALID_VALUE),
393 "error code should be invalid value (zero ip)");
394 SESSION_TEST ((dummy_segment_count == 0),
395 "shouldn't have received request to map new segment");
396 connect_args.sep.ip.ip4.as_u8[0] = 127;
397 error = vnet_connect (&connect_args);
398 SESSION_TEST ((error == 0), "client connect should not return error code");
399 code = clib_error_get_code (error);
400 SESSION_TEST ((dummy_segment_count == 1),
401 "should've received request to map new segment");
402 SESSION_TEST ((dummy_accept == 1), "should've received accept request");
403 detach_args.app_index = client_index;
404 vnet_application_detach (&detach_args);
406 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
407 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
408 attach_args.api_client_index = dummy_client_api_index;
409 error = vnet_application_attach (&attach_args);
410 SESSION_TEST ((error == 0), "client attachment should work");
411 error = vnet_connect (&connect_args);
412 SESSION_TEST ((error != 0), "client connect should return error code");
413 code = clib_error_get_code (error);
414 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
415 "error code should be connect (nothing in local scope)");
416 detach_args.app_index = client_index;
417 vnet_application_detach (&detach_args);
420 * Unbind and detach server and then re-attach with local scope only
422 unbind_args.handle = bind_args.handle;
423 unbind_args.app_index = server_index;
424 error = vnet_unbind (&unbind_args);
425 SESSION_TEST ((error == 0), "unbind should work");
427 s = session_lookup_listener (server_st_index, &server_sep);
428 SESSION_TEST ((s == 0), "listener should not exist in global table");
429 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
430 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
431 "listener should not exist in local table");
433 detach_args.app_index = server_index;
434 vnet_application_detach (&detach_args);
436 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
437 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
438 attach_args.api_client_index = dummy_server_api_index;
439 error = vnet_application_attach (&attach_args);
440 SESSION_TEST ((error == 0), "app attachment should work");
441 server_index = attach_args.app_index;
442 server = application_get (server_index);
443 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
444 "app should be in the right ns");
446 bind_args.app_index = server_index;
447 error = vnet_bind (&bind_args);
448 SESSION_TEST ((error == 0), "bind should work");
450 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
451 s = session_lookup_listener (server_st_index, &server_sep);
452 SESSION_TEST ((s == 0), "listener should not exist in global table");
453 server_local_st_index = application_local_session_table (server);
454 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
455 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
456 "listener should exist in local table");
458 unbind_args.handle = bind_args.handle;
459 error = vnet_unbind (&unbind_args);
460 SESSION_TEST ((error == 0), "unbind should work");
462 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
463 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
464 "listener should not exist in local table");
467 * Client attach + connect in default ns with local scope
469 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
470 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
471 attach_args.namespace_id = 0;
472 attach_args.api_client_index = dummy_client_api_index;
473 vnet_application_attach (&attach_args);
474 error = vnet_connect (&connect_args);
475 SESSION_TEST ((error != 0), "client connect should return error code");
476 code = clib_error_get_code (error);
477 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
478 "error code should be connect (not in same ns)");
479 detach_args.app_index = client_index;
480 vnet_application_detach (&detach_args);
485 detach_args.app_index = server_index;
486 vnet_application_detach (&detach_args);
489 * Create loopback interface
491 session_create_lookpback (0, &sw_if_index, &intf_addr);
496 ns_args.sw_if_index = sw_if_index;
497 error = vnet_app_namespace_add_del (&ns_args);
498 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
499 clib_error_get_code (error));
502 * Attach server with local and global scope
504 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
505 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
506 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
507 attach_args.namespace_id = ns_id;
508 attach_args.api_client_index = dummy_server_api_index;
509 error = vnet_application_attach (&attach_args);
510 SESSION_TEST ((error == 0), "server attachment should work");
511 server_index = attach_args.app_index;
513 bind_args.app_index = server_index;
514 error = vnet_bind (&bind_args);
515 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
516 s = session_lookup_listener (server_st_index, &server_sep);
517 SESSION_TEST ((s == 0), "zero listener should not exist in global table");
519 s = session_lookup_listener (server_st_index, &intf_sep);
520 SESSION_TEST ((s != 0), "intf listener should exist in global table");
521 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
523 server_local_st_index = application_local_session_table (server);
524 handle = session_lookup_local_endpoint (server_local_st_index, &server_sep);
525 SESSION_TEST ((handle != SESSION_INVALID_HANDLE),
526 "zero listener should exist in local table");
527 detach_args.app_index = server_index;
528 vnet_application_detach (&detach_args);
534 session_delete_loopback (sw_if_index);
539 session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
541 session_rules_table_t _srt, *srt = &_srt;
542 u16 lcl_port = 1234, rmt_port = 4321;
543 u32 action_index = 1, res;
544 ip4_address_t lcl_lkup, rmt_lkup;
548 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
550 if (unformat (input, "verbose"))
554 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
560 memset (srt, 0, sizeof (*srt));
561 session_rules_table_init (srt);
563 ip4_address_t lcl_ip = {
564 .as_u32 = clib_host_to_net_u32 (0x01020304),
566 ip4_address_t rmt_ip = {
567 .as_u32 = clib_host_to_net_u32 (0x05060708),
569 ip4_address_t lcl_ip2 = {
570 .as_u32 = clib_host_to_net_u32 (0x02020202),
572 ip4_address_t rmt_ip2 = {
573 .as_u32 = clib_host_to_net_u32 (0x06060606),
575 ip4_address_t lcl_ip3 = {
576 .as_u32 = clib_host_to_net_u32 (0x03030303),
578 ip4_address_t rmt_ip3 = {
579 .as_u32 = clib_host_to_net_u32 (0x07070707),
581 fib_prefix_t lcl_pref = {
582 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
584 .fp_proto = FIB_PROTOCOL_IP4,
586 fib_prefix_t rmt_pref = {
587 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
589 .fp_proto = FIB_PROTOCOL_IP4,
592 session_rule_table_add_del_args_t args = {
595 .lcl_port = lcl_port,
596 .rmt_port = rmt_port,
597 .action_index = action_index++,
600 error = session_rules_table_add_del (srt, &args);
601 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
605 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
606 SESSION_TEST ((res == 1),
607 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
611 * 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
613 args.lcl.fp_addr.ip4 = lcl_ip;
614 args.lcl.fp_len = 24;
615 args.action_index = action_index++;
616 error = session_rules_table_add_del (srt, &args);
617 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/16 4321 action %d",
619 args.rmt.fp_addr.ip4 = rmt_ip;
620 args.rmt.fp_len = 24;
621 args.action_index = action_index++;
622 error = session_rules_table_add_del (srt, &args);
623 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/24 4321 action %d",
627 * 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
629 args.lcl.fp_addr.ip4 = lcl_ip2;
630 args.lcl.fp_len = 24;
631 args.rmt.fp_addr.ip4 = rmt_ip2;
632 args.rmt.fp_len = 16;
633 args.action_index = action_index++;
634 error = session_rules_table_add_del (srt, &args);
635 SESSION_TEST ((error == 0), "Add 2.2.2.2/24 1234 6.6.6.6/16 4321 action %d",
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), "Add 3.3.3.3/24 1234 7.7.7.7/16 4321 action %d",
645 * Add again 3.3.3.3/24 1234 7.7.7.7/16 4321
647 args.lcl.fp_addr.ip4 = lcl_ip3;
648 args.rmt.fp_addr.ip4 = rmt_ip3;
649 args.action_index = action_index++;
650 error = session_rules_table_add_del (srt, &args);
651 SESSION_TEST ((error == 0), "overwrite 3.3.3.3/24 1234 7.7.7.7/16 4321 "
652 "action %d", action_index - 1);
655 * 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
656 * and 3.3.3.3 1234 7.7.7.7 4321
659 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
660 SESSION_TEST ((res == 3),
661 "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
664 lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
665 rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
667 session_rules_table_lookup4 (srt, &lcl_lkup,
668 &rmt_lkup, lcl_port, rmt_port);
669 SESSION_TEST ((res == 1),
670 "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
674 session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
675 SESSION_TEST ((res == 6),
676 "Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
677 "should be 6 (updated): %d", res);
680 * Add 1.2.3.4/24 * 5.6.7.8/24 *
681 * Lookup 1.2.3.4 1234 5.6.7.8 4321 and 1.2.3.4 1235 5.6.7.8 4321
683 args.lcl.fp_addr.ip4 = lcl_ip;
684 args.rmt.fp_addr.ip4 = rmt_ip;
685 args.lcl.fp_len = 24;
686 args.rmt.fp_len = 24;
689 args.action_index = action_index++;
690 error = session_rules_table_add_del (srt, &args);
691 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
694 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
695 SESSION_TEST ((res == 7),
696 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
697 " be 7 (lpm dst): %d", res);
699 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
700 lcl_port + 1, rmt_port);
701 SESSION_TEST ((res == 7),
702 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
706 * Del 1.2.3.4/24 * 5.6.7.8/24 *
707 * Add 1.2.3.4/16 * 5.6.7.8/16 * and 1.2.3.4/24 1235 5.6.7.8/24 4321
708 * Lookup 1.2.3.4 1234 5.6.7.8 4321, 1.2.3.4 1235 5.6.7.8 4321 and
709 * 1.2.3.4 1235 5.6.7.8 4322
712 error = session_rules_table_add_del (srt, &args);
713 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 * 5.6.7.8/24 *");
715 args.lcl.fp_addr.ip4 = lcl_ip;
716 args.rmt.fp_addr.ip4 = rmt_ip;
717 args.lcl.fp_len = 16;
718 args.rmt.fp_len = 16;
721 args.action_index = action_index++;
723 error = session_rules_table_add_del (srt, &args);
724 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 * action %d",
727 args.lcl.fp_addr.ip4 = lcl_ip;
728 args.rmt.fp_addr.ip4 = rmt_ip;
729 args.lcl.fp_len = 24;
730 args.rmt.fp_len = 24;
731 args.lcl_port = lcl_port + 1;
732 args.rmt_port = rmt_port;
733 args.action_index = action_index++;
735 error = session_rules_table_add_del (srt, &args);
736 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1235 5.6.7.8/24 4321 action %d",
740 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
743 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
744 SESSION_TEST ((res == 3),
745 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
748 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
749 lcl_port + 1, rmt_port);
750 SESSION_TEST ((res == 9),
751 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
754 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
755 lcl_port + 1, rmt_port + 1);
756 SESSION_TEST ((res == 8),
757 "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
761 * Delete 1.2.0.0/16 1234 5.6.0.0/16 4321 and 1.2.0.0/16 * 5.6.0.0/16 *
762 * Lookup 1.2.3.4 1234 5.6.7.8 4321
764 args.lcl_port = 1234;
765 args.rmt_port = 4321;
766 args.lcl.fp_len = 16;
767 args.rmt.fp_len = 16;
769 error = session_rules_table_add_del (srt, &args);
770 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
772 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
773 SESSION_TEST ((res == 3),
774 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
780 error = session_rules_table_add_del (srt, &args);
781 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
783 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
784 SESSION_TEST ((res == 3),
785 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
789 * Delete 1.2.3.4/24 1234 5.6.7.5/24
791 args.lcl.fp_addr.ip4 = lcl_ip;
792 args.rmt.fp_addr.ip4 = rmt_ip;
793 args.lcl.fp_len = 24;
794 args.rmt.fp_len = 24;
795 args.lcl_port = 1234;
796 args.rmt_port = 4321;
798 error = session_rules_table_add_del (srt, &args);
799 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
801 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
802 SESSION_TEST ((res == 2), "Action should be 2: %d", res);
808 session_test_rules (vlib_main_t * vm, unformat_input_t * input)
810 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
811 u64 options[APP_OPTIONS_N_OPTIONS];
812 u16 lcl_port = 1234, rmt_port = 4321;
813 u32 server_index, server_index2;
814 u32 dummy_server_api_index = ~0;
815 transport_connection_t *tc;
816 u32 dummy_port = 1111;
817 clib_error_t *error = 0;
818 u8 is_filtered = 0, *ns_id = format (0, "appns1");
819 stream_session_t *listener, *s;
820 app_namespace_t *default_ns = app_namespace_get_default ();
821 u32 local_ns_index = default_ns->local_table_index;
823 app_namespace_t *app_ns;
826 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
828 if (unformat (input, "verbose"))
832 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
838 server_sep.is_ip4 = 1;
839 server_sep.port = dummy_port;
840 memset (options, 0, sizeof (options));
842 vnet_app_attach_args_t attach_args = {
843 .api_client_index = ~0,
846 .session_cb_vft = &dummy_session_cbs,
849 vnet_bind_args_t bind_args = {
855 * Attach server with global and local default scope
857 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
858 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
859 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
860 attach_args.namespace_id = 0;
861 attach_args.api_client_index = dummy_server_api_index;
862 error = vnet_application_attach (&attach_args);
863 SESSION_TEST ((error == 0), "server attached");
864 server_index = attach_args.app_index;
866 bind_args.app_index = server_index;
867 error = vnet_bind (&bind_args);
868 SESSION_TEST ((error == 0), "server bound to %U/%d", format_ip46_address,
869 &server_sep.ip, 1, server_sep.port);
870 listener = listen_session_get_from_handle (bind_args.handle);
871 ip4_address_t lcl_ip = {
872 .as_u32 = clib_host_to_net_u32 (0x01020304),
874 ip4_address_t rmt_ip = {
875 .as_u32 = clib_host_to_net_u32 (0x05060708),
877 fib_prefix_t lcl_pref = {
878 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
880 .fp_proto = FIB_PROTOCOL_IP4,
882 fib_prefix_t rmt_pref = {
883 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
885 .fp_proto = FIB_PROTOCOL_IP4,
888 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
889 &rmt_pref.fp_addr.ip4, lcl_port,
890 rmt_port, TRANSPORT_PROTO_TCP, 0,
892 SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
895 * Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action server_index
897 session_rule_add_del_args_t args = {
898 .table_args.lcl = lcl_pref,
899 .table_args.rmt = rmt_pref,
900 .table_args.lcl_port = lcl_port,
901 .table_args.rmt_port = rmt_port,
902 .table_args.action_index = server_index,
903 .table_args.is_add = 1,
906 error = vnet_session_rule_add_del (&args);
907 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
908 args.table_args.action_index);
910 tc = session_lookup_connection4 (0, &lcl_pref.fp_addr.ip4,
911 &rmt_pref.fp_addr.ip4, lcl_port, rmt_port,
912 TRANSPORT_PROTO_TCP);
913 SESSION_TEST ((tc->c_index == listener->connection_index),
914 "optimized lookup should return the listener");
915 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
916 &rmt_pref.fp_addr.ip4, lcl_port,
917 rmt_port, TRANSPORT_PROTO_TCP, 0,
919 SESSION_TEST ((tc->c_index == listener->connection_index),
920 "lookup should return the listener");
921 s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
922 lcl_port, rmt_port, TRANSPORT_PROTO_TCP);
923 SESSION_TEST ((s->connection_index == listener->connection_index),
924 "safe lookup should return the listener");
925 session_endpoint_t sep = {
926 .ip = rmt_pref.fp_addr,
929 .transport_proto = TRANSPORT_PROTO_TCP,
931 handle = session_lookup_local_endpoint (local_ns_index, &sep);
932 SESSION_TEST ((handle != server_index), "local session endpoint lookup "
933 "should not work (global scope)");
935 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
936 &rmt_pref.fp_addr.ip4, lcl_port + 1,
937 rmt_port, TRANSPORT_PROTO_TCP, 0,
939 SESSION_TEST ((tc == 0),
940 "optimized lookup for wrong lcl port + 1 should not work");
943 * Add 1.2.3.4/16 * 5.6.7.8/16 4321
945 args.table_args.lcl_port = 0;
946 args.scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
947 error = vnet_session_rule_add_del (&args);
948 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 4321 action %d",
949 args.table_args.action_index);
950 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
951 &rmt_pref.fp_addr.ip4, lcl_port + 1,
952 rmt_port, TRANSPORT_PROTO_TCP, 0,
954 SESSION_TEST ((tc->c_index == listener->connection_index),
955 "optimized lookup for lcl port + 1 should work");
956 handle = session_lookup_local_endpoint (local_ns_index, &sep);
957 SESSION_TEST ((handle == server_index), "local session endpoint lookup "
958 "should work (lcl ip was zeroed)");
961 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
963 args.table_args.lcl_port = 1234;
964 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
965 args.table_args.lcl.fp_len = 30;
966 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
967 args.table_args.rmt.fp_len = 30;
968 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
969 error = vnet_session_rule_add_del (&args);
970 SESSION_TEST ((error == 0), "Add 1.2.3.4/30 1234 5.6.7.8/30 4321 action %d",
971 args.table_args.action_index);
975 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
976 TRANSPORT_PROTO_TCP);
977 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
978 TRANSPORT_PROTO_TCP);
981 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
982 &rmt_pref.fp_addr.ip4, lcl_port,
983 rmt_port, TRANSPORT_PROTO_TCP, 0,
985 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
986 "should fail (deny rule)");
987 SESSION_TEST ((is_filtered == 1), "lookup should be filtered (deny)");
989 handle = session_lookup_local_endpoint (local_ns_index, &sep);
990 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
991 "5.6.7.8/16 4321 in local table should return deny");
993 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
994 &rmt_pref.fp_addr.ip4, lcl_port + 1,
995 rmt_port, TRANSPORT_PROTO_TCP, 0,
997 SESSION_TEST ((tc->c_index == listener->connection_index),
998 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should work");
1001 * "Mask" deny rule with more specific allow:
1002 * Add allow rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -3 (allow)
1004 args.table_args.is_add = 1;
1005 args.table_args.lcl_port = 1234;
1006 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1007 args.table_args.lcl.fp_len = 32;
1008 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1009 args.table_args.rmt.fp_len = 32;
1010 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1011 error = vnet_session_rule_add_del (&args);
1012 SESSION_TEST ((error == 0), "Add masking rule 1.2.3.4/30 1234 5.6.7.8/32 "
1013 "4321 action %d", args.table_args.action_index);
1016 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1017 &rmt_pref.fp_addr.ip4, lcl_port,
1018 rmt_port, TRANSPORT_PROTO_TCP, 0,
1020 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
1021 "should fail (allow without app)");
1022 SESSION_TEST ((is_filtered == 0), "lookup should NOT be filtered");
1024 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1025 SESSION_TEST ((handle == SESSION_INVALID_HANDLE), "lookup for 1.2.3.4/32 "
1026 "1234 5.6.7.8/32 4321 in local table should return invalid");
1030 vlib_cli_output (vm, "Local rules");
1031 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1032 TRANSPORT_PROTO_TCP);
1035 sep.ip.ip4.as_u32 += 1 << 24;
1036 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1037 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234"
1038 " 5.6.7.9/32 4321 in local table should return deny");
1040 vnet_connect_args_t connect_args = {
1042 .app_index = attach_args.app_index,
1046 /* Try connecting */
1047 error = vnet_connect (&connect_args);
1048 SESSION_TEST ((error != 0), "connect should fail");
1049 rv = clib_error_get_code (error);
1050 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1051 "connect should be filtered");
1053 sep.ip.ip4.as_u32 -= 1 << 24;
1056 * Delete masking rule: 1.2.3.4/32 1234 5.6.7.8/32 4321 allow
1058 args.table_args.is_add = 0;
1059 args.table_args.lcl_port = 1234;
1060 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1061 args.table_args.lcl.fp_len = 32;
1062 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1063 args.table_args.rmt.fp_len = 32;
1064 error = vnet_session_rule_add_del (&args);
1065 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 allow");
1069 * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
1071 args.table_args.is_add = 1;
1072 args.table_args.lcl_port = 0;
1073 args.table_args.lcl.fp_len = 0;
1074 args.table_args.rmt.fp_len = 16;
1075 args.table_args.action_index = -1;
1076 error = vnet_session_rule_add_del (&args);
1077 SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d",
1078 args.table_args.action_index);
1082 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1083 TRANSPORT_PROTO_TCP);
1084 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1085 TRANSPORT_PROTO_TCP);
1088 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1089 SESSION_TEST ((handle == SESSION_DROP_HANDLE),
1090 "local session endpoint lookup should return deny");
1093 * Delete 1.2.3.4/32 1234 5.6.7.8/32 4321 deny
1095 args.table_args.is_add = 0;
1096 args.table_args.lcl_port = 1234;
1097 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1098 args.table_args.lcl.fp_len = 30;
1099 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1100 args.table_args.rmt.fp_len = 30;
1101 error = vnet_session_rule_add_del (&args);
1102 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1104 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1105 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
1106 "local session endpoint lookup should return invalid");
1109 * Delete 0/0 * 5.6.7.8/16 4321, 1.2.3.4/16 * 5.6.7.8/16 4321 and
1110 * 1.2.3.4/16 1234 5.6.7.8/16 4321
1112 args.table_args.is_add = 0;
1113 args.table_args.lcl_port = 0;
1114 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1115 args.table_args.lcl.fp_len = 0;
1116 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1117 args.table_args.rmt.fp_len = 16;
1118 args.table_args.rmt_port = 4321;
1119 error = vnet_session_rule_add_del (&args);
1120 SESSION_TEST ((error == 0), "Del 0/0 * 5.6.7.8/16 4321");
1121 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1122 SESSION_TEST ((handle != server_index), "local session endpoint lookup "
1123 "should not work (removed)");
1125 args.table_args.is_add = 0;
1126 args.table_args.lcl = lcl_pref;
1128 args.table_args.is_add = 0;
1129 args.table_args.lcl_port = 0;
1130 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1131 args.table_args.lcl.fp_len = 16;
1132 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1133 args.table_args.rmt.fp_len = 16;
1134 args.table_args.rmt_port = 4321;
1135 error = vnet_session_rule_add_del (&args);
1136 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
1137 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1138 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1139 rmt_port, TRANSPORT_PROTO_TCP, 0,
1141 SESSION_TEST ((tc == 0),
1142 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should not "
1145 args.table_args.is_add = 0;
1146 args.table_args.lcl_port = 1234;
1147 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1148 args.table_args.lcl.fp_len = 16;
1149 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1150 args.table_args.rmt.fp_len = 16;
1151 args.table_args.rmt_port = 4321;
1152 error = vnet_session_rule_add_del (&args);
1153 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
1154 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1155 &rmt_pref.fp_addr.ip4, lcl_port,
1156 rmt_port, TRANSPORT_PROTO_TCP, 0,
1158 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should "
1159 "not work (del + deny)");
1161 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1162 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1163 &rmt_pref.fp_addr.ip4, lcl_port,
1164 rmt_port, TRANSPORT_PROTO_TCP, 0,
1166 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should"
1167 " not work (no-rule)");
1170 * Test tags. Add/overwrite/del rule with tag
1172 args.table_args.is_add = 1;
1173 args.table_args.lcl_port = 1234;
1174 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1175 args.table_args.lcl.fp_len = 16;
1176 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1177 args.table_args.rmt.fp_len = 16;
1178 args.table_args.rmt_port = 4321;
1179 args.table_args.tag = format (0, "test_rule");
1180 args.table_args.action_index = server_index;
1181 error = vnet_session_rule_add_del (&args);
1182 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 deny "
1186 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1187 TRANSPORT_PROTO_TCP);
1188 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1189 TRANSPORT_PROTO_TCP);
1191 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1192 &rmt_pref.fp_addr.ip4, lcl_port,
1193 rmt_port, TRANSPORT_PROTO_TCP, 0,
1195 SESSION_TEST ((tc->c_index == listener->connection_index),
1196 "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should work");
1198 vec_free (args.table_args.tag);
1199 args.table_args.lcl_port = 1234;
1200 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1201 args.table_args.lcl.fp_len = 16;
1202 args.table_args.tag = format (0, "test_rule_overwrite");
1203 error = vnet_session_rule_add_del (&args);
1204 SESSION_TEST ((error == 0),
1205 "Overwrite 1.2.3.4/16 1234 5.6.7.8/16 4321 deny tag test_rule"
1209 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1210 TRANSPORT_PROTO_TCP);
1211 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1212 TRANSPORT_PROTO_TCP);
1215 args.table_args.is_add = 0;
1216 args.table_args.lcl_port += 1;
1217 error = vnet_session_rule_add_del (&args);
1218 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny "
1219 "tag %v", args.table_args.tag);
1222 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1223 TRANSPORT_PROTO_TCP);
1224 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1225 TRANSPORT_PROTO_TCP);
1227 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1228 &rmt_pref.fp_addr.ip4, lcl_port,
1229 rmt_port, TRANSPORT_PROTO_TCP, 0,
1231 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/32 4321 should not"
1236 * Test local rules with multiple namespaces
1240 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1242 args.table_args.is_add = 1;
1243 args.table_args.lcl_port = 1234;
1244 args.table_args.rmt_port = 0;
1245 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1246 args.table_args.lcl.fp_len = 32;
1247 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1248 args.table_args.rmt.fp_len = 32;
1249 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1250 args.table_args.tag = 0;
1251 args.scope = SESSION_RULE_SCOPE_LOCAL;
1252 error = vnet_session_rule_add_del (&args);
1253 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
1254 args.table_args.action_index);
1256 * Add 'white' rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
1258 args.table_args.is_add = 1;
1259 args.table_args.lcl_port = 1234;
1260 args.table_args.rmt_port = 4321;
1261 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1262 args.table_args.lcl.fp_len = 32;
1263 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1264 args.table_args.rmt.fp_len = 32;
1265 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1266 error = vnet_session_rule_add_del (&args);
1270 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1271 TRANSPORT_PROTO_TCP);
1274 vnet_app_namespace_add_del_args_t ns_args = {
1277 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
1280 error = vnet_app_namespace_add_del (&ns_args);
1281 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
1282 clib_error_get_code (error));
1283 app_ns = app_namespace_get_from_id (ns_id);
1285 attach_args.namespace_id = ns_id;
1286 attach_args.api_client_index = dummy_server_api_index - 1;
1287 error = vnet_application_attach (&attach_args);
1288 SESSION_TEST ((error == 0), "server2 attached");
1289 server_index2 = attach_args.app_index;
1292 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1294 args.table_args.lcl_port = 1234;
1295 args.table_args.rmt_port = 0;
1296 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1297 args.table_args.lcl.fp_len = 32;
1298 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1299 args.table_args.rmt.fp_len = 32;
1300 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1301 args.appns_index = app_namespace_index (app_ns);
1303 error = vnet_session_rule_add_del (&args);
1304 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d "
1305 "in test namespace", args.table_args.action_index);
1307 * Lookup default namespace
1309 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1310 SESSION_TEST ((handle == SESSION_INVALID_HANDLE),
1311 "lookup for 1.2.3.4/32 1234 5.6.7.8/32 4321 in local table "
1312 "should return allow (invalid)");
1315 handle = session_lookup_local_endpoint (local_ns_index, &sep);
1316 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1317 "5.6.7.8/16 432*2* in local table should return deny");
1319 connect_args.app_index = server_index;
1320 connect_args.sep = sep;
1321 error = vnet_connect (&connect_args);
1322 SESSION_TEST ((error != 0), "connect should fail");
1323 rv = clib_error_get_code (error);
1324 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1325 "connect should be filtered");
1328 * Lookup test namespace
1330 handle = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1331 SESSION_TEST ((handle == SESSION_DROP_HANDLE), "lookup for 1.2.3.4/32 1234 "
1332 "5.6.7.8/16 4321 in local table should return deny");
1334 connect_args.app_index = server_index;
1335 error = vnet_connect (&connect_args);
1336 SESSION_TEST ((error != 0), "connect should fail");
1337 rv = clib_error_get_code (error);
1338 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1339 "connect should be filtered");
1341 args.table_args.is_add = 0;
1342 vnet_session_rule_add_del (&args);
1344 args.appns_index = 0;
1345 args.table_args.is_add = 0;
1346 vnet_session_rule_add_del (&args);
1348 args.table_args.rmt_port = 4321;
1349 vnet_session_rule_add_del (&args);
1353 vec_free (args.table_args.tag);
1354 vnet_app_detach_args_t detach_args = {
1355 .app_index = server_index,
1357 vnet_application_detach (&detach_args);
1359 detach_args.app_index = server_index2;
1360 vnet_application_detach (&detach_args);
1367 session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
1369 u64 options[APP_OPTIONS_N_OPTIONS];
1370 char *show_listeners = "sh session listeners tcp verbose";
1371 char *show_local_listeners = "sh app ns table default";
1372 unformat_input_t tmp_input;
1373 u32 server_index, app_index;
1374 u32 dummy_server_api_index = ~0, sw_if_index = 0;
1375 clib_error_t *error = 0;
1376 u8 sst, is_filtered = 0;
1377 stream_session_t *s;
1378 transport_connection_t *tc;
1379 u16 lcl_port = 1234, rmt_port = 4321;
1380 app_namespace_t *app_ns;
1383 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1385 if (unformat (input, "verbose"))
1389 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1395 ip4_address_t lcl_ip = {
1396 .as_u32 = clib_host_to_net_u32 (0x01020304),
1398 ip4_address_t rmt_ip = {
1399 .as_u32 = clib_host_to_net_u32 (0x05060708),
1401 fib_prefix_t rmt_pref = {
1402 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1404 .fp_proto = FIB_PROTOCOL_IP4,
1406 session_endpoint_t sep = {
1407 .ip = rmt_pref.fp_addr,
1410 .transport_proto = TRANSPORT_PROTO_TCP,
1414 * Create loopback interface
1416 session_create_lookpback (0, &sw_if_index, &lcl_ip);
1418 app_ns = app_namespace_get_default ();
1419 app_ns->sw_if_index = sw_if_index;
1421 memset (options, 0, sizeof (options));
1422 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
1423 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
1424 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_IS_PROXY;
1425 options[APP_OPTIONS_PROXY_TRANSPORT] = 1 << TRANSPORT_PROTO_TCP;
1426 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1427 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1428 vnet_app_attach_args_t attach_args = {
1429 .api_client_index = ~0,
1432 .session_cb_vft = &dummy_session_cbs,
1435 attach_args.api_client_index = dummy_server_api_index;
1436 error = vnet_application_attach (&attach_args);
1437 SESSION_TEST ((error == 0), "server attachment should work");
1438 server_index = attach_args.app_index;
1442 unformat_init_string (&tmp_input, show_listeners,
1443 strlen (show_listeners));
1444 vlib_cli_input (vm, &tmp_input, 0, 0);
1445 unformat_init_string (&tmp_input, show_local_listeners,
1446 strlen (show_local_listeners));
1447 vlib_cli_input (vm, &tmp_input, 0, 0);
1450 tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
1451 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1452 SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
1454 sst = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, 1);
1455 s = listen_session_get (sst, tc->s_index);
1456 SESSION_TEST ((s->app_index == server_index), "lookup should return the"
1459 tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
1460 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1461 SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
1464 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1465 SESSION_TEST ((app_index == server_index), "local session endpoint lookup"
1468 vnet_app_detach_args_t detach_args = {
1469 .app_index = server_index,
1471 vnet_application_detach (&detach_args);
1475 unformat_init_string (&tmp_input, show_listeners,
1476 strlen (show_listeners));
1477 vlib_cli_input (vm, &tmp_input, 0, 0);
1478 unformat_init_string (&tmp_input, show_local_listeners,
1479 strlen (show_local_listeners));
1480 vlib_cli_input (vm, &tmp_input, 0, 0);
1483 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1484 SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
1485 "local session endpoint lookup should not work after detach");
1487 unformat_free (&tmp_input);
1491 static clib_error_t *
1492 session_test (vlib_main_t * vm,
1493 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
1497 vnet_session_enable_disable (vm, 1);
1499 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1501 if (unformat (input, "basic"))
1502 res = session_test_basic (vm, input);
1503 else if (unformat (input, "namespace"))
1504 res = session_test_namespace (vm, input);
1505 else if (unformat (input, "rules-table"))
1506 res = session_test_rule_table (vm, input);
1507 else if (unformat (input, "rules"))
1508 res = session_test_rules (vm, input);
1509 else if (unformat (input, "proxy"))
1510 res = session_test_proxy (vm, input);
1511 else if (unformat (input, "all"))
1513 if ((res = session_test_basic (vm, input)))
1515 if ((res = session_test_namespace (vm, input)))
1517 if ((res = session_test_rule_table (vm, input)))
1519 if ((res = session_test_rules (vm, input)))
1521 if ((res = session_test_proxy (vm, input)))
1530 return clib_error_return (0, "Session unit test failed");
1535 VLIB_CLI_COMMAND (tcp_test_command, static) =
1537 .path = "test session",
1538 .short_help = "internal session unit tests",
1539 .function = session_test,
1544 * fd.io coding-style-patch-verification: ON
1547 * eval: (c-set-style "gnu")