blob: 56d40b81ef8deb463e96fc199bf0fbba31132eaa [file] [log] [blame]
Florin Corascea194d2017-10-02 00:18:51 -07001/*
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:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
15
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>
Florin Coras1c710452017-10-17 00:03:13 -070020#include <vnet/session/session_rules_table.h>
Florin Corascea194d2017-10-02 00:18:51 -070021
22#define SESSION_TEST_I(_cond, _comment, _args...) \
23({ \
24 int _evald = (_cond); \
25 if (!(_evald)) { \
26 fformat(stderr, "FAIL:%d: " _comment "\n", \
27 __LINE__, ##_args); \
28 } else { \
29 fformat(stderr, "PASS:%d: " _comment "\n", \
30 __LINE__, ##_args); \
31 } \
32 _evald; \
33})
34
35#define SESSION_TEST(_cond, _comment, _args...) \
36{ \
37 if (!SESSION_TEST_I(_cond, _comment, ##_args)) { \
38 return 1; \
39 } \
40}
41
42void
43dummy_session_reset_callback (stream_session_t * s)
44{
45 clib_warning ("called...");
46}
47
48int
49dummy_session_connected_callback (u32 app_index, u32 api_context,
50 stream_session_t * s, u8 is_fail)
51{
52 clib_warning ("called...");
53 return -1;
54}
55
56int
57dummy_add_segment_callback (u32 client_index, const u8 * seg_name,
58 u32 seg_size)
59{
60 clib_warning ("called...");
61 return -1;
62}
63
64int
65dummy_redirect_connect_callback (u32 client_index, void *mp)
66{
67 return VNET_API_ERROR_SESSION_REDIRECT;
68}
69
70void
71dummy_session_disconnect_callback (stream_session_t * s)
72{
73 clib_warning ("called...");
74}
75
76int
77dummy_session_accept_callback (stream_session_t * s)
78{
79 clib_warning ("called...");
80 return -1;
81}
82
83int
84dummy_server_rx_callback (stream_session_t * s)
85{
86 clib_warning ("called...");
87 return -1;
88}
89
90/* *INDENT-OFF* */
91static 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,
98};
99/* *INDENT-ON* */
100
101static int
Florin Coras4e4531e2017-11-06 23:27:56 -0800102session_test_basic (vlib_main_t * vm, unformat_input_t * input)
103{
104 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
105 u64 options[SESSION_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle;
106 u8 segment_name[128];
107 clib_error_t *error = 0;
108 u32 server_index;
109
110 memset (options, 0, sizeof (options));
111 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
112 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
113 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
114 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
115 vnet_app_attach_args_t attach_args = {
116 .api_client_index = ~0,
117 .options = options,
118 .namespace_id = 0,
119 .session_cb_vft = &dummy_session_cbs,
120 .segment_name = segment_name,
121 };
122
123 error = vnet_application_attach (&attach_args);
124 SESSION_TEST ((error == 0), "app attached");
125 server_index = attach_args.app_index;
126
127 server_sep.is_ip4 = 1;
128 vnet_bind_args_t bind_args = {
129 .sep = server_sep,
130 .app_index = 0,
131 };
132
133 bind_args.app_index = server_index;
134 error = vnet_bind (&bind_args);
135 SESSION_TEST ((error == 0), "server bind4 should work");
136 bind4_handle = bind_args.handle;
137
138 error = vnet_bind (&bind_args);
139 SESSION_TEST ((error != 0), "double server bind4 should not work");
140
141 bind_args.sep.is_ip4 = 0;
142 error = vnet_bind (&bind_args);
143 SESSION_TEST ((error == 0), "server bind6 should work");
144 bind6_handle = bind_args.handle;
145
146 error = vnet_bind (&bind_args);
147 SESSION_TEST ((error != 0), "double server bind6 should not work");
148
149 vnet_unbind_args_t unbind_args = {
150 .handle = bind4_handle,
151 .app_index = server_index,
152 };
153 error = vnet_unbind (&unbind_args);
154 SESSION_TEST ((error == 0), "unbind4 should work");
155
156 unbind_args.handle = bind6_handle;
157 error = vnet_unbind (&unbind_args);
158 SESSION_TEST ((error == 0), "unbind6 should work");
159
160 vnet_app_detach_args_t detach_args = {
161 .app_index = server_index,
162 };
163 vnet_application_detach (&detach_args);
164 return 0;
165}
166
167static int
Florin Corascea194d2017-10-02 00:18:51 -0700168session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
169{
170 u64 options[SESSION_OPTIONS_N_OPTIONS], dummy_secret = 1234;
171 u32 server_index, server_st_index, server_local_st_index;
172 u32 dummy_port = 1234, local_listener, client_index;
173 u32 dummy_api_context = 4321, dummy_client_api_index = 1234;
174 u32 dummy_server_api_index = ~0, sw_if_index = 0;
175 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
176 session_endpoint_t client_sep = SESSION_ENDPOINT_NULL;
177 session_endpoint_t intf_sep = SESSION_ENDPOINT_NULL;
178 clib_error_t *error = 0;
179 u8 *ns_id = format (0, "appns1"), intf_mac[6];
180 app_namespace_t *app_ns;
181 u8 segment_name[128];
182 application_t *server;
183 stream_session_t *s;
184 int code;
185
186 server_sep.is_ip4 = 1;
187 server_sep.port = dummy_port;
188 client_sep.is_ip4 = 1;
189 client_sep.port = dummy_port;
190 memset (options, 0, sizeof (options));
191 memset (intf_mac, 0, sizeof (intf_mac));
192
Florin Coras7999e832017-10-31 01:51:04 -0700193 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
Florin Corascea194d2017-10-02 00:18:51 -0700194 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
195 vnet_app_attach_args_t attach_args = {
196 .api_client_index = ~0,
197 .options = options,
198 .namespace_id = 0,
199 .session_cb_vft = &dummy_session_cbs,
200 .segment_name = segment_name,
201 };
202
203 vnet_bind_args_t bind_args = {
204 .sep = server_sep,
205 .app_index = 0,
206 };
207
208 vnet_connect_args_t connect_args = {
209 .sep = client_sep,
210 .app_index = 0,
211 .api_context = 0,
212 };
213
214 vnet_unbind_args_t unbind_args = {
215 .handle = bind_args.handle,
216 .app_index = 0,
217 };
218
219 vnet_app_detach_args_t detach_args = {
220 .app_index = 0,
221 };
222
223 ip4_address_t intf_addr = {
224 .as_u32 = clib_host_to_net_u32 (0x06000105),
225 };
226
227 intf_sep.ip.ip4 = intf_addr;
228 intf_sep.is_ip4 = 1;
229 intf_sep.port = dummy_port;
230
231 /*
232 * Insert namespace and lookup
233 */
234
235 vnet_app_namespace_add_del_args_t ns_args = {
236 .ns_id = ns_id,
237 .secret = dummy_secret,
238 .sw_if_index = APP_NAMESPACE_INVALID_INDEX,
239 .is_add = 1
240 };
241 error = vnet_app_namespace_add_del (&ns_args);
242 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
243 clib_error_get_code (error));
244
245 app_ns = app_namespace_get_from_id (ns_id);
246 SESSION_TEST ((app_ns != 0), "should find ns %v status", ns_id);
247 SESSION_TEST ((app_ns->ns_secret == dummy_secret), "secret should be %d",
248 dummy_secret);
249 SESSION_TEST ((app_ns->sw_if_index == APP_NAMESPACE_INVALID_INDEX),
250 "sw_if_index should be invalid");
251
252 /*
253 * Try application attach with wrong secret
254 */
255
256 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
257 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
258 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret - 1;
259 attach_args.namespace_id = ns_id;
260 attach_args.api_client_index = dummy_server_api_index;
261
262 error = vnet_application_attach (&attach_args);
263 SESSION_TEST ((error != 0), "app attachment should fail");
264 code = clib_error_get_code (error);
265 SESSION_TEST ((code == VNET_API_ERROR_APP_WRONG_NS_SECRET),
266 "code should be wrong ns secret: %d", code);
267
268 /*
269 * Attach server with global default scope
270 */
271 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
272 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
273 options[APP_OPTIONS_NAMESPACE_SECRET] = 0;
274 attach_args.namespace_id = 0;
275 attach_args.api_client_index = dummy_server_api_index;
276 error = vnet_application_attach (&attach_args);
277 SESSION_TEST ((error == 0), "server attachment should work");
278 server_index = attach_args.app_index;
279 server = application_get (server_index);
280 SESSION_TEST ((server->ns_index == 0),
281 "server should be in the default ns");
282
283 bind_args.app_index = server_index;
284 error = vnet_bind (&bind_args);
285 SESSION_TEST ((error == 0), "server bind should work");
286
287 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
288 s = session_lookup_listener (server_st_index, &server_sep);
289 SESSION_TEST ((s != 0), "listener should exist in global table");
290 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
291 "the server");
292 server_local_st_index = application_local_session_table (server);
293 SESSION_TEST ((server_local_st_index == APP_INVALID_INDEX),
294 "server shouldn't have access to local table");
295
296 unbind_args.app_index = server_index;
Florin Corasfc1c6122017-10-26 14:25:12 -0700297 unbind_args.handle = bind_args.handle;
Florin Corascea194d2017-10-02 00:18:51 -0700298 error = vnet_unbind (&unbind_args);
299 SESSION_TEST ((error == 0), "unbind should work");
300
301 s = session_lookup_listener (server_st_index, &server_sep);
302 SESSION_TEST ((s == 0), "listener should not exist in global table");
303
304 detach_args.app_index = server_index;
305 vnet_application_detach (&detach_args);
306
307 /*
308 * Attach server with local and global scope
309 */
310 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
311 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
312 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
313 attach_args.namespace_id = ns_id;
314 attach_args.api_client_index = dummy_server_api_index;
315 error = vnet_application_attach (&attach_args);
316 SESSION_TEST ((error == 0), "server attachment should work");
317 server_index = attach_args.app_index;
318 server = application_get (server_index);
319 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
320 "server should be in the right ns");
321
322 bind_args.app_index = server_index;
323 error = vnet_bind (&bind_args);
324 SESSION_TEST ((error == 0), "bind should work");
325 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
326 s = session_lookup_listener (server_st_index, &server_sep);
327 SESSION_TEST ((s != 0), "listener should exist in global table");
328 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
329 "the server");
330 server_local_st_index = application_local_session_table (server);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700331 local_listener =
332 session_lookup_local_session_endpoint (server_local_st_index,
333 &server_sep);
Florin Corascea194d2017-10-02 00:18:51 -0700334 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
335 "listener should exist in local table");
336
337 /*
338 * Try client connect with 1) local scope 2) global scope
339 */
340 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
341 attach_args.api_client_index = dummy_client_api_index;
342 error = vnet_application_attach (&attach_args);
343 SESSION_TEST ((error == 0), "client attachment should work");
344 client_index = attach_args.app_index;
345 connect_args.api_context = dummy_api_context;
346 connect_args.app_index = client_index;
347 error = vnet_connect (&connect_args);
348 SESSION_TEST ((error != 0), "client connect should return error code");
349 code = clib_error_get_code (error);
350 SESSION_TEST ((code == VNET_API_ERROR_INVALID_VALUE),
351 "error code should be invalid value (zero ip)");
352 connect_args.sep.ip.ip4.as_u8[0] = 127;
353 error = vnet_connect (&connect_args);
354 SESSION_TEST ((error != 0), "client connect should return error code");
355 code = clib_error_get_code (error);
356 SESSION_TEST ((code == VNET_API_ERROR_SESSION_REDIRECT),
357 "error code should be redirect");
358 detach_args.app_index = client_index;
359 vnet_application_detach (&detach_args);
360
361 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
362 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
363 attach_args.api_client_index = dummy_client_api_index;
364 error = vnet_application_attach (&attach_args);
365 SESSION_TEST ((error == 0), "client attachment should work");
366 error = vnet_connect (&connect_args);
367 SESSION_TEST ((error != 0), "client connect should return error code");
368 code = clib_error_get_code (error);
369 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
370 "error code should be connect (nothing in local scope)");
371 detach_args.app_index = client_index;
372 vnet_application_detach (&detach_args);
373
374 /*
375 * Unbind and detach server and then re-attach with local scope only
376 */
377 unbind_args.handle = bind_args.handle;
378 unbind_args.app_index = server_index;
379 error = vnet_unbind (&unbind_args);
380 SESSION_TEST ((error == 0), "unbind should work");
381
382 s = session_lookup_listener (server_st_index, &server_sep);
383 SESSION_TEST ((s == 0), "listener should not exist in global table");
Florin Coras3cbc04b2017-10-02 00:18:51 -0700384 local_listener =
385 session_lookup_local_session_endpoint (server_local_st_index,
386 &server_sep);
Florin Corascea194d2017-10-02 00:18:51 -0700387 SESSION_TEST ((s == 0), "listener should not exist in local table");
388
389 detach_args.app_index = server_index;
390 vnet_application_detach (&detach_args);
391
392 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
393 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
394 attach_args.api_client_index = dummy_server_api_index;
395 error = vnet_application_attach (&attach_args);
396 SESSION_TEST ((error == 0), "app attachment should work");
397 server_index = attach_args.app_index;
398 server = application_get (server_index);
399 SESSION_TEST ((server->ns_index == app_namespace_index (app_ns)),
400 "app should be in the right ns");
401
402 bind_args.app_index = server_index;
403 error = vnet_bind (&bind_args);
404 SESSION_TEST ((error == 0), "bind should work");
405
406 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
407 s = session_lookup_listener (server_st_index, &server_sep);
408 SESSION_TEST ((s == 0), "listener should not exist in global table");
409 server_local_st_index = application_local_session_table (server);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700410 local_listener =
411 session_lookup_local_session_endpoint (server_local_st_index,
412 &server_sep);
Florin Corascea194d2017-10-02 00:18:51 -0700413 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
414 "listener should exist in local table");
415
416 unbind_args.handle = bind_args.handle;
417 error = vnet_unbind (&unbind_args);
418 SESSION_TEST ((error == 0), "unbind should work");
419
Florin Coras3cbc04b2017-10-02 00:18:51 -0700420 local_listener =
421 session_lookup_local_session_endpoint (server_local_st_index,
422 &server_sep);
Florin Corascea194d2017-10-02 00:18:51 -0700423 SESSION_TEST ((local_listener == SESSION_INVALID_INDEX),
424 "listener should not exist in local table");
425
426 /*
427 * Client attach + connect in default ns with local scope
428 */
429 options[APP_OPTIONS_FLAGS] &= ~APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
430 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
431 attach_args.namespace_id = 0;
432 attach_args.api_client_index = dummy_client_api_index;
433 vnet_application_attach (&attach_args);
434 error = vnet_connect (&connect_args);
435 SESSION_TEST ((error != 0), "client connect should return error code");
436 code = clib_error_get_code (error);
437 SESSION_TEST ((code == VNET_API_ERROR_SESSION_CONNECT),
438 "error code should be connect (not in same ns)");
439 detach_args.app_index = client_index;
440 vnet_application_detach (&detach_args);
441
442 /*
443 * Detach server
444 */
445 detach_args.app_index = server_index;
446 vnet_application_detach (&detach_args);
447
448 /*
449 * Create loopback interface
450 */
451 if (vnet_create_loopback_interface (&sw_if_index, intf_mac, 0, 0))
452 {
453 clib_warning ("couldn't create loopback. stopping the test!");
454 return 0;
455 }
456 vnet_sw_interface_set_flags (vnet_get_main (), sw_if_index,
457 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
458 ip4_add_del_interface_address (vlib_get_main (), sw_if_index, &intf_addr,
459 24, 0);
460
461 /*
462 * Update namespace
463 */
464 ns_args.sw_if_index = sw_if_index;
465 error = vnet_app_namespace_add_del (&ns_args);
466 SESSION_TEST ((error == 0), "app ns insertion should succeed: %d",
467 clib_error_get_code (error));
468
469 /*
470 * Attach server with local and global scope
471 */
472 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
473 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
474 options[APP_OPTIONS_NAMESPACE_SECRET] = dummy_secret;
475 attach_args.namespace_id = ns_id;
476 attach_args.api_client_index = dummy_server_api_index;
477 error = vnet_application_attach (&attach_args);
478 SESSION_TEST ((error == 0), "server attachment should work");
479 server_index = attach_args.app_index;
480
481 bind_args.app_index = server_index;
482 error = vnet_bind (&bind_args);
483 server_st_index = application_session_table (server, FIB_PROTOCOL_IP4);
484 s = session_lookup_listener (server_st_index, &server_sep);
485 SESSION_TEST ((s == 0), "zero listener should not exist in global table");
486
487 s = session_lookup_listener (server_st_index, &intf_sep);
488 SESSION_TEST ((s != 0), "intf listener should exist in global table");
489 SESSION_TEST ((s->app_index == server_index), "app_index should be that of "
490 "the server");
491 server_local_st_index = application_local_session_table (server);
Florin Coras3cbc04b2017-10-02 00:18:51 -0700492 local_listener =
493 session_lookup_local_session_endpoint (server_local_st_index,
494 &server_sep);
Florin Corascea194d2017-10-02 00:18:51 -0700495 SESSION_TEST ((local_listener != SESSION_INVALID_INDEX),
496 "zero listener should exist in local table");
497 detach_args.app_index = server_index;
498 vnet_application_detach (&detach_args);
499
500 /*
501 * Cleanup
502 */
503 vec_free (ns_id);
504 vnet_delete_loopback_interface (sw_if_index);
505 return 0;
506}
507
Florin Coras1c710452017-10-17 00:03:13 -0700508static int
509session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
510{
511 session_rules_table_t _srt, *srt = &_srt;
512 u16 lcl_port = 1234, rmt_port = 4321;
513 u32 action_index = 1, res;
514 ip4_address_t lcl_lkup, rmt_lkup;
515 clib_error_t *error;
516 int verbose = 0;
517
518 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
519 {
520 if (unformat (input, "verbose"))
521 verbose = 1;
522 else
523 {
524 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
525 input);
526 return -1;
527 }
528 }
529
530 memset (srt, 0, sizeof (*srt));
531 session_rules_table_init (srt);
532
533 ip4_address_t lcl_ip = {
534 .as_u32 = clib_host_to_net_u32 (0x01020304),
535 };
536 ip4_address_t rmt_ip = {
537 .as_u32 = clib_host_to_net_u32 (0x05060708),
538 };
539 ip4_address_t lcl_ip2 = {
540 .as_u32 = clib_host_to_net_u32 (0x02020202),
541 };
542 ip4_address_t rmt_ip2 = {
543 .as_u32 = clib_host_to_net_u32 (0x06060606),
544 };
545 ip4_address_t lcl_ip3 = {
546 .as_u32 = clib_host_to_net_u32 (0x03030303),
547 };
548 ip4_address_t rmt_ip3 = {
549 .as_u32 = clib_host_to_net_u32 (0x07070707),
550 };
551 fib_prefix_t lcl_pref = {
552 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
553 .fp_len = 16,
554 .fp_proto = FIB_PROTOCOL_IP4,
555 };
556 fib_prefix_t rmt_pref = {
557 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
558 .fp_len = 16,
559 .fp_proto = FIB_PROTOCOL_IP4,
560 };
561
562 session_rule_table_add_del_args_t args = {
563 .lcl = lcl_pref,
564 .rmt = rmt_pref,
565 .lcl_port = lcl_port,
566 .rmt_port = rmt_port,
567 .action_index = action_index++,
568 .is_add = 1,
569 };
570 error = session_rules_table_add_del (srt, &args);
571 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
572 action_index - 1);
573
574 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800575 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700576 SESSION_TEST ((res == 1),
577 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
578 res);
579
580 /*
581 * 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
582 */
583 args.lcl.fp_addr.ip4 = lcl_ip;
584 args.lcl.fp_len = 24;
585 args.action_index = action_index++;
586 error = session_rules_table_add_del (srt, &args);
587 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/16 4321 action %d",
588 action_index - 1);
589 args.rmt.fp_addr.ip4 = rmt_ip;
590 args.rmt.fp_len = 24;
591 args.action_index = action_index++;
592 error = session_rules_table_add_del (srt, &args);
593 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/24 4321 action %d",
594 action_index - 1);
595
596 /*
597 * 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
598 */
599 args.lcl.fp_addr.ip4 = lcl_ip2;
600 args.lcl.fp_len = 24;
601 args.rmt.fp_addr.ip4 = rmt_ip2;
602 args.rmt.fp_len = 16;
603 args.action_index = action_index++;
604 error = session_rules_table_add_del (srt, &args);
605 SESSION_TEST ((error == 0), "Add 2.2.2.2/24 1234 6.6.6.6/16 4321 action %d",
606 action_index - 1);
607 args.lcl.fp_addr.ip4 = lcl_ip3;
608 args.rmt.fp_addr.ip4 = rmt_ip3;
609 args.action_index = action_index++;
610 error = session_rules_table_add_del (srt, &args);
611 SESSION_TEST ((error == 0), "Add 3.3.3.3/24 1234 7.7.7.7/16 4321 action %d",
612 action_index - 1);
613
614 /*
615 * Add again 3.3.3.3/24 1234 7.7.7.7/16 4321
616 */
617 args.lcl.fp_addr.ip4 = lcl_ip3;
618 args.rmt.fp_addr.ip4 = rmt_ip3;
619 args.action_index = action_index++;
620 error = session_rules_table_add_del (srt, &args);
621 SESSION_TEST ((error == 0), "overwrite 3.3.3.3/24 1234 7.7.7.7/16 4321 "
622 "action %d", action_index - 1);
623
624 /*
625 * 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
626 * and 3.3.3.3 1234 7.7.7.7 4321
627 */
628 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800629 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700630 SESSION_TEST ((res == 3),
631 "Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
632 res);
633
634 lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
635 rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
636 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800637 session_rules_table_lookup4 (srt, &lcl_lkup,
Florin Coras1c710452017-10-17 00:03:13 -0700638 &rmt_lkup, lcl_port, rmt_port);
639 SESSION_TEST ((res == 1),
640 "Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
641 res);
642
643 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800644 session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700645 SESSION_TEST ((res == 6),
646 "Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
647 "should be 6 (updated): %d", res);
648
649 /*
650 * Add 1.2.3.4/24 * 5.6.7.8/24 *
651 * Lookup 1.2.3.4 1234 5.6.7.8 4321 and 1.2.3.4 1235 5.6.7.8 4321
652 */
653 args.lcl.fp_addr.ip4 = lcl_ip;
654 args.rmt.fp_addr.ip4 = rmt_ip;
655 args.lcl.fp_len = 24;
656 args.rmt.fp_len = 24;
657 args.lcl_port = 0;
658 args.rmt_port = 0;
659 args.action_index = action_index++;
660 error = session_rules_table_add_del (srt, &args);
661 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
662 action_index - 1);
663 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800664 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700665 SESSION_TEST ((res == 7),
666 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
667 " be 7 (lpm dst): %d", res);
668 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800669 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
Florin Coras1c710452017-10-17 00:03:13 -0700670 lcl_port + 1, rmt_port);
671 SESSION_TEST ((res == 7),
672 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
673 res);
674
675 /*
676 * Del 1.2.3.4/24 * 5.6.7.8/24 *
677 * Add 1.2.3.4/16 * 5.6.7.8/16 * and 1.2.3.4/24 1235 5.6.7.8/24 4321
678 * Lookup 1.2.3.4 1234 5.6.7.8 4321, 1.2.3.4 1235 5.6.7.8 4321 and
679 * 1.2.3.4 1235 5.6.7.8 4322
680 */
681 args.is_add = 0;
682 error = session_rules_table_add_del (srt, &args);
683 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 * 5.6.7.8/24 *");
684
685 args.lcl.fp_addr.ip4 = lcl_ip;
686 args.rmt.fp_addr.ip4 = rmt_ip;
687 args.lcl.fp_len = 16;
688 args.rmt.fp_len = 16;
689 args.lcl_port = 0;
690 args.rmt_port = 0;
691 args.action_index = action_index++;
692 args.is_add = 1;
693 error = session_rules_table_add_del (srt, &args);
694 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 * action %d",
695 action_index - 1);
696
697 args.lcl.fp_addr.ip4 = lcl_ip;
698 args.rmt.fp_addr.ip4 = rmt_ip;
699 args.lcl.fp_len = 24;
700 args.rmt.fp_len = 24;
701 args.lcl_port = lcl_port + 1;
702 args.rmt_port = rmt_port;
703 args.action_index = action_index++;
704 args.is_add = 1;
705 error = session_rules_table_add_del (srt, &args);
706 SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1235 5.6.7.8/24 4321 action %d",
707 action_index - 1);
708
709 if (verbose)
Florin Corasc97a7392017-11-05 23:07:07 -0800710 session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
Florin Coras1c710452017-10-17 00:03:13 -0700711
712 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800713 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700714 SESSION_TEST ((res == 3),
715 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
716 res);
717 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800718 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
Florin Coras1c710452017-10-17 00:03:13 -0700719 lcl_port + 1, rmt_port);
720 SESSION_TEST ((res == 9),
721 "Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
722 res);
723 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800724 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
Florin Coras1c710452017-10-17 00:03:13 -0700725 lcl_port + 1, rmt_port + 1);
726 SESSION_TEST ((res == 8),
727 "Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
728 res);
729
730 /*
731 * Delete 1.2.0.0/16 1234 5.6.0.0/16 4321 and 1.2.0.0/16 * 5.6.0.0/16 *
732 * Lookup 1.2.3.4 1234 5.6.7.8 4321
733 */
734 args.lcl_port = 1234;
735 args.rmt_port = 4321;
736 args.lcl.fp_len = 16;
737 args.rmt.fp_len = 16;
738 args.is_add = 0;
739 error = session_rules_table_add_del (srt, &args);
740 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
741 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800742 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700743 SESSION_TEST ((res == 3),
744 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
745 res);
746
747 args.lcl_port = 0;
748 args.rmt_port = 0;
749 args.is_add = 0;
750 error = session_rules_table_add_del (srt, &args);
751 SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
752 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800753 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700754 SESSION_TEST ((res == 3),
755 "Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
756 res);
757
758 /*
759 * Delete 1.2.3.4/24 1234 5.6.7.5/24
760 */
761 args.lcl.fp_addr.ip4 = lcl_ip;
762 args.rmt.fp_addr.ip4 = rmt_ip;
763 args.lcl.fp_len = 24;
764 args.rmt.fp_len = 24;
765 args.lcl_port = 1234;
766 args.rmt_port = 4321;
767 args.is_add = 0;
768 error = session_rules_table_add_del (srt, &args);
769 SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
770 res =
Florin Corasc97a7392017-11-05 23:07:07 -0800771 session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
Florin Coras1c710452017-10-17 00:03:13 -0700772 SESSION_TEST ((res == 2), "Action should be 2: %d", res);
773
774 return 0;
775}
776
777static int
778session_test_rules (vlib_main_t * vm, unformat_input_t * input)
779{
780 session_endpoint_t server_sep = SESSION_ENDPOINT_NULL;
781 u64 options[SESSION_OPTIONS_N_OPTIONS];
782 u16 lcl_port = 1234, rmt_port = 4321;
783 u32 server_index, app_index;
784 u32 dummy_server_api_index = ~0;
785 transport_connection_t *tc;
786 u32 dummy_port = 1111;
787 clib_error_t *error = 0;
788 u8 segment_name[128];
789 stream_session_t *listener, *s;
790 app_namespace_t *default_ns = app_namespace_get_default ();
791 u32 local_ns_index = default_ns->local_table_index;
Florin Corasf0c1c962017-11-02 21:31:46 -0700792 int verbose = 0;
793
794 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
795 {
796 if (unformat (input, "verbose"))
797 verbose = 1;
798 else
799 {
800 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
801 input);
802 return -1;
803 }
804 }
Florin Coras1c710452017-10-17 00:03:13 -0700805
806 server_sep.is_ip4 = 1;
807 server_sep.port = dummy_port;
808 memset (options, 0, sizeof (options));
809
810 vnet_app_attach_args_t attach_args = {
811 .api_client_index = ~0,
812 .options = options,
813 .namespace_id = 0,
814 .session_cb_vft = &dummy_session_cbs,
815 .segment_name = segment_name,
816 };
817
818 vnet_bind_args_t bind_args = {
819 .sep = server_sep,
820 .app_index = 0,
821 };
822
823 /*
824 * Attach server with global and local default scope
825 */
Florin Coras7999e832017-10-31 01:51:04 -0700826 options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
Florin Coras1c710452017-10-17 00:03:13 -0700827 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
828 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
829 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
830 attach_args.namespace_id = 0;
831 attach_args.api_client_index = dummy_server_api_index;
832 error = vnet_application_attach (&attach_args);
833 SESSION_TEST ((error == 0), "server attached");
834 server_index = attach_args.app_index;
835
836 bind_args.app_index = server_index;
837 error = vnet_bind (&bind_args);
838 SESSION_TEST ((error == 0), "server bound to %U/%d", format_ip46_address,
839 &server_sep.ip, 1, server_sep.port);
840 listener = listen_session_get_from_handle (bind_args.handle);
841 ip4_address_t lcl_ip = {
842 .as_u32 = clib_host_to_net_u32 (0x01020304),
843 };
844 ip4_address_t rmt_ip = {
845 .as_u32 = clib_host_to_net_u32 (0x05060708),
846 };
847 fib_prefix_t lcl_pref = {
848 .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
849 .fp_len = 16,
850 .fp_proto = FIB_PROTOCOL_IP4,
851 };
852 fib_prefix_t rmt_pref = {
853 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
854 .fp_len = 16,
855 .fp_proto = FIB_PROTOCOL_IP4,
856 };
857
858 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
859 &rmt_pref.fp_addr.ip4, lcl_port,
860 rmt_port, TRANSPORT_PROTO_TCP, 0);
861 SESSION_TEST ((tc == 0), "optimized lookup should not work (port)");
862
863 /*
864 * Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action server_index
865 */
866 session_rule_add_del_args_t args = {
867 .table_args.lcl = lcl_pref,
868 .table_args.rmt = rmt_pref,
869 .table_args.lcl_port = lcl_port,
870 .table_args.rmt_port = rmt_port,
871 .table_args.action_index = server_index,
872 .table_args.is_add = 1,
873 .appns_index = 0,
874 };
875 error = vnet_session_rule_add_del (&args);
876 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
877 args.table_args.action_index);
878
879 tc = session_lookup_connection4 (0, &lcl_pref.fp_addr.ip4,
880 &rmt_pref.fp_addr.ip4, lcl_port, rmt_port,
881 TRANSPORT_PROTO_TCP);
882 SESSION_TEST ((tc->c_index == listener->connection_index),
883 "optimized lookup should return the listener");
884 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
885 &rmt_pref.fp_addr.ip4, lcl_port,
886 rmt_port, TRANSPORT_PROTO_TCP, 0);
887 SESSION_TEST ((tc->c_index == listener->connection_index),
888 "lookup should return the listener");
889 s = session_lookup_safe4 (0, &lcl_pref.fp_addr.ip4, &rmt_pref.fp_addr.ip4,
890 lcl_port, rmt_port, TRANSPORT_PROTO_TCP);
891 SESSION_TEST ((s->connection_index == listener->connection_index),
892 "safe lookup should return the listener");
893 session_endpoint_t sep = {
894 .ip = rmt_pref.fp_addr,
895 .is_ip4 = 1,
896 .port = rmt_port,
897 .transport_proto = TRANSPORT_PROTO_TCP,
898 };
899 app_index = session_lookup_local_session_endpoint (local_ns_index, &sep);
900 SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
901 "should not work (global scope)");
902
903 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
904 &rmt_pref.fp_addr.ip4, lcl_port + 1,
905 rmt_port, TRANSPORT_PROTO_TCP, 0);
906 SESSION_TEST ((tc == 0),
Florin Corasf0c1c962017-11-02 21:31:46 -0700907 "optimized lookup for wrong lcl port + 1 should not work");
Florin Coras1c710452017-10-17 00:03:13 -0700908
909 /*
910 * Add 1.2.3.4/16 * 5.6.7.8/16 4321
911 */
912 args.table_args.lcl_port = 0;
913 args.scope = SESSION_RULE_SCOPE_LOCAL | SESSION_RULE_SCOPE_GLOBAL;
914 error = vnet_session_rule_add_del (&args);
915 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 4321 action %d",
916 args.table_args.action_index);
917 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
918 &rmt_pref.fp_addr.ip4, lcl_port + 1,
919 rmt_port, TRANSPORT_PROTO_TCP, 0);
920 SESSION_TEST ((tc->c_index == listener->connection_index),
921 "optimized lookup for lcl port + 1 should work");
922 app_index = session_lookup_local_session_endpoint (local_ns_index, &sep);
923 SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
924 "should not work (constrained lcl ip)");
925
926 /*
Florin Corasf0c1c962017-11-02 21:31:46 -0700927 * Add drop rule 1.2.3.4/32 1234 5.6.7.8/32 4321 action -2 (drop)
928 */
929 args.table_args.lcl_port = 1234;
930 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
931 args.table_args.lcl.fp_len = 32;
932 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
933 args.table_args.rmt.fp_len = 32;
934 args.table_args.action_index = SESSION_RULES_TABLE_ACTION_DROP;
935 error = vnet_session_rule_add_del (&args);
936 SESSION_TEST ((error == 0), "Add 1.2.3.4/32 1234 5.6.7.8/32 4321 action %d",
937 args.table_args.action_index);
938
939 if (verbose)
940 {
941 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
942 TRANSPORT_PROTO_TCP);
943 session_lookup_dump_local_rules_table (0, FIB_PROTOCOL_IP4,
944 TRANSPORT_PROTO_TCP);
945 }
946
947 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
948 &rmt_pref.fp_addr.ip4, lcl_port,
949 rmt_port, TRANSPORT_PROTO_TCP, 0);
950 SESSION_TEST ((tc == 0), "lookup for 1.2.3.4/32 1234 5.6.7.8/16 4321 "
951 "should fail (drop rule)");
952
953 /*
Florin Coras1c710452017-10-17 00:03:13 -0700954 * Add local scope rule for 0/0 * 5.6.7.8/16 4321 action server_index
955 */
Florin Corasf0c1c962017-11-02 21:31:46 -0700956 args.table_args.lcl_port = 0;
Florin Coras1c710452017-10-17 00:03:13 -0700957 args.table_args.lcl.fp_len = 0;
Florin Corasf0c1c962017-11-02 21:31:46 -0700958 args.table_args.rmt.fp_len = 16;
959 args.table_args.action_index = server_index;
Florin Coras1c710452017-10-17 00:03:13 -0700960 error = vnet_session_rule_add_del (&args);
961 SESSION_TEST ((error == 0), "Add * * 5.6.7.8/16 4321 action %d",
962 args.table_args.action_index);
Florin Corasf0c1c962017-11-02 21:31:46 -0700963
964 if (verbose)
965 {
966 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
967 TRANSPORT_PROTO_TCP);
968 session_lookup_dump_local_rules_table (0, FIB_PROTOCOL_IP4,
969 TRANSPORT_PROTO_TCP);
970 }
971
Florin Coras1c710452017-10-17 00:03:13 -0700972 app_index = session_lookup_local_session_endpoint (local_ns_index, &sep);
973 SESSION_TEST ((app_index == server_index), "local session endpoint lookup "
974 "should work");
975
976 /*
977 * Delete 0/0 * 5.6.7.8/16 4321, 1.2.3.4/16 * 5.6.7.8/16 4321 and
978 * 1.2.3.4/16 1234 5.6.7.8/16 4321
979 */
980 args.table_args.is_add = 0;
981 error = vnet_session_rule_add_del (&args);
982 SESSION_TEST ((error == 0), "Del 0/0 * 5.6.7.8/16 4321");
983 app_index = session_lookup_local_session_endpoint (local_ns_index, &sep);
984 SESSION_TEST ((app_index != server_index), "local session endpoint lookup "
985 "should not work (removed)");
986
987 args.table_args.is_add = 0;
988 args.table_args.lcl = lcl_pref;
989 error = vnet_session_rule_add_del (&args);
990 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 * 5.6.7.8/16 4321");
991 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
992 &rmt_pref.fp_addr.ip4, lcl_port + 1,
993 rmt_port, TRANSPORT_PROTO_TCP, 0);
994 SESSION_TEST ((tc == 0), "optimized lookup for lcl port + 1 should not "
995 "work (del)");
996
997 args.table_args.is_add = 0;
998 args.table_args.lcl_port = 1234;
999 error = vnet_session_rule_add_del (&args);
1000 SESSION_TEST ((error == 0), "Del 1.2.3.4/16 1234 5.6.7.8/16 4321");
1001 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1002 &rmt_pref.fp_addr.ip4, lcl_port,
1003 rmt_port, TRANSPORT_PROTO_TCP, 0);
Florin Corasf0c1c962017-11-02 21:31:46 -07001004 SESSION_TEST ((tc == 0),
1005 "optimized lookup should not work (del + negative)");
1006
1007 args.table_args.is_add = 0;
1008 args.table_args.lcl_port = 1234;
1009 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1010 args.table_args.lcl.fp_len = 32;
1011 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1012 args.table_args.rmt.fp_len = 32;
1013 error = vnet_session_rule_add_del (&args);
1014 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 drop");
1015 tc = session_lookup_connection_wt4 (0, &lcl_pref.fp_addr.ip4,
1016 &rmt_pref.fp_addr.ip4, lcl_port,
1017 rmt_port, TRANSPORT_PROTO_TCP, 0);
1018 SESSION_TEST ((tc == 0), "optimized lookup should not work (no-rule)");
Florin Corasc97a7392017-11-05 23:07:07 -08001019
1020 /*
1021 * Test tags. Add/del rule with tag
1022 */
1023 args.table_args.is_add = 1;
1024 args.table_args.lcl_port = 1234;
1025 args.table_args.lcl.fp_addr.ip4 = lcl_ip;
1026 args.table_args.lcl.fp_len = 16;
1027 args.table_args.rmt.fp_addr.ip4 = rmt_ip;
1028 args.table_args.rmt.fp_len = 16;
1029 args.table_args.tag = format (0, "test_rule");
1030 error = vnet_session_rule_add_del (&args);
1031 SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 drop "
1032 "tag test_rule");
1033 if (verbose)
1034 {
1035 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1036 TRANSPORT_PROTO_TCP);
1037 session_lookup_dump_local_rules_table (0, FIB_PROTOCOL_IP4,
1038 TRANSPORT_PROTO_TCP);
1039 }
1040 args.table_args.is_add = 0;
1041 args.table_args.lcl_port += 1;
1042 SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 drop "
1043 "tag test_rule");
1044
Florin Coras4e4531e2017-11-06 23:27:56 -08001045 vnet_app_detach_args_t detach_args = {
1046 .app_index = server_index,
1047 };
1048 vnet_application_detach (&detach_args);
Florin Coras1c710452017-10-17 00:03:13 -07001049 return 0;
1050}
1051
Florin Coras7999e832017-10-31 01:51:04 -07001052static int
1053session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
1054{
1055 u64 options[SESSION_OPTIONS_N_OPTIONS];
1056 u32 server_index, app_index;
1057 u32 dummy_server_api_index = ~0, sw_if_index = 0;
1058 clib_error_t *error = 0;
1059 u8 segment_name[128], intf_mac[6], sst;
1060 stream_session_t *s;
1061 transport_connection_t *tc;
1062 u16 lcl_port = 1234, rmt_port = 4321;
1063 app_namespace_t *app_ns;
1064 int verbose = 0;
1065
1066 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1067 {
1068 if (unformat (input, "verbose"))
1069 verbose = 1;
1070 else
1071 {
1072 vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1073 input);
1074 return -1;
1075 }
1076 }
1077
1078 ip4_address_t lcl_ip = {
1079 .as_u32 = clib_host_to_net_u32 (0x01020304),
1080 };
1081 ip4_address_t rmt_ip = {
1082 .as_u32 = clib_host_to_net_u32 (0x05060708),
1083 };
1084 fib_prefix_t rmt_pref = {
1085 .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
1086 .fp_len = 16,
1087 .fp_proto = FIB_PROTOCOL_IP4,
1088 };
1089 session_endpoint_t sep = {
1090 .ip = rmt_pref.fp_addr,
1091 .is_ip4 = 1,
1092 .port = rmt_port,
1093 .transport_proto = TRANSPORT_PROTO_TCP,
1094 };
1095
1096 /*
1097 * Create loopback interface
1098 */
1099 memset (intf_mac, 0, sizeof (intf_mac));
1100 if (vnet_create_loopback_interface (&sw_if_index, intf_mac, 0, 0))
1101 {
1102 clib_warning ("couldn't create loopback. stopping the test!");
1103 return 0;
1104 }
1105 vnet_sw_interface_set_flags (vnet_get_main (), sw_if_index,
1106 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
1107 ip4_add_del_interface_address (vlib_get_main (), sw_if_index, &lcl_ip,
1108 24, 0);
1109
1110 app_ns = app_namespace_get_default ();
1111 app_ns->sw_if_index = sw_if_index;
1112
1113 memset (options, 0, sizeof (options));
1114 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
1115 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_IS_PROXY;
1116 options[APP_OPTIONS_PROXY_TRANSPORT] = 1 << TRANSPORT_PROTO_TCP;
1117 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1118 options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1119 vnet_app_attach_args_t attach_args = {
1120 .api_client_index = ~0,
1121 .options = options,
1122 .namespace_id = 0,
1123 .session_cb_vft = &dummy_session_cbs,
1124 .segment_name = segment_name,
1125 };
1126
1127 attach_args.api_client_index = dummy_server_api_index;
1128 error = vnet_application_attach (&attach_args);
1129 SESSION_TEST ((error == 0), "server attachment should work");
1130 server_index = attach_args.app_index;
1131
1132 if (verbose)
1133 session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
1134 TRANSPORT_PROTO_TCP);
1135
1136 tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
1137 TRANSPORT_PROTO_TCP, 0);
1138 SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
1139 "successful");
1140 sst = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, 1);
1141 s = listen_session_get (sst, tc->s_index);
1142 SESSION_TEST ((s->app_index == server_index), "lookup should return the"
1143 " server");
1144
1145 tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
1146 TRANSPORT_PROTO_TCP, 0);
1147 SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
1148 " not work");
1149
1150 if (verbose)
1151 session_lookup_dump_local_rules_table (app_ns->local_table_index,
1152 FIB_PROTOCOL_IP4,
1153 TRANSPORT_PROTO_TCP);
1154 app_index =
1155 session_lookup_local_session_endpoint (app_ns->local_table_index, &sep);
1156 SESSION_TEST ((app_index == server_index), "local session endpoint lookup"
1157 " should work");
1158
1159 vnet_app_detach_args_t detach_args = {
1160 .app_index = server_index,
1161 };
1162 vnet_application_detach (&detach_args);
1163
1164 if (verbose)
1165 session_lookup_dump_local_rules_table (app_ns->local_table_index,
1166 FIB_PROTOCOL_IP4,
1167 TRANSPORT_PROTO_TCP);
1168
1169 app_index =
1170 session_lookup_local_session_endpoint (app_ns->local_table_index, &sep);
1171 SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
1172 "local session endpoint lookup should not work after detach");
1173
1174 return 0;
1175}
1176
Florin Corascea194d2017-10-02 00:18:51 -07001177static clib_error_t *
1178session_test (vlib_main_t * vm,
1179 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
1180{
1181 int res = 0;
1182
1183 vnet_session_enable_disable (vm, 1);
1184
1185 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1186 {
Florin Coras4e4531e2017-11-06 23:27:56 -08001187 if (unformat (input, "basic"))
1188 res = session_test_basic (vm, input);
1189 else if (unformat (input, "namespace"))
1190 res = session_test_namespace (vm, input);
Florin Coras1c710452017-10-17 00:03:13 -07001191 else if (unformat (input, "rules-table"))
1192 res = session_test_rule_table (vm, input);
1193 else if (unformat (input, "rules"))
1194 res = session_test_rules (vm, input);
Florin Coras7999e832017-10-31 01:51:04 -07001195 else if (unformat (input, "proxy"))
1196 res = session_test_proxy (vm, input);
Florin Coras4e4531e2017-11-06 23:27:56 -08001197 else if (unformat (input, "all"))
1198 {
1199 if ((res = session_test_basic (vm, input)))
1200 goto done;
1201 if ((res = session_test_namespace (vm, input)))
1202 goto done;
1203 if ((res = session_test_rule_table (vm, input)))
1204 goto done;
1205 if ((res = session_test_rules (vm, input)))
1206 goto done;
1207 if ((res = session_test_proxy (vm, input)))
1208 goto done;
1209 }
Florin Corascea194d2017-10-02 00:18:51 -07001210 else
1211 break;
1212 }
1213
Florin Coras4e4531e2017-11-06 23:27:56 -08001214done:
Florin Corascea194d2017-10-02 00:18:51 -07001215 if (res)
1216 return clib_error_return (0, "Session unit test failed");
1217 return 0;
1218}
1219
1220/* *INDENT-OFF* */
1221VLIB_CLI_COMMAND (tcp_test_command, static) =
1222{
1223 .path = "test session",
1224 .short_help = "internal session unit tests",
1225 .function = session_test,
1226};
1227/* *INDENT-ON* */
1228
1229/*
1230 * fd.io coding-style-patch-verification: ON
1231 *
1232 * Local Variables:
1233 * eval: (c-set-style "gnu")
1234 * End:
1235 */