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_test_basic (vlib_main_t * vm, unformat_input_t * input)
104 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
105 u64 options[APP_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle;
106 clib_error_t *error = 0;
109 memset (options, 0, sizeof (options));
110 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
111 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
112 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
113 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
114 vnet_app_attach_args_t attach_args = {
115 .api_client_index = ~0,
118 .session_cb_vft = &dummy_session_cbs,
121 error = vnet_application_attach (&attach_args);
122 SESSION_TEST ((error == 0), "app attached");
123 server_index = attach_args.app_index;
125 server_sep.is_ip4 = 1;
126 vnet_bind_args_t bind_args = {
131 bind_args.app_index = server_index;
132 error = vnet_bind (&bind_args);
133 SESSION_TEST ((error == 0), "server bind4 should work");
134 bind4_handle = bind_args.handle;
136 error = vnet_bind (&bind_args);
137 SESSION_TEST ((error != 0), "double server bind4 should not work");
139 bind_args.sep.is_ip4 = 0;
140 error = vnet_bind (&bind_args);
141 SESSION_TEST ((error == 0), "server bind6 should work");
142 bind6_handle = bind_args.handle;
144 error = vnet_bind (&bind_args);
145 SESSION_TEST ((error != 0), "double server bind6 should not work");
147 vnet_unbind_args_t unbind_args = {
148 .handle = bind4_handle,
149 .app_index = server_index,
151 error = vnet_unbind (&unbind_args);
152 SESSION_TEST ((error == 0), "unbind4 should work");
154 unbind_args.handle = bind6_handle;
155 error = vnet_unbind (&unbind_args);
156 SESSION_TEST ((error == 0), "unbind6 should work");
158 vnet_app_detach_args_t detach_args = {
159 .app_index = server_index,
161 vnet_application_detach (&detach_args);
166 session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
168 u64 options[APP_OPTIONS_N_OPTIONS], dummy_secret = 1234;
169 u32 server_index, server_st_index, server_local_st_index;
170 u32 dummy_port = 1234, local_listener, client_index;
171 u32 dummy_api_context = 4321, dummy_client_api_index = 1234;
172 u32 dummy_server_api_index = ~0, sw_if_index = 0;
173 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
174 session_endpoint_t client_sep = SESSION_ENDPOINT_NULL;
175 session_endpoint_t intf_sep = SESSION_ENDPOINT_NULL;
176 clib_error_t *error = 0;
177 u8 *ns_id = format (0, "appns1"), intf_mac[6];
178 app_namespace_t *app_ns;
179 application_t *server;
183 server_sep.is_ip4 = 1;
184 server_sep.port = dummy_port;
185 client_sep.is_ip4 = 1;
186 client_sep.port = dummy_port;
187 memset (options, 0, sizeof (options));
188 memset (intf_mac, 0, sizeof (intf_mac));
190 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
191 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
192 vnet_app_attach_args_t attach_args = {
193 .api_client_index = ~0,
196 .session_cb_vft = &dummy_session_cbs,
199 vnet_bind_args_t bind_args = {
204 vnet_connect_args_t connect_args = {
210 vnet_unbind_args_t unbind_args = {
211 .handle = bind_args.handle,
215 vnet_app_detach_args_t detach_args = {
219 ip4_address_t intf_addr = {
220 .as_u32 = clib_host_to_net_u32 (0x06000105),
223 intf_sep.ip.ip4 = intf_addr;
225 intf_sep.port = dummy_port;
228 * Insert namespace and lookup
231 vnet_app_namespace_add_del_args_t ns_args = {
233 .secret = dummy_secret,
234 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
237 error = vnet_app_namespace_add_del (&ns_args);
238 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
239 clib_error_get_code (error));
241 app_ns = app_namespace_get_from_id (ns_id);
242 SESSION_TEST ((app_ns != 0), "should find ns %v status", ns_id);
243 SESSION_TEST ((app_ns->ns_secret == dummy_secret), "secret should be %d",
245 SESSION_TEST ((app_ns->sw_if_index == APP_NAMESPACE_INVALID_INDEX),
246 "sw_if_index should be invalid");
249 * Try application attach with wrong secret
252 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
253 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
254 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret - 1;
255 attach_args.namespace_id = ns_id;
256 attach_args.api_client_index = dummy_server_api_index;
258 error = vnet_application_attach (&attach_args);
259 SESSION_TEST ((error != 0), "app attachment should fail");
260 code = clib_error_get_code (error);
261 SESSION_TEST ((code == VNET_API_ERROR_APP_WRONG_NS_SECRET),
262 "code should be wrong ns secret: %d", code);
265 * Attach server with global default scope
267 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
268 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
269 options[APP_OPTIONS_NAMESPACE_SECRET] = 0;
270 attach_args.namespace_id = 0;
271 attach_args.api_client_index = dummy_server_api_index;
272 error = vnet_application_attach (&attach_args);
273 SESSION_TEST ((error == 0), "server attachment should work");
274 server_index = attach_args.app_index;
275 server = application_get (server_index);
276 SESSION_TEST ((server->ns_index == 0),
277 "server should be in the default ns");
279 bind_args.app_index = server_index;
280 error = vnet_bind (&bind_args);
281 SESSION_TEST ((error == 0), "server bind should work");
283 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
284 s = session_lookup_listener (server_st_index, &server_sep);
285 SESSION_TEST ((s != 0), "listener should exist in global table");
286 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
288 server_local_st_index = application_local_session_table (server);
289 SESSION_TEST ((server_local_st_index == APP_INVALID_INDEX),
290 "server shouldn't have access to local table");
292 unbind_args.app_index = server_index;
293 unbind_args.handle = bind_args.handle;
294 error = vnet_unbind (&unbind_args);
295 SESSION_TEST ((error == 0), "unbind should work");
297 s = session_lookup_listener (server_st_index, &server_sep);
298 SESSION_TEST ((s == 0), "listener should not exist in global table");
300 detach_args.app_index = server_index;
301 vnet_application_detach (&detach_args);
304 * Attach server with local and global scope
306 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
307 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
308 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
309 attach_args.namespace_id = ns_id;
310 attach_args.api_client_index = dummy_server_api_index;
311 error = vnet_application_attach (&attach_args);
312 SESSION_TEST ((error == 0), "server attachment should work");
313 server_index = attach_args.app_index;
314 server = application_get (server_index);
315 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
316 "server should be in the right ns");
318 bind_args.app_index = server_index;
319 error = vnet_bind (&bind_args);
320 SESSION_TEST ((error == 0), "bind should work");
321 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
322 s = session_lookup_listener (server_st_index, &server_sep);
323 SESSION_TEST ((s != 0), "listener should exist in global table");
324 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
326 server_local_st_index = application_local_session_table (server);
328 session_lookup_local_endpoint (server_local_st_index, &server_sep);
329 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
330 "listener should exist in local table");
333 * Try client connect with 1) local scope 2) global scope
335 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
336 attach_args.api_client_index = dummy_client_api_index;
337 error = vnet_application_attach (&attach_args);
338 SESSION_TEST ((error == 0), "client attachment should work");
339 client_index = attach_args.app_index;
340 connect_args.api_context = dummy_api_context;
341 connect_args.app_index = client_index;
342 error = vnet_connect (&connect_args);
343 SESSION_TEST ((error != 0), "client connect should return error code");
344 code = clib_error_get_code (error);
345 SESSION_TEST ((code == VNET_API_ERROR_INVALID_VALUE),
346 "error code should be invalid value (zero ip)");
347 connect_args.sep.ip.ip4.as_u8[0] = 127;
348 error = vnet_connect (&connect_args);
349 SESSION_TEST ((error != 0), "client connect should return error code");
350 code = clib_error_get_code (error);
351 SESSION_TEST ((code == VNET_API_ERROR_SESSION_REDIRECT),
352 "error code should be redirect");
353 detach_args.app_index = client_index;
354 vnet_application_detach (&detach_args);
356 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
357 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
358 attach_args.api_client_index = dummy_client_api_index;
359 error = vnet_application_attach (&attach_args);
360 SESSION_TEST ((error == 0), "client attachment should work");
361 error = vnet_connect (&connect_args);
362 SESSION_TEST ((error != 0), "client connect should return error code");
363 code = clib_error_get_code (error);
364 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
365 "error code should be connect (nothing in local scope)");
366 detach_args.app_index = client_index;
367 vnet_application_detach (&detach_args);
370 * Unbind and detach server and then re-attach with local scope only
372 unbind_args.handle = bind_args.handle;
373 unbind_args.app_index = server_index;
374 error = vnet_unbind (&unbind_args);
375 SESSION_TEST ((error == 0), "unbind should work");
377 s = session_lookup_listener (server_st_index, &server_sep);
378 SESSION_TEST ((s == 0), "listener should not exist in global table");
380 session_lookup_local_endpoint (server_local_st_index, &server_sep);
381 SESSION_TEST ((s == 0), "listener should not exist in local table");
383 detach_args.app_index = server_index;
384 vnet_application_detach (&detach_args);
386 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
387 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
388 attach_args.api_client_index = dummy_server_api_index;
389 error = vnet_application_attach (&attach_args);
390 SESSION_TEST ((error == 0), "app attachment should work");
391 server_index = attach_args.app_index;
392 server = application_get (server_index);
393 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
394 "app should be in the right ns");
396 bind_args.app_index = server_index;
397 error = vnet_bind (&bind_args);
398 SESSION_TEST ((error == 0), "bind should work");
400 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
401 s = session_lookup_listener (server_st_index, &server_sep);
402 SESSION_TEST ((s == 0), "listener should not exist in global table");
403 server_local_st_index = application_local_session_table (server);
405 session_lookup_local_endpoint (server_local_st_index, &server_sep);
406 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
407 "listener should exist in local table");
409 unbind_args.handle = bind_args.handle;
410 error = vnet_unbind (&unbind_args);
411 SESSION_TEST ((error == 0), "unbind should work");
414 session_lookup_local_endpoint (server_local_st_index, &server_sep);
415 SESSION_TEST ((local_listener == SESSION_INVALID_INDEX),
416 "listener should not exist in local table");
419 * Client attach + connect in default ns with local scope
421 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
422 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
423 attach_args.namespace_id = 0;
424 attach_args.api_client_index = dummy_client_api_index;
425 vnet_application_attach (&attach_args);
426 error = vnet_connect (&connect_args);
427 SESSION_TEST ((error != 0), "client connect should return error code");
428 code = clib_error_get_code (error);
429 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
430 "error code should be connect (not in same ns)");
431 detach_args.app_index = client_index;
432 vnet_application_detach (&detach_args);
437 detach_args.app_index = server_index;
438 vnet_application_detach (&detach_args);
441 * Create loopback interface
443 if (vnet_create_loopback_interface (&sw_if_index, intf_mac, 0, 0))
445 clib_warning ("couldn't create loopback. stopping the test!");
448 vnet_sw_interface_set_flags (vnet_get_main (), sw_if_index,
449 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
450 ip4_add_del_interface_address (vlib_get_main (), sw_if_index, &intf_addr,
456 ns_args.sw_if_index = sw_if_index;
457 error = vnet_app_namespace_add_del (&ns_args);
458 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
459 clib_error_get_code (error));
462 * Attach server with local and global scope
464 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
465 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
466 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
467 attach_args.namespace_id = ns_id;
468 attach_args.api_client_index = dummy_server_api_index;
469 error = vnet_application_attach (&attach_args);
470 SESSION_TEST ((error == 0), "server attachment should work");
471 server_index = attach_args.app_index;
473 bind_args.app_index = server_index;
474 error = vnet_bind (&bind_args);
475 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
476 s = session_lookup_listener (server_st_index, &server_sep);
477 SESSION_TEST ((s == 0), "zero listener should not exist in global table");
479 s = session_lookup_listener (server_st_index, &intf_sep);
480 SESSION_TEST ((s != 0), "intf listener should exist in global table");
481 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
483 server_local_st_index = application_local_session_table (server);
485 session_lookup_local_endpoint (server_local_st_index, &server_sep);
486 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
487 "zero listener should exist in local table");
488 detach_args.app_index = server_index;
489 vnet_application_detach (&detach_args);
495 /* fails in multi core scenarions .. */
496 /* vnet_delete_loopback_interface (sw_if_index); */
501 session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
503 session_rules_table_t _srt, *srt = &_srt;
504 u16 lcl_port = 1234, rmt_port = 4321;
505 u32 action_index = 1, res;
506 ip4_address_t lcl_lkup, rmt_lkup;
510 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
512 if (unformat (input, "verbose"))
516 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
522 memset (srt, 0, sizeof (*srt));
523 session_rules_table_init (srt);
525 ip4_address_t lcl_ip = {
526 .as_u32 = clib_host_to_net_u32 (0x01020304),
528 ip4_address_t rmt_ip = {
529 .as_u32 = clib_host_to_net_u32 (0x05060708),
531 ip4_address_t lcl_ip2 = {
532 .as_u32 = clib_host_to_net_u32 (0x02020202),
534 ip4_address_t rmt_ip2 = {
535 .as_u32 = clib_host_to_net_u32 (0x06060606),
537 ip4_address_t lcl_ip3 = {
538 .as_u32 = clib_host_to_net_u32 (0x03030303),
540 ip4_address_t rmt_ip3 = {
541 .as_u32 = clib_host_to_net_u32 (0x07070707),
543 fib_prefix_t lcl_pref = {
544 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
546 .fp_proto = FIB_PROTOCOL_IP4,
548 fib_prefix_t rmt_pref = {
549 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
551 .fp_proto = FIB_PROTOCOL_IP4,
554 session_rule_table_add_del_args_t args = {
557 .lcl_port = lcl_port,
558 .rmt_port = rmt_port,
559 .action_index = action_index++,
562 error = session_rules_table_add_del (srt, &args);
563 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
567 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
568 SESSION_TEST ((res == 1),
569 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
573 * 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
575 args.lcl.fp_addr.ip4 = lcl_ip;
576 args.lcl.fp_len = 24;
577 args.action_index = action_index++;
578 error = session_rules_table_add_del (srt, &args);
579 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/16 4321 action %d",
581 args.rmt.fp_addr.ip4 = rmt_ip;
582 args.rmt.fp_len = 24;
583 args.action_index = action_index++;
584 error = session_rules_table_add_del (srt, &args);
585 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/24 4321 action %d",
589 * 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
591 args.lcl.fp_addr.ip4 = lcl_ip2;
592 args.lcl.fp_len = 24;
593 args.rmt.fp_addr.ip4 = rmt_ip2;
594 args.rmt.fp_len = 16;
595 args.action_index = action_index++;
596 error = session_rules_table_add_del (srt, &args);
597 SESSION_TEST ((error == 0), "Add 2.2.2.2/24 1234 6.6.6.6/16 4321 action %d",
599 args.lcl.fp_addr.ip4 = lcl_ip3;
600 args.rmt.fp_addr.ip4 = rmt_ip3;
601 args.action_index = action_index++;
602 error = session_rules_table_add_del (srt, &args);
603 SESSION_TEST ((error == 0), "Add 3.3.3.3/24 1234 7.7.7.7/16 4321 action %d",
607 * Add again 3.3.3.3/24 1234 7.7.7.7/16 4321
609 args.lcl.fp_addr.ip4 = lcl_ip3;
610 args.rmt.fp_addr.ip4 = rmt_ip3;
611 args.action_index = action_index++;
612 error = session_rules_table_add_del (srt, &args);
613 SESSION_TEST ((error == 0), "overwrite 3.3.3.3/24 1234 7.7.7.7/16 4321 "
614 "action %d", action_index - 1);
617 * 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
618 * and 3.3.3.3 1234 7.7.7.7 4321
621 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
622 SESSION_TEST ((res == 3),
623 "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
626 lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
627 rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
629 session_rules_table_lookup4 (srt, &lcl_lkup,
630 &rmt_lkup, lcl_port, rmt_port);
631 SESSION_TEST ((res == 1),
632 "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
636 session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
637 SESSION_TEST ((res == 6),
638 "Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
639 "should be 6 (updated): %d", res);
642 * Add 1.2.3.4/24 * 5.6.7.8/24 *
643 * Lookup 1.2.3.4 1234 5.6.7.8 4321 and 1.2.3.4 1235 5.6.7.8 4321
645 args.lcl.fp_addr.ip4 = lcl_ip;
646 args.rmt.fp_addr.ip4 = rmt_ip;
647 args.lcl.fp_len = 24;
648 args.rmt.fp_len = 24;
651 args.action_index = action_index++;
652 error = session_rules_table_add_del (srt, &args);
653 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
656 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
657 SESSION_TEST ((res == 7),
658 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
659 " be 7 (lpm dst): %d", res);
661 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
662 lcl_port + 1, rmt_port);
663 SESSION_TEST ((res == 7),
664 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
668 * Del 1.2.3.4/24 * 5.6.7.8/24 *
669 * Add 1.2.3.4/16 * 5.6.7.8/16 * and 1.2.3.4/24 1235 5.6.7.8/24 4321
670 * Lookup 1.2.3.4 1234 5.6.7.8 4321, 1.2.3.4 1235 5.6.7.8 4321 and
671 * 1.2.3.4 1235 5.6.7.8 4322
674 error = session_rules_table_add_del (srt, &args);
675 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 * 5.6.7.8/24 *");
677 args.lcl.fp_addr.ip4 = lcl_ip;
678 args.rmt.fp_addr.ip4 = rmt_ip;
679 args.lcl.fp_len = 16;
680 args.rmt.fp_len = 16;
683 args.action_index = action_index++;
685 error = session_rules_table_add_del (srt, &args);
686 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 * action %d",
689 args.lcl.fp_addr.ip4 = lcl_ip;
690 args.rmt.fp_addr.ip4 = rmt_ip;
691 args.lcl.fp_len = 24;
692 args.rmt.fp_len = 24;
693 args.lcl_port = lcl_port + 1;
694 args.rmt_port = rmt_port;
695 args.action_index = action_index++;
697 error = session_rules_table_add_del (srt, &args);
698 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1235 5.6.7.8/24 4321 action %d",
702 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
705 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
706 SESSION_TEST ((res == 3),
707 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
710 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
711 lcl_port + 1, rmt_port);
712 SESSION_TEST ((res == 9),
713 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
716 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
717 lcl_port + 1, rmt_port + 1);
718 SESSION_TEST ((res == 8),
719 "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
723 * Delete 1.2.0.0/16 1234 5.6.0.0/16 4321 and 1.2.0.0/16 * 5.6.0.0/16 *
724 * Lookup 1.2.3.4 1234 5.6.7.8 4321
726 args.lcl_port = 1234;
727 args.rmt_port = 4321;
728 args.lcl.fp_len = 16;
729 args.rmt.fp_len = 16;
731 error = session_rules_table_add_del (srt, &args);
732 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
734 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
735 SESSION_TEST ((res == 3),
736 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
742 error = session_rules_table_add_del (srt, &args);
743 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
745 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
746 SESSION_TEST ((res == 3),
747 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
751 * Delete 1.2.3.4/24 1234 5.6.7.5/24
753 args.lcl.fp_addr.ip4 = lcl_ip;
754 args.rmt.fp_addr.ip4 = rmt_ip;
755 args.lcl.fp_len = 24;
756 args.rmt.fp_len = 24;
757 args.lcl_port = 1234;
758 args.rmt_port = 4321;
760 error = session_rules_table_add_del (srt, &args);
761 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
763 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
764 SESSION_TEST ((res == 2), "Action should be 2: %d", res);
770 session_test_rules (vlib_main_t * vm, unformat_input_t * input)
772 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
773 u64 options[APP_OPTIONS_N_OPTIONS];
774 u16 lcl_port = 1234, rmt_port = 4321;
775 u32 server_index, server_index2, app_index;
776 u32 dummy_server_api_index = ~0;
777 transport_connection_t *tc;
778 u32 dummy_port = 1111;
779 clib_error_t *error = 0;
780 u8 is_filtered = 0, *ns_id = format (0, "appns1");
781 stream_session_t *listener, *s;
782 app_namespace_t *default_ns = app_namespace_get_default ();
783 u32 local_ns_index = default_ns->local_table_index;
785 app_namespace_t *app_ns;
787 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
789 if (unformat (input, "verbose"))
793 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
799 server_sep.is_ip4 = 1;
800 server_sep.port = dummy_port;
801 memset (options, 0, sizeof (options));
803 vnet_app_attach_args_t attach_args = {
804 .api_client_index = ~0,
807 .session_cb_vft = &dummy_session_cbs,
810 vnet_bind_args_t bind_args = {
816 * Attach server with global and local default scope
818 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
819 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
820 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
821 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
822 attach_args.namespace_id = 0;
823 attach_args.api_client_index = dummy_server_api_index;
824 error = vnet_application_attach (&attach_args);
825 SESSION_TEST ((error == 0), "server attached");
826 server_index = attach_args.app_index;
828 bind_args.app_index = server_index;
829 error = vnet_bind (&bind_args);
830 SESSION_TEST ((error == 0), "server bound to %U/%d", format_ip46_address,
831 &server_sep.ip, 1, server_sep.port);
832 listener = listen_session_get_from_handle (bind_args.handle);
833 ip4_address_t lcl_ip = {
834 .as_u32 = clib_host_to_net_u32 (0x01020304),
836 ip4_address_t rmt_ip = {
837 .as_u32 = clib_host_to_net_u32 (0x05060708),
839 fib_prefix_t lcl_pref = {
840 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
842 .fp_proto = FIB_PROTOCOL_IP4,
844 fib_prefix_t rmt_pref = {
845 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
847 .fp_proto = FIB_PROTOCOL_IP4,
850 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
851 &rmt_pref.fp_addr.ip4, lcl_port,
852 rmt_port, TRANSPORT_PROTO_TCP, 0,
854 SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
857 * Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action server_index
859 session_rule_add_del_args_t args = {
860 .table_args.lcl = lcl_pref,
861 .table_args.rmt = rmt_pref,
862 .table_args.lcl_port = lcl_port,
863 .table_args.rmt_port = rmt_port,
864 .table_args.action_index = server_index,
865 .table_args.is_add = 1,
868 error = vnet_session_rule_add_del (&args);
869 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
870 args.table_args.action_index);
872 tc = session_lookup_connection4 (0, &lcl_pref.fp_addr.ip4,
873 &rmt_pref.fp_addr.ip4, lcl_port, rmt_port,
874 TRANSPORT_PROTO_TCP);
875 SESSION_TEST ((tc->c_index == listener->connection_index),
876 "optimized lookup should return the listener");
877 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
878 &rmt_pref.fp_addr.ip4, lcl_port,
879 rmt_port, TRANSPORT_PROTO_TCP, 0,
881 SESSION_TEST ((tc->c_index == listener->connection_index),
882 "lookup should return the listener");
883 s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
884 lcl_port, rmt_port, TRANSPORT_PROTO_TCP);
885 SESSION_TEST ((s->connection_index == listener->connection_index),
886 "safe lookup should return the listener");
887 session_endpoint_t sep = {
888 .ip = rmt_pref.fp_addr,
891 .transport_proto = TRANSPORT_PROTO_TCP,
893 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
894 SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
895 "should not work (global scope)");
897 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
898 &rmt_pref.fp_addr.ip4, lcl_port + 1,
899 rmt_port, TRANSPORT_PROTO_TCP, 0,
901 SESSION_TEST ((tc == 0),
902 "optimized lookup for wrong lcl port + 1 should not work");
905 * Add 1.2.3.4/16 * 5.6.7.8/16 4321
907 args.table_args.lcl_port = 0;
908 args.scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
909 error = vnet_session_rule_add_del (&args);
910 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 4321 action %d",
911 args.table_args.action_index);
912 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
913 &rmt_pref.fp_addr.ip4, lcl_port + 1,
914 rmt_port, TRANSPORT_PROTO_TCP, 0,
916 SESSION_TEST ((tc->c_index == listener->connection_index),
917 "optimized lookup for lcl port + 1 should work");
918 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
919 SESSION_TEST ((app_index == server_index), "local session endpoint lookup "
920 "should work (lcl ip was zeroed)");
923 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
925 args.table_args.lcl_port = 1234;
926 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
927 args.table_args.lcl.fp_len = 30;
928 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
929 args.table_args.rmt.fp_len = 30;
930 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
931 error = vnet_session_rule_add_del (&args);
932 SESSION_TEST ((error == 0), "Add 1.2.3.4/30 1234 5.6.7.8/30 4321 action %d",
933 args.table_args.action_index);
937 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
938 TRANSPORT_PROTO_TCP);
939 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
940 TRANSPORT_PROTO_TCP);
943 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
944 &rmt_pref.fp_addr.ip4, lcl_port,
945 rmt_port, TRANSPORT_PROTO_TCP, 0,
947 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
948 "should fail (deny rule)");
949 SESSION_TEST ((is_filtered == 1), "lookup should be filtered (deny)");
951 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
952 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
953 "5.6.7.8/16 4321 in local table should return deny");
955 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
956 &rmt_pref.fp_addr.ip4, lcl_port + 1,
957 rmt_port, TRANSPORT_PROTO_TCP, 0,
959 SESSION_TEST ((tc->c_index == listener->connection_index),
960 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should work");
963 * "Mask" deny rule with more specific allow:
964 * Add allow rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -3 (allow)
966 args.table_args.is_add = 1;
967 args.table_args.lcl_port = 1234;
968 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
969 args.table_args.lcl.fp_len = 32;
970 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
971 args.table_args.rmt.fp_len = 32;
972 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
973 error = vnet_session_rule_add_del (&args);
974 SESSION_TEST ((error == 0), "Add masking rule 1.2.3.4/30 1234 5.6.7.8/32 "
975 "4321 action %d", args.table_args.action_index);
978 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
979 &rmt_pref.fp_addr.ip4, lcl_port,
980 rmt_port, TRANSPORT_PROTO_TCP, 0,
982 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
983 "should fail (allow without app)");
984 SESSION_TEST ((is_filtered == 0), "lookup should NOT be filtered");
986 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
987 SESSION_TEST ((app_index == APP_INVALID_INDEX), "lookup for 1.2.3.4/32 1234"
988 " 5.6.7.8/32 4321 in local table should return invalid");
992 vlib_cli_output (vm, "Local rules");
993 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
994 TRANSPORT_PROTO_TCP);
997 sep.ip.ip4.as_u32 += 1 << 24;
998 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
999 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234"
1000 " 5.6.7.9/32 4321 in local table should return deny");
1002 vnet_connect_args_t connect_args = {
1004 .app_index = attach_args.app_index,
1008 /* Try connecting */
1009 error = vnet_connect (&connect_args);
1010 SESSION_TEST ((error != 0), "connect should fail");
1011 rv = clib_error_get_code (error);
1012 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1013 "connect should be filtered");
1015 sep.ip.ip4.as_u32 -= 1 << 24;
1020 * Delete masking rule: 1.2.3.4/32 1234 5.6.7.8/32 4321 allow
1022 args.table_args.is_add = 0;
1023 args.table_args.lcl_port = 1234;
1024 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1025 args.table_args.lcl.fp_len = 32;
1026 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1027 args.table_args.rmt.fp_len = 32;
1028 error = vnet_session_rule_add_del (&args);
1029 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 allow");
1033 * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
1035 args.table_args.is_add = 1;
1036 args.table_args.lcl_port = 0;
1037 args.table_args.lcl.fp_len = 0;
1038 args.table_args.rmt.fp_len = 16;
1039 args.table_args.action_index = -1;
1040 error = vnet_session_rule_add_del (&args);
1041 SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d",
1042 args.table_args.action_index);
1046 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1047 TRANSPORT_PROTO_TCP);
1048 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1049 TRANSPORT_PROTO_TCP);
1052 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1053 SESSION_TEST ((app_index == APP_DROP_INDEX),
1054 "local session endpoint lookup should return deny");
1057 * Delete 1.2.3.4/32 1234 5.6.7.8/32 4321 deny
1059 args.table_args.is_add = 0;
1060 args.table_args.lcl_port = 1234;
1061 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1062 args.table_args.lcl.fp_len = 30;
1063 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1064 args.table_args.rmt.fp_len = 30;
1065 error = vnet_session_rule_add_del (&args);
1066 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1068 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1069 SESSION_TEST ((app_index == APP_INVALID_INDEX),
1070 "local session endpoint lookup should return invalid");
1073 * Delete 0/0 * 5.6.7.8/16 4321, 1.2.3.4/16 * 5.6.7.8/16 4321 and
1074 * 1.2.3.4/16 1234 5.6.7.8/16 4321
1076 args.table_args.is_add = 0;
1077 args.table_args.lcl_port = 0;
1078 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1079 args.table_args.lcl.fp_len = 0;
1080 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1081 args.table_args.rmt.fp_len = 16;
1082 args.table_args.rmt_port = 4321;
1083 error = vnet_session_rule_add_del (&args);
1084 SESSION_TEST ((error == 0), "Del 0/0 * 5.6.7.8/16 4321");
1085 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1086 SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
1087 "should not work (removed)");
1089 args.table_args.is_add = 0;
1090 args.table_args.lcl = lcl_pref;
1092 args.table_args.is_add = 0;
1093 args.table_args.lcl_port = 0;
1094 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1095 args.table_args.lcl.fp_len = 16;
1096 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1097 args.table_args.rmt.fp_len = 16;
1098 args.table_args.rmt_port = 4321;
1099 error = vnet_session_rule_add_del (&args);
1100 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
1101 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1102 &rmt_pref.fp_addr.ip4, lcl_port + 1,
1103 rmt_port, TRANSPORT_PROTO_TCP, 0,
1105 SESSION_TEST ((tc == 0),
1106 "lookup 1.2.3.4/32 123*5* 5.6.7.8/16 4321 should not "
1109 args.table_args.is_add = 0;
1110 args.table_args.lcl_port = 1234;
1111 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1112 args.table_args.lcl.fp_len = 16;
1113 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1114 args.table_args.rmt.fp_len = 16;
1115 args.table_args.rmt_port = 4321;
1116 error = vnet_session_rule_add_del (&args);
1117 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
1118 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1119 &rmt_pref.fp_addr.ip4, lcl_port,
1120 rmt_port, TRANSPORT_PROTO_TCP, 0,
1122 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should "
1123 "not work (del + deny)");
1125 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny");
1126 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1127 &rmt_pref.fp_addr.ip4, lcl_port,
1128 rmt_port, TRANSPORT_PROTO_TCP, 0,
1130 SESSION_TEST ((tc == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should"
1131 " not work (no-rule)");
1134 * Test tags. Add/overwrite/del rule with tag
1136 args.table_args.is_add = 1;
1137 args.table_args.lcl_port = 1234;
1138 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1139 args.table_args.lcl.fp_len = 16;
1140 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1141 args.table_args.rmt.fp_len = 16;
1142 args.table_args.rmt_port = 4321;
1143 args.table_args.tag = format (0, "test_rule");
1144 args.table_args.action_index = server_index;
1145 error = vnet_session_rule_add_del (&args);
1146 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 deny "
1150 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1151 TRANSPORT_PROTO_TCP);
1152 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1153 TRANSPORT_PROTO_TCP);
1155 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1156 &rmt_pref.fp_addr.ip4, lcl_port,
1157 rmt_port, TRANSPORT_PROTO_TCP, 0,
1159 SESSION_TEST ((tc->c_index == listener->connection_index),
1160 "lookup 1.2.3.4/32 1234 5.6.7.8/16 4321 should work");
1162 vec_free (args.table_args.tag);
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.tag = format (0, "test_rule_overwrite");
1167 error = vnet_session_rule_add_del (&args);
1168 SESSION_TEST ((error == 0),
1169 "Overwrite 1.2.3.4/16 1234 5.6.7.8/16 4321 deny tag test_rule"
1173 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1174 TRANSPORT_PROTO_TCP);
1175 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1176 TRANSPORT_PROTO_TCP);
1179 args.table_args.is_add = 0;
1180 args.table_args.lcl_port += 1;
1181 error = vnet_session_rule_add_del (&args);
1182 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 deny "
1183 "tag %v", args.table_args.tag);
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 == 0), "lookup 1.2.3.4/32 1234 5.6.7.8/32 4321 should not"
1200 * Test local rules with multiple namespaces
1204 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1206 args.table_args.is_add = 1;
1207 args.table_args.lcl_port = 1234;
1208 args.table_args.rmt_port = 0;
1209 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1210 args.table_args.lcl.fp_len = 32;
1211 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1212 args.table_args.rmt.fp_len = 32;
1213 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1214 args.table_args.tag = 0;
1215 args.scope = SESSION_RULE_SCOPE_LOCAL;
1216 error = vnet_session_rule_add_del (&args);
1217 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
1218 args.table_args.action_index);
1220 * Add 'white' rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
1222 args.table_args.is_add = 1;
1223 args.table_args.lcl_port = 1234;
1224 args.table_args.rmt_port = 4321;
1225 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1226 args.table_args.lcl.fp_len = 32;
1227 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1228 args.table_args.rmt.fp_len = 32;
1229 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_ALLOW;
1230 error = vnet_session_rule_add_del (&args);
1234 session_lookup_dump_local_rules_table (local_ns_index, FIB_PROTOCOL_IP4,
1235 TRANSPORT_PROTO_TCP);
1238 vnet_app_namespace_add_del_args_t ns_args = {
1241 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
1244 error = vnet_app_namespace_add_del (&ns_args);
1245 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
1246 clib_error_get_code (error));
1247 app_ns = app_namespace_get_from_id (ns_id);
1249 attach_args.namespace_id = ns_id;
1250 attach_args.api_client_index = dummy_server_api_index - 1;
1251 error = vnet_application_attach (&attach_args);
1252 SESSION_TEST ((error == 0), "server2 attached");
1253 server_index2 = attach_args.app_index;
1256 * Add deny rule 1.2.3.4/32 1234 5.6.7.8/32 0 action -2 (drop)
1258 args.table_args.lcl_port = 1234;
1259 args.table_args.rmt_port = 0;
1260 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1261 args.table_args.lcl.fp_len = 32;
1262 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1263 args.table_args.rmt.fp_len = 32;
1264 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
1265 args.appns_index = app_namespace_index (app_ns);
1267 error = vnet_session_rule_add_del (&args);
1268 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d "
1269 "in test namespace", args.table_args.action_index);
1271 * Lookup default namespace
1273 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1274 SESSION_TEST ((app_index == APP_INVALID_INDEX),
1275 "lookup for 1.2.3.4/32 1234 5.6.7.8/32 4321 in local table "
1276 "should return allow (invalid)");
1279 app_index = session_lookup_local_endpoint (local_ns_index, &sep);
1280 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
1281 "5.6.7.8/16 432*2* in local table should return deny");
1283 connect_args.app_index = server_index;
1284 connect_args.sep = sep;
1285 error = vnet_connect (&connect_args);
1286 SESSION_TEST ((error != 0), "connect should fail");
1287 rv = clib_error_get_code (error);
1288 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1289 "connect should be filtered");
1292 * Lookup test namespace
1294 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1295 SESSION_TEST ((app_index == APP_DROP_INDEX), "lookup for 1.2.3.4/32 1234 "
1296 "5.6.7.8/16 4321 in local table should return deny");
1298 connect_args.app_index = server_index;
1299 error = vnet_connect (&connect_args);
1300 SESSION_TEST ((error != 0), "connect should fail");
1301 rv = clib_error_get_code (error);
1302 SESSION_TEST ((rv == VNET_API_ERROR_APP_CONNECT_FILTERED),
1303 "connect should be filtered");
1305 args.table_args.is_add = 0;
1306 vnet_session_rule_add_del (&args);
1308 args.appns_index = 0;
1309 args.table_args.is_add = 0;
1310 vnet_session_rule_add_del (&args);
1312 args.table_args.rmt_port = 4321;
1313 vnet_session_rule_add_del (&args);
1317 vec_free (args.table_args.tag);
1318 vnet_app_detach_args_t detach_args = {
1319 .app_index = server_index,
1321 vnet_application_detach (&detach_args);
1323 detach_args.app_index = server_index2;
1324 vnet_application_detach (&detach_args);
1331 session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
1333 u64 options[APP_OPTIONS_N_OPTIONS];
1334 char *show_listeners = "sh session listeners tcp verbose";
1335 char *show_local_listeners = "sh app ns table default";
1336 unformat_input_t tmp_input;
1337 u32 server_index, app_index;
1338 u32 dummy_server_api_index = ~0, sw_if_index = 0;
1339 clib_error_t *error = 0;
1340 u8 intf_mac[6], sst, is_filtered = 0;
1341 stream_session_t *s;
1342 transport_connection_t *tc;
1343 u16 lcl_port = 1234, rmt_port = 4321;
1344 app_namespace_t *app_ns;
1347 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1349 if (unformat (input, "verbose"))
1353 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1359 ip4_address_t lcl_ip = {
1360 .as_u32 = clib_host_to_net_u32 (0x01020304),
1362 ip4_address_t rmt_ip = {
1363 .as_u32 = clib_host_to_net_u32 (0x05060708),
1365 fib_prefix_t rmt_pref = {
1366 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1368 .fp_proto = FIB_PROTOCOL_IP4,
1370 session_endpoint_t sep = {
1371 .ip = rmt_pref.fp_addr,
1374 .transport_proto = TRANSPORT_PROTO_TCP,
1378 * Create loopback interface
1380 memset (intf_mac, 0, sizeof (intf_mac));
1381 if (vnet_create_loopback_interface (&sw_if_index, intf_mac, 0, 0))
1383 clib_warning ("couldn't create loopback. stopping the test!");
1386 vnet_sw_interface_set_flags (vnet_get_main (), sw_if_index,
1387 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
1388 ip4_add_del_interface_address (vlib_get_main (), sw_if_index, &lcl_ip,
1391 app_ns = app_namespace_get_default ();
1392 app_ns->sw_if_index = sw_if_index;
1394 memset (options, 0, sizeof (options));
1395 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
1396 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_IS_PROXY;
1397 options[APP_OPTIONS_PROXY_TRANSPORT] = 1 << TRANSPORT_PROTO_TCP;
1398 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1399 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1400 vnet_app_attach_args_t attach_args = {
1401 .api_client_index = ~0,
1404 .session_cb_vft = &dummy_session_cbs,
1407 attach_args.api_client_index = dummy_server_api_index;
1408 error = vnet_application_attach (&attach_args);
1409 SESSION_TEST ((error == 0), "server attachment should work");
1410 server_index = attach_args.app_index;
1414 unformat_init_string (&tmp_input, show_listeners,
1415 strlen (show_listeners));
1416 vlib_cli_input (vm, &tmp_input, 0, 0);
1417 unformat_init_string (&tmp_input, show_local_listeners,
1418 strlen (show_local_listeners));
1419 vlib_cli_input (vm, &tmp_input, 0, 0);
1422 tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
1423 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1424 SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
1426 sst = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, 1);
1427 s = listen_session_get (sst, tc->s_index);
1428 SESSION_TEST ((s->app_index == server_index), "lookup should return the"
1431 tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
1432 TRANSPORT_PROTO_TCP, 0, &is_filtered);
1433 SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
1436 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1437 SESSION_TEST ((app_index == server_index), "local session endpoint lookup"
1440 vnet_app_detach_args_t detach_args = {
1441 .app_index = server_index,
1443 vnet_application_detach (&detach_args);
1447 unformat_init_string (&tmp_input, show_listeners,
1448 strlen (show_listeners));
1449 vlib_cli_input (vm, &tmp_input, 0, 0);
1450 unformat_init_string (&tmp_input, show_local_listeners,
1451 strlen (show_local_listeners));
1452 vlib_cli_input (vm, &tmp_input, 0, 0);
1455 app_index = session_lookup_local_endpoint (app_ns->local_table_index, &sep);
1456 SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
1457 "local session endpoint lookup should not work after detach");
1459 unformat_free (&tmp_input);
1463 static clib_error_t *
1464 session_test (vlib_main_t * vm,
1465 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
1469 vnet_session_enable_disable (vm, 1);
1471 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1473 if (unformat (input, "basic"))
1474 res = session_test_basic (vm, input);
1475 else if (unformat (input, "namespace"))
1476 res = session_test_namespace (vm, input);
1477 else if (unformat (input, "rules-table"))
1478 res = session_test_rule_table (vm, input);
1479 else if (unformat (input, "rules"))
1480 res = session_test_rules (vm, input);
1481 else if (unformat (input, "proxy"))
1482 res = session_test_proxy (vm, input);
1483 else if (unformat (input, "all"))
1485 if ((res = session_test_basic (vm, input)))
1487 if ((res = session_test_namespace (vm, input)))
1489 if ((res = session_test_rule_table (vm, input)))
1491 if ((res = session_test_rules (vm, input)))
1493 if ((res = session_test_proxy (vm, input)))
1502 return clib_error_return (0, "Session unit test failed");
1507 VLIB_CLI_COMMAND (tcp_test_command, static) =
1509 .path = "test session",
1510 .short_help = "internal session unit tests",
1511 .function = session_test,
1516 * fd.io coding-style-patch-verification: ON
1519 * eval: (c-set-style "gnu")