aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/spelling_wordlist.txt1
-rw-r--r--src/plugins/hs_apps/echo_client.c5
-rw-r--r--src/plugins/hs_apps/echo_server.c5
-rw-r--r--src/plugins/hs_apps/http_cli.c5
-rw-r--r--src/plugins/hs_apps/http_client_cli.c5
-rw-r--r--src/plugins/hs_apps/http_simple_post.c7
-rw-r--r--src/plugins/hs_apps/http_tps.c5
-rw-r--r--src/plugins/hs_apps/proxy.c5
-rw-r--r--src/plugins/http_static/http_static.c5
-rw-r--r--src/plugins/http_static/static_server.c5
-rw-r--r--src/plugins/tlsopenssl/tls_openssl.c5
-rw-r--r--src/plugins/unittest/segment_manager_test.c5
-rw-r--r--src/plugins/unittest/session_test.c365
-rw-r--r--src/plugins/unittest/tcp_test.c5
-rw-r--r--src/vnet/CMakeLists.txt1
-rw-r--r--src/vnet/session/application_namespace.c11
-rw-r--r--src/vnet/session/application_namespace.h4
-rw-r--r--src/vnet/session/session.api60
-rw-r--r--src/vnet/session/session.c48
-rw-r--r--src/vnet/session/session.h50
-rw-r--r--src/vnet/session/session_api.c249
-rw-r--r--src/vnet/session/session_cli.c65
-rw-r--r--src/vnet/session/session_lookup.c272
-rw-r--r--src/vnet/session/session_lookup.h15
-rw-r--r--src/vnet/session/session_rules_table.c313
-rw-r--r--src/vnet/session/session_rules_table.h216
-rw-r--r--src/vnet/session/session_sdl.c768
-rw-r--r--src/vnet/session/session_sdl.h36
-rw-r--r--src/vnet/session/session_table.c15
-rw-r--r--src/vnet/session/session_table.h3
-rw-r--r--src/vnet/session/session_test.c23
-rw-r--r--test/asf/test_session_sdl.py297
-rw-r--r--test/asf/vpp_session_sdl.py75
33 files changed, 2620 insertions, 329 deletions
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index e4283909d99..8de7bf4ee24 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -1004,6 +1004,7 @@ screenshot
scrollbar
scrollbars
sctp
+sdl
sealert
seatbelt
seg
diff --git a/src/plugins/hs_apps/echo_client.c b/src/plugins/hs_apps/echo_client.c
index d1443e75e80..8dec5d86824 100644
--- a/src/plugins/hs_apps/echo_client.c
+++ b/src/plugins/hs_apps/echo_client.c
@@ -429,8 +429,11 @@ ec_init (vlib_main_t *vm)
ecm->app_is_init = 1;
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
vlib_worker_thread_barrier_sync (vm);
- vnet_session_enable_disable (vm, 1 /* turn on session and transports */);
+ vnet_session_enable_disable (vm, &args);
/* Turn on the builtin client input nodes */
foreach_vlib_main ()
diff --git a/src/plugins/hs_apps/echo_server.c b/src/plugins/hs_apps/echo_server.c
index 0243252434a..756a1cc3451 100644
--- a/src/plugins/hs_apps/echo_server.c
+++ b/src/plugins/hs_apps/echo_server.c
@@ -736,7 +736,10 @@ echo_server_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
goto cleanup;
}
- vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (vm, &args);
if (!server_uri_set)
{
diff --git a/src/plugins/hs_apps/http_cli.c b/src/plugins/hs_apps/http_cli.c
index 17624b3e827..e0bb9afba4a 100644
--- a/src/plugins/hs_apps/http_cli.c
+++ b/src/plugins/hs_apps/http_cli.c
@@ -731,7 +731,10 @@ start_server:
if (hcm->app_index != (u32) ~0)
return clib_error_return (0, "test http server is already running");
- vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (vm, &args);
rv = hcs_create (vm);
switch (rv)
diff --git a/src/plugins/hs_apps/http_client_cli.c b/src/plugins/hs_apps/http_client_cli.c
index 722499b24c3..afa173c98df 100644
--- a/src/plugins/hs_apps/http_client_cli.c
+++ b/src/plugins/hs_apps/http_client_cli.c
@@ -558,8 +558,11 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input,
goto done;
}
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
vlib_worker_thread_barrier_sync (vm);
- vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */);
+ vnet_session_enable_disable (vm, &args);
vlib_worker_thread_barrier_release (vm);
err = hcc_run (vm, print_output);
diff --git a/src/plugins/hs_apps/http_simple_post.c b/src/plugins/hs_apps/http_simple_post.c
index b0b9a38db2d..0c2b30ad25c 100644
--- a/src/plugins/hs_apps/http_simple_post.c
+++ b/src/plugins/hs_apps/http_simple_post.c
@@ -522,8 +522,11 @@ hsp_command_fn (vlib_main_t *vm, unformat_input_t *input,
goto done;
}
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
vlib_worker_thread_barrier_sync (vm);
- vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */);
+ vnet_session_enable_disable (vm, &args);
vlib_worker_thread_barrier_release (vm);
hspm->cli_node_index =
@@ -566,4 +569,4 @@ hsp_main_init (vlib_main_t *vm)
return 0;
}
-VLIB_INIT_FUNCTION (hsp_main_init); \ No newline at end of file
+VLIB_INIT_FUNCTION (hsp_main_init);
diff --git a/src/plugins/hs_apps/http_tps.c b/src/plugins/hs_apps/http_tps.c
index b37c447295a..35a5802f476 100644
--- a/src/plugins/hs_apps/http_tps.c
+++ b/src/plugins/hs_apps/http_tps.c
@@ -760,7 +760,10 @@ start_server:
if (htm->app_index == (u32) ~0)
{
- vnet_session_enable_disable (vm, 1 /* is_enable */);
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (vm, &args);
if (hts_create (vm))
{
diff --git a/src/plugins/hs_apps/proxy.c b/src/plugins/hs_apps/proxy.c
index e8fedf921a5..5edea0945b0 100644
--- a/src/plugins/hs_apps/proxy.c
+++ b/src/plugins/hs_apps/proxy.c
@@ -915,7 +915,10 @@ proxy_server_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
goto done;
}
- vnet_session_enable_disable (vm, 1 /* turn on session and transport */ );
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (vm, &args);
rv = proxy_server_create (vm);
switch (rv)
diff --git a/src/plugins/http_static/http_static.c b/src/plugins/http_static/http_static.c
index 9a98763b312..967b8474af8 100644
--- a/src/plugins/http_static/http_static.c
+++ b/src/plugins/http_static/http_static.c
@@ -85,7 +85,10 @@ hss_enable_api (u32 fifo_size, u32 cache_limit, u32 prealloc_fifos,
if (hsm->app_index != ~0)
return VNET_API_ERROR_APP_ALREADY_ATTACHED;
- vnet_session_enable_disable (hsm->vlib_main, 1 /* turn on TCP, etc. */);
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (hsm->vlib_main, &args);
rv = hss_create (hsm->vlib_main);
switch (rv)
diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c
index 674ce8a0580..5515a98b446 100644
--- a/src/plugins/http_static/static_server.c
+++ b/src/plugins/http_static/static_server.c
@@ -950,7 +950,10 @@ no_input:
goto done;
}
- vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (vm, &args);
if ((rv = hss_create (vm)))
{
diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c
index 5d172a0adcf..19aae3ffadc 100644
--- a/src/plugins/tlsopenssl/tls_openssl.c
+++ b/src/plugins/tlsopenssl/tls_openssl.c
@@ -1286,7 +1286,10 @@ tls_openssl_set_command_fn (vlib_main_t * vm, unformat_input_t * input,
}
else
{
- vnet_session_enable_disable (vm, 1);
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (vm, &args);
if (openssl_engine_register (engine_name, engine_alg, async) < 0)
{
return clib_error_return (0, "Failed to register %s polling",
diff --git a/src/plugins/unittest/segment_manager_test.c b/src/plugins/unittest/segment_manager_test.c
index a106470ee48..29da662e007 100644
--- a/src/plugins/unittest/segment_manager_test.c
+++ b/src/plugins/unittest/segment_manager_test.c
@@ -739,8 +739,11 @@ segment_manager_test (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd_arg)
{
int res = 0;
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
- vnet_session_enable_disable (vm, 1);
+ vnet_session_enable_disable (vm, &args);
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
diff --git a/src/plugins/unittest/session_test.c b/src/plugins/unittest/session_test.c
index 6d28b2d25ec..a70a6ea88bf 100644
--- a/src/plugins/unittest/session_test.c
+++ b/src/plugins/unittest/session_test.c
@@ -13,13 +13,11 @@
* limitations under the License.
*/
-#include <vnet/session/application_namespace.h>
-#include <vnet/session/application_interface.h>
+#include <arpa/inet.h>
#include <vnet/session/application.h>
#include <vnet/session/session.h>
-#include <vnet/session/session_rules_table.h>
-#include <vnet/tcp/tcp.h>
#include <sys/epoll.h>
+#include <vnet/session/session_rules_table.h>
#define SESSION_TEST_I(_cond, _comment, _args...) \
({ \
@@ -775,10 +773,37 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
return 0;
}
+static void
+session_test_disable_rt_backend_engine (vlib_main_t *vm)
+{
+ session_enable_disable_args_t args = { .is_en = 0,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_DISABLE };
+ vnet_session_enable_disable (vm, &args);
+}
+
+static void
+session_test_enable_rule_table_engine (vlib_main_t *vm)
+{
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
+ vnet_session_enable_disable (vm, &args);
+}
+
+static void
+session_test_enable_sdl_engine (vlib_main_t *vm)
+{
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_SDL };
+ vnet_session_enable_disable (vm, &args);
+}
+
static int
session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
{
- session_rules_table_t _srt, *srt = &_srt;
+ session_table_t *st = session_table_alloc ();
u16 lcl_port = 1234, rmt_port = 4321;
u32 action_index = 1, res;
ip4_address_t lcl_lkup, rmt_lkup;
@@ -796,8 +821,11 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
}
}
- clib_memset (srt, 0, sizeof (*srt));
- session_rules_table_init (srt);
+ session_test_disable_rt_backend_engine (vm);
+ session_test_enable_rule_table_engine (vm);
+
+ session_table_init (st, FIB_PROTOCOL_MAX);
+ session_rules_table_init (st, FIB_PROTOCOL_MAX);
ip4_address_t lcl_ip = {
.as_u32 = clib_host_to_net_u32 (0x01020304),
@@ -836,12 +864,13 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
.action_index = action_index++,
.is_add = 1,
};
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 1.2.3.4/16 1234 5.6.7.8/16 4321 action %d",
action_index - 1);
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
SESSION_TEST ((res == 1),
"Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 1: %d",
res);
@@ -852,13 +881,15 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.lcl.fp_addr.ip4 = lcl_ip;
args.lcl.fp_len = 24;
args.action_index = action_index++;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/16 4321 action %d",
action_index - 1);
args.rmt.fp_addr.ip4 = rmt_ip;
args.rmt.fp_len = 24;
args.action_index = action_index++;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1234 5.6.7.8/24 4321 action %d",
action_index - 1);
@@ -870,13 +901,15 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.rmt.fp_addr.ip4 = rmt_ip2;
args.rmt.fp_len = 16;
args.action_index = action_index++;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 2.2.2.2/24 1234 6.6.6.6/16 4321 action %d",
action_index - 1);
args.lcl.fp_addr.ip4 = lcl_ip3;
args.rmt.fp_addr.ip4 = rmt_ip3;
args.action_index = action_index++;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 3.3.3.3/24 1234 7.7.7.7/16 4321 action %d",
action_index - 1);
@@ -886,7 +919,8 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.lcl.fp_addr.ip4 = lcl_ip3;
args.rmt.fp_addr.ip4 = rmt_ip3;
args.action_index = action_index++;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "overwrite 3.3.3.3/24 1234 7.7.7.7/16 4321 "
"action %d", action_index - 1);
@@ -894,23 +928,22 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
* 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
* and 3.3.3.3 1234 7.7.7.7 4321
*/
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
SESSION_TEST ((res == 3),
"Lookup 1.2.3.4 1234 5.6.7.8 4321 action " "should be 3: %d",
res);
lcl_lkup.as_u32 = clib_host_to_net_u32 (0x01020204);
rmt_lkup.as_u32 = clib_host_to_net_u32 (0x05060709);
- res =
- session_rules_table_lookup4 (srt, &lcl_lkup,
- &rmt_lkup, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_lkup, &rmt_lkup, lcl_port, rmt_port);
SESSION_TEST ((res == 1),
"Lookup 1.2.2.4 1234 5.6.7.9 4321, action " "should be 1: %d",
res);
- res =
- session_rules_table_lookup4 (srt, &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip3, &rmt_ip3, lcl_port, rmt_port);
SESSION_TEST ((res == 6),
"Lookup 3.3.3.3 1234 7.7.7.7 4321, action "
"should be 6 (updated): %d", res);
@@ -926,17 +959,17 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.lcl_port = 0;
args.rmt_port = 0;
args.action_index = action_index++;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 1.2.3.4/24 * 5.6.7.8/24 * action %d",
action_index - 1);
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
SESSION_TEST ((res == 7),
"Lookup 1.2.3.4 1234 5.6.7.8 4321, action should"
" be 7 (lpm dst): %d", res);
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
- lcl_port + 1, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port + 1, rmt_port);
SESSION_TEST ((res == 7),
"Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 7: %d",
res);
@@ -948,7 +981,8 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
* 1.2.3.4 1235 5.6.7.8 4322
*/
args.is_add = 0;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Del 1.2.3.4/24 * 5.6.7.8/24 *");
args.lcl.fp_addr.ip4 = lcl_ip;
@@ -959,7 +993,8 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.rmt_port = 0;
args.action_index = action_index++;
args.is_add = 1;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 1.2.3.4/16 * 5.6.7.8/16 * action %d",
action_index - 1);
@@ -971,27 +1006,28 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.rmt_port = rmt_port;
args.action_index = action_index++;
args.is_add = 1;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Add 1.2.3.4/24 1235 5.6.7.8/24 4321 action %d",
action_index - 1);
if (verbose)
- session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
+ session_rules_table_cli_dump (vm, st->srtg_handle, TRANSPORT_PROTO_TCP,
+ FIB_PROTOCOL_IP4);
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
SESSION_TEST ((res == 3),
"Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
res);
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
- lcl_port + 1, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port + 1, rmt_port);
SESSION_TEST ((res == 9),
"Lookup 1.2.3.4 1235 5.6.7.8 4321, action should " "be 9: %d",
res);
res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip,
- lcl_port + 1, rmt_port + 1);
+ session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP, &lcl_ip,
+ &rmt_ip, lcl_port + 1, rmt_port + 1);
SESSION_TEST ((res == 8),
"Lookup 1.2.3.4 1235 5.6.7.8 4322, action should " "be 8: %d",
res);
@@ -1005,10 +1041,11 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.lcl.fp_len = 16;
args.rmt.fp_len = 16;
args.is_add = 0;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Del 1.2.0.0/16 1234 5.6.0.0/16 4321");
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
SESSION_TEST ((res == 3),
"Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
res);
@@ -1016,10 +1053,11 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.lcl_port = 0;
args.rmt_port = 0;
args.is_add = 0;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Del 1.2.0.0/16 * 5.6.0.0/16 *");
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
SESSION_TEST ((res == 3),
"Lookup 1.2.3.4 1234 5.6.7.8 4321, action should " "be 3: %d",
res);
@@ -1034,12 +1072,15 @@ session_test_rule_table (vlib_main_t * vm, unformat_input_t * input)
args.lcl_port = 1234;
args.rmt_port = 4321;
args.is_add = 0;
- error = session_rules_table_add_del (srt, &args);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
SESSION_TEST ((error == 0), "Del 1.2.3.4/24 1234 5.6.7.5/24");
- res =
- session_rules_table_lookup4 (srt, &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
SESSION_TEST ((res == 2), "Action should be 2: %d", res);
+ session_table_free (st, FIB_PROTOCOL_MAX);
+
return 0;
}
@@ -1075,6 +1116,9 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
}
}
+ session_test_disable_rt_backend_engine (vm);
+ session_test_enable_rule_table_engine (vm);
+
server_sep.is_ip4 = 1;
server_sep.port = placeholder_port;
clib_memset (options, 0, sizeof (options));
@@ -2115,15 +2159,19 @@ session_test_enable_disable (vlib_main_t *vm, unformat_input_t *input)
/* warm up */
for (i = 0; i < 10; i++)
{
- vnet_session_enable_disable (vm, 0);
- vnet_session_enable_disable (vm, 1);
+ session_test_disable_rt_backend_engine (vm);
+ session_test_enable_sdl_engine (vm);
+ session_test_disable_rt_backend_engine (vm);
+ session_test_enable_rule_table_engine (vm);
}
was_using = session_get_memory_usage ();
for (i = 0; i < iteration; i++)
{
- vnet_session_enable_disable (vm, 0);
- vnet_session_enable_disable (vm, 1);
+ session_test_disable_rt_backend_engine (vm);
+ session_test_enable_sdl_engine (vm);
+ session_test_disable_rt_backend_engine (vm);
+ session_test_enable_rule_table_engine (vm);
}
now_using = session_get_memory_usage ();
@@ -2134,13 +2182,220 @@ session_test_enable_disable (vlib_main_t *vm, unformat_input_t *input)
return 0;
}
+static int
+session_test_sdl (vlib_main_t *vm, unformat_input_t *input)
+{
+ session_table_t *st = session_table_alloc ();
+ u16 lcl_port = 0, rmt_port = 0;
+ u32 action_index = 1, res;
+ int verbose = 0, error;
+ ip4_address_t lcl_ip;
+ const char ip_str_1234[] = "1.2.3.4";
+ inet_pton (AF_INET, ip_str_1234, &lcl_ip);
+ ip4_address_t rmt_ip = {
+ .as_u32 = clib_host_to_net_u32 (0x0),
+ };
+ ip6_address_t rmt_ip6 = {
+ .as_u64 = { 0, 0 },
+ };
+ fib_prefix_t lcl_pref = {
+ .fp_addr.ip4.as_u32 = lcl_ip.as_u32,
+ .fp_len = 16,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ };
+ fib_prefix_t rmt_pref = {
+ .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
+ .fp_len = 0,
+ .fp_proto = 0,
+ };
+ session_rule_table_add_del_args_t args = {
+ .lcl = lcl_pref,
+ .rmt = rmt_pref,
+ .lcl_port = lcl_port,
+ .rmt_port = rmt_port,
+ .action_index = action_index++,
+ .is_add = 1,
+ };
+ const char ip_str_1200[] = "1.2.0.0";
+ const char ip_str_1230[] = "1.2.3.0";
+ const char ip_str_1111[] = "1.1.1.1";
+ const char ip6_str[] = "2501:0db8:85a3:0000:0000:8a2e:0371:1";
+ const char ip6_str2[] = "2501:0db8:85a3:0000:0000:8a2e:0372:1";
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "verbose"))
+ verbose = 1;
+ else
+ {
+ vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
+ input);
+ return -1;
+ }
+ }
+
+ session_test_disable_rt_backend_engine (vm);
+ session_test_enable_sdl_engine (vm);
+
+ session_table_init (st, FIB_PROTOCOL_MAX);
+ session_rules_table_init (st, FIB_PROTOCOL_MAX);
+
+ /* Add 1.2.0.0/16 */
+ args.lcl.fp_len = 16;
+ inet_pton (AF_INET, ip_str_1200, &args.lcl.fp_addr.ip4.as_u32);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == 0), "Add %s/%d action %d", ip_str_1200,
+ args.lcl.fp_len, action_index - 1);
+
+ /* Lookup 1.2.3.4 */
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ SESSION_TEST ((res == action_index - 1),
+ "Lookup %s, action should "
+ "be 1: %d",
+ ip_str_1234, action_index - 1);
+
+ /*
+ * Add 1.2.3.0/24
+ */
+ args.lcl.fp_len = 24;
+ inet_pton (AF_INET, ip_str_1230, &args.lcl.fp_addr.ip4.as_u32);
+ args.action_index = action_index++;
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == 0), "Add %s/%d action %d", ip_str_1230,
+ args.lcl.fp_len, action_index - 1);
+
+ /* Lookup 1.2.3.4 */
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ SESSION_TEST ((res == action_index - 1),
+ "Lookup %s, action should "
+ "be 2: %d",
+ ip_str_1234, action_index - 1);
+
+ /* look up 1.1.1.1, should be -1 (invalid index) */
+ inet_pton (AF_INET, ip_str_1111, &lcl_ip);
+ res = session_rules_table_lookup4 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_ip, &rmt_ip, lcl_port, rmt_port);
+ SESSION_TEST ((res == SESSION_TABLE_INVALID_INDEX),
+ "Lookup %s, action should "
+ "be -1: %d",
+ ip_str_1111, res);
+
+ /* Add again 1.2.0.0/16, should be rejected */
+ args.lcl.fp_len = 16;
+ inet_pton (AF_INET, ip_str_1200, &args.lcl.fp_addr.ip4.as_u32);
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == SESSION_E_IPINUSE), "Add %s/%d action %d",
+ ip_str_1200, args.lcl.fp_len, error);
+ /*
+ * Add 0.0.0.0/0, should get an error
+ */
+ args.lcl.fp_len = 0;
+ args.lcl.fp_addr.ip4.as_u32 = 0;
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == SESSION_E_IPINUSE), "Add 0.0.0.0/%d action %d",
+ args.lcl.fp_len, error);
+
+ /* delete 0.0.0.0 should be rejected */
+ args.is_add = 0;
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == SESSION_E_NOROUTE), "Del 0.0.0.0/%d action %d",
+ args.lcl.fp_len, error);
+ if (verbose)
+ session_rules_table_cli_dump (vm, st->srtg_handle, TRANSPORT_PROTO_TCP,
+ FIB_PROTOCOL_IP4);
+
+ /*
+ * Clean up
+ * Delete 1.2.0.0/16
+ * Delete 1.2.3.0/24
+ */
+ inet_pton (AF_INET, ip_str_1200, &args.lcl.fp_addr.ip4.as_u32);
+ args.lcl.fp_len = 16;
+ args.is_add = 0;
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == 0), "Del %s/%d should 0: %d", ip_str_1200,
+ args.lcl.fp_len, error);
+
+ inet_pton (AF_INET, ip_str_1230, &args.lcl.fp_addr.ip4.as_u32);
+ args.lcl.fp_len = 24;
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == 0), "Del %s/%d, should be 0: %d", ip_str_1230,
+ args.lcl.fp_len, error);
+ if (verbose)
+ session_rules_table_cli_dump (vm, st->srtg_handle, TRANSPORT_PROTO_TCP,
+ FIB_PROTOCOL_IP4);
+
+ /* ip6 tests */
+
+ /*
+ * Add ip6 2001:0db8:85a3:0000:0000:8a2e:0371:1/124
+ */
+ ip6_address_t lcl_lkup;
+ inet_pton (AF_INET6, ip6_str, &args.lcl.fp_addr.ip6);
+ args.lcl.fp_len = 124;
+ args.lcl.fp_proto = FIB_PROTOCOL_IP6;
+ args.action_index = action_index++;
+ args.is_add = 1;
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == 0), "Add %s/%d action %d", ip6_str, args.lcl.fp_len,
+ action_index - 1);
+ if (verbose)
+ session_rules_table_cli_dump (vm, st->srtg_handle, TRANSPORT_PROTO_TCP,
+ FIB_PROTOCOL_IP6);
+
+ /* Lookup 2001:0db8:85a3:0000:0000:8a2e:0371:1 */
+ res = session_rules_table_lookup6 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &args.lcl.fp_addr.ip6, &rmt_ip6, lcl_port,
+ rmt_port);
+ SESSION_TEST ((res == action_index - 1),
+ "Lookup %s action should "
+ "be 3: %d",
+ ip6_str, action_index - 1);
+
+ /* Lookup 2001:0db8:85a3:0000:0000:8a2e:0372:1 */
+ inet_pton (AF_INET6, ip6_str2, &lcl_lkup);
+ res = session_rules_table_lookup6 (st->srtg_handle, TRANSPORT_PROTO_TCP,
+ &lcl_lkup, &rmt_ip6, lcl_port, rmt_port);
+ SESSION_TEST ((res == SESSION_TABLE_INVALID_INDEX),
+ "Lookup %s action should "
+ "be -1: %d",
+ ip6_str2, res);
+
+ /*
+ * del ip6 2001:0db8:85a3:0000:0000:8a2e:0371:1/124
+ */
+ args.is_add = 0;
+ args.lcl.fp_len = 124;
+ error =
+ session_rules_table_add_del (st->srtg_handle, TRANSPORT_PROTO_TCP, &args);
+ SESSION_TEST ((error == 0), "del %s/%d, should be 0: %d", ip6_str,
+ args.lcl.fp_len, error);
+ if (verbose)
+ session_rules_table_cli_dump (vm, st->srtg_handle, TRANSPORT_PROTO_TCP,
+ FIB_PROTOCOL_IP6);
+
+ session_table_free (st, FIB_PROTOCOL_MAX);
+
+ return 0;
+}
+
static clib_error_t *
session_test (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd_arg)
{
int res = 0;
- vnet_session_enable_disable (vm, 1);
+ session_test_enable_rule_table_engine (vm);
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -2162,6 +2417,8 @@ session_test (vlib_main_t * vm,
res = session_test_mq_basic (vm, input);
else if (unformat (input, "enable-disable"))
res = session_test_enable_disable (vm, input);
+ else if (unformat (input, "sdl"))
+ res = session_test_sdl (vm, input);
else if (unformat (input, "all"))
{
if ((res = session_test_basic (vm, input)))
@@ -2180,6 +2437,8 @@ session_test (vlib_main_t * vm,
goto done;
if ((res = session_test_mq_basic (vm, input)))
goto done;
+ if ((res = session_test_sdl (vm, input)))
+ goto done;
if ((res = session_test_enable_disable (vm, input)))
goto done;
}
diff --git a/src/plugins/unittest/tcp_test.c b/src/plugins/unittest/tcp_test.c
index 34033a0b622..bd39474ce93 100644
--- a/src/plugins/unittest/tcp_test.c
+++ b/src/plugins/unittest/tcp_test.c
@@ -1550,8 +1550,11 @@ tcp_test (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd_arg)
{
int res = 0;
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ RT_BACKEND_ENGINE_RULE_TABLE };
- vnet_session_enable_disable (vm, 1);
+ vnet_session_enable_disable (vm, &args);
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt
index 1af2d40eff1..6262e803057 100644
--- a/src/vnet/CMakeLists.txt
+++ b/src/vnet/CMakeLists.txt
@@ -1012,6 +1012,7 @@ list(APPEND VNET_SOURCES
session/application_namespace.c
session/segment_manager.c
session/session_api.c
+ session/session_sdl.c
)
list(APPEND VNET_HEADERS
diff --git a/src/vnet/session/application_namespace.c b/src/vnet/session/application_namespace.c
index dbc6a6be80f..8b06331d803 100644
--- a/src/vnet/session/application_namespace.c
+++ b/src/vnet/session/application_namespace.c
@@ -34,6 +34,17 @@ static app_namespace_t *app_namespace_pool;
static u8 app_sapi_enabled;
+void
+app_namespace_walk (app_namespace_walk_fn_t fn, void *ctx)
+{
+ app_namespace_t *app_ns;
+
+ pool_foreach (app_ns, app_namespace_pool)
+ {
+ fn (app_ns, ctx);
+ }
+}
+
app_namespace_t *
app_namespace_get (u32 index)
{
diff --git a/src/vnet/session/application_namespace.h b/src/vnet/session/application_namespace.h
index 261325cbe0e..b441e3c48f2 100644
--- a/src/vnet/session/application_namespace.h
+++ b/src/vnet/session/application_namespace.h
@@ -15,6 +15,7 @@
#include <vppinfra/socket.h>
#include <vnet/vnet.h>
+#include <vnet/session/session_types.h>
#include <vnet/session/session_table.h>
#ifndef SRC_VNET_SESSION_APPLICATION_NAMESPACE_H_
@@ -87,6 +88,9 @@ vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t *a);
u32 app_namespace_get_fib_index (app_namespace_t * app_ns, u8 fib_proto);
session_table_t *app_namespace_get_local_table (app_namespace_t * app_ns);
+typedef void (*app_namespace_walk_fn_t) (app_namespace_t *app_ns, void *ctx);
+extern void app_namespace_walk (app_namespace_walk_fn_t fn, void *ctx);
+
always_inline app_namespace_t *
app_namespace_get_default (void)
{
diff --git a/src/vnet/session/session.api b/src/vnet/session/session.api
index 6affae4112d..26346eaa466 100644
--- a/src/vnet/session/session.api
+++ b/src/vnet/session/session.api
@@ -13,12 +13,19 @@
* limitations under the License.
*/
-option version = "4.0.0";
+option version = "4.0.1";
import "vnet/interface_types.api";
import "vnet/ip/ip_types.api";
+typedef sdl_rule
+{
+ vl_api_prefix_t lcl;
+ u32 action_index;
+ string tag[64];
+};
+
enum transport_proto : u8
{
TRANSPORT_PROTO_API_TCP,
@@ -28,6 +35,14 @@ enum transport_proto : u8
TRANSPORT_PROTO_API_QUIC,
};
+enum rt_backend_engine : u8
+{
+ RT_BACKEND_ENGINE_API_DISABLE = 0,
+ RT_BACKEND_ENGINE_API_RULE_TABLE,
+ RT_BACKEND_ENGINE_API_NONE,
+ RT_BACKEND_ENGINE_API_SDL,
+};
+
/** \brief Application attach to session layer
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@@ -166,11 +181,18 @@ define app_worker_add_del_reply
@param is_enable - disable session layer if 0, enable otherwise
*/
autoreply define session_enable_disable {
+ option deprecated;
u32 client_index;
u32 context;
bool is_enable [default=true];
};
+autoreply define session_enable_disable_v2 {
+ u32 client_index;
+ u32 context;
+ vl_api_rt_backend_engine_t rt_engine_type;
+};
+
/** \brief enable/disable session layer socket api
@param client_index - opaque cookie to identify the sender
client to vpp direction only
@@ -417,6 +439,42 @@ define session_rules_details
string tag[64];
};
+autoreply define session_sdl_add_del {
+ u32 client_index;
+ u32 context;
+ u32 appns_index;
+ bool is_add;
+ u32 count;
+ vl_api_sdl_rule_t r[count];
+};
+
+/** \brief Dump session sdl
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ */
+define session_sdl_dump
+{
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Session sdl details
+ @param context - sender context, to match reply w/ request
+ @param lcl - local prefix
+ @param action_index - the only action defined now is forward to
+ application with index action_index
+ @param appns_index - application namespace where rule is to be applied to
+ @param tag - tag
+ */
+define session_sdl_details
+{
+ u32 context;
+ vl_api_prefix_t lcl;
+ u32 action_index;
+ u32 appns_index;
+ string tag[64];
+};
+
/*
* Local Variables:
* eval: (c-set-style "gnu")
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index c1becf2c5ea..ac02281cf5c 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -24,6 +24,7 @@
#include <vnet/fib/ip4_fib.h>
#include <vlib/stats/stats.h>
#include <vlib/dma/dma.h>
+#include <vnet/session/session_rules_table.h>
session_main_t session_main;
@@ -1996,7 +1997,8 @@ session_stats_collector_init (void)
}
static clib_error_t *
-session_manager_main_enable (vlib_main_t * vm)
+session_manager_main_enable (vlib_main_t *vm,
+ session_rt_engine_type_t rt_engine_type)
{
session_main_t *smm = &session_main;
vlib_thread_main_t *vtm = vlib_get_thread_main ();
@@ -2004,6 +2006,9 @@ session_manager_main_enable (vlib_main_t * vm)
session_worker_t *wrk;
int i;
+ if (session_rt_backend_enable_disable (rt_engine_type))
+ return clib_error_return (0, "error on enable backend engine");
+
/* We only initialize once and do not de-initialized on disable */
if (smm->is_initialized)
goto done;
@@ -2082,9 +2087,11 @@ done:
}
static void
-session_manager_main_disable (vlib_main_t * vm)
+session_manager_main_disable (vlib_main_t *vm,
+ session_rt_engine_type_t rt_engine_type)
{
transport_enable_disable (vm, 0 /* is_en */ );
+ session_rt_backend_enable_disable (rt_engine_type);
}
/* in this new callback, cookie hint the index */
@@ -2221,22 +2228,24 @@ session_node_enable_disable (u8 is_en)
}
clib_error_t *
-vnet_session_enable_disable (vlib_main_t * vm, u8 is_en)
+vnet_session_enable_disable (vlib_main_t *vm,
+ session_enable_disable_args_t *args)
{
clib_error_t *error = 0;
- if (is_en)
+
+ if (args->is_en)
{
if (session_main.is_enabled)
return 0;
- error = session_manager_main_enable (vm);
- session_node_enable_disable (is_en);
+ error = session_manager_main_enable (vm, args->rt_engine_type);
+ session_node_enable_disable (1);
}
else
{
session_main.is_enabled = 0;
- session_manager_main_disable (vm);
- session_node_enable_disable (is_en);
+ session_manager_main_disable (vm, args->rt_engine_type);
+ session_node_enable_disable (0);
}
return error;
@@ -2263,10 +2272,15 @@ static clib_error_t *
session_main_loop_init (vlib_main_t * vm)
{
session_main_t *smm = &session_main;
+
if (smm->session_enable_asap)
{
+ session_enable_disable_args_t args = { .is_en = 1,
+ .rt_engine_type =
+ smm->rt_engine_type };
+
vlib_worker_thread_barrier_sync (vm);
- vnet_session_enable_disable (vm, 1 /* is_en */ );
+ vnet_session_enable_disable (vm, &args);
vlib_worker_thread_barrier_release (vm);
}
return 0;
@@ -2356,8 +2370,22 @@ session_config_fn (vlib_main_t * vm, unformat_input_t * input)
smm->port_allocator_min_src_port = tmp;
else if (unformat (input, "max-src-port %d", &tmp))
smm->port_allocator_max_src_port = tmp;
+ else if (unformat (input, "enable rt-backend rule-table"))
+ {
+ smm->rt_engine_type = RT_BACKEND_ENGINE_RULE_TABLE;
+ smm->session_enable_asap = 1;
+ }
+ else if (unformat (input, "enable rt-backend sdl"))
+ {
+ smm->rt_engine_type = RT_BACKEND_ENGINE_SDL;
+ smm->session_enable_asap = 1;
+ }
else if (unformat (input, "enable"))
- smm->session_enable_asap = 1;
+ {
+ /* enable session without rt-backend */
+ smm->rt_engine_type = RT_BACKEND_ENGINE_NONE;
+ smm->session_enable_asap = 1;
+ }
else if (unformat (input, "use-app-socket-api"))
(void) appns_sapi_enable_disable (1 /* is_enable */);
else if (unformat (input, "poll-main"))
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index 67a182573e4..24150fbbcd1 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -184,6 +184,19 @@ typedef void (*nat44_original_dst_lookup_fn) (
u16 i2o_dst_port, ip_protocol_t proto, u32 *original_dst,
u16 *original_dst_port);
+#define foreach_rt_engine \
+ _ (DISABLE, "disable") \
+ _ (RULE_TABLE, "enable with rt-backend rule table") \
+ _ (NONE, "enable without rt-backend") \
+ _ (SDL, "enable with rt-backend sdl")
+
+typedef enum
+{
+#define _(v, s) RT_BACKEND_ENGINE_##v,
+ foreach_rt_engine
+#undef _
+} session_rt_engine_type_t;
+
typedef struct session_main_
{
/** Worker contexts */
@@ -235,6 +248,9 @@ typedef struct session_main_
/** Enable session manager at startup */
u8 session_enable_asap;
+ /** Session engine type */
+ session_rt_engine_type_t rt_engine_type;
+
/** Poll session node in main thread */
u8 poll_main;
@@ -292,6 +308,12 @@ typedef enum session_q_process_evt_
SESSION_Q_PROCESS_STOP
} session_q_process_evt_t;
+typedef struct _session_enable_disable_args_t
+{
+ session_rt_engine_type_t rt_engine_type;
+ u8 is_en;
+} session_enable_disable_args_t;
+
#define TRANSPORT_PROTO_INVALID (session_main.last_transport_proto_type + 1)
#define TRANSPORT_N_PROTOS (session_main.last_transport_proto_type + 1)
@@ -812,7 +834,9 @@ session_wrk_update_time (session_worker_t *wrk, f64 now)
void session_wrk_enable_adaptive_mode (session_worker_t *wrk);
fifo_segment_t *session_main_get_wrk_mqs_segment (void);
void session_node_enable_disable (u8 is_en);
-clib_error_t *vnet_session_enable_disable (vlib_main_t * vm, u8 is_en);
+clib_error_t *
+vnet_session_enable_disable (vlib_main_t *vm,
+ session_enable_disable_args_t *args);
void session_wrk_handle_evts_main_rpc (void *);
void session_wrk_program_app_wrk_evts (session_worker_t *wrk,
u32 app_wrk_index);
@@ -921,6 +945,30 @@ pool_program_safe_realloc (void **p, u32 elt_size, u32 align)
} \
while (0)
+always_inline u8
+session_is_enabled_without_rt_backend (void)
+{
+ session_main_t *smm = vnet_get_session_main ();
+
+ return (smm->rt_engine_type == RT_BACKEND_ENGINE_NONE);
+}
+
+always_inline u8
+session_sdl_is_enabled (void)
+{
+ session_main_t *smm = vnet_get_session_main ();
+
+ return (smm->rt_engine_type == RT_BACKEND_ENGINE_SDL);
+}
+
+always_inline u8
+session_rule_table_is_enabled (void)
+{
+ session_main_t *smm = vnet_get_session_main ();
+
+ return (smm->rt_engine_type == RT_BACKEND_ENGINE_RULE_TABLE);
+}
+
#endif /* __included_session_h__ */
/*
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 8bb38398e3f..a729baaae29 100644
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -18,9 +18,10 @@
#include <vnet/session/application.h>
#include <vnet/session/application_interface.h>
#include <vnet/session/application_local.h>
-#include <vnet/session/session_rules_table.h>
-#include <vnet/session/session_table.h>
#include <vnet/session/session.h>
+#include <vnet/session/session_table.h>
+#include <vnet/session/session_rules_table.h>
+#include <vnet/session/session_sdl.h>
#include <vnet/ip/ip_types_api.h>
#include <vnet/format_fns.h>
@@ -30,6 +31,105 @@
#define REPLY_MSG_ID_BASE session_main.msg_id_base
#include <vlibapi/api_helper_macros.h>
+VLIB_REGISTER_LOG_CLASS (session_api_log, static) = { .class_name = "session",
+ .subclass_name = "api" };
+
+#define log_debug(fmt, ...) \
+ vlib_log_debug (session_api_log.class, "%s: " fmt, __func__, __VA_ARGS__)
+#define log_warn(fmt, ...) \
+ vlib_log_warn (session_api_log.class, fmt, __VA_ARGS__)
+#define log_err(fmt, ...) \
+ vlib_log_err (session_api_log.class, fmt, __VA_ARGS__)
+
+static int
+verify_message_len (void *mp, u64 expected_len, char *where)
+{
+ u32 supplied_len = vl_msg_api_get_msg_length (mp);
+
+ if (supplied_len < expected_len)
+ {
+ log_err ("%s: Supplied message length %d is less than expected %d",
+ where, supplied_len, expected_len);
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+static void
+vl_api_session_sdl_add_del_t_handler (vl_api_session_sdl_add_del_t *mp)
+{
+ vl_api_session_sdl_add_del_reply_t *rmp;
+ session_rule_add_del_args_t args;
+ session_rule_table_add_del_args_t *table_args = &args.table_args;
+ int rv = 0;
+ u32 count = clib_net_to_host_u32 (mp->count);
+ u64 expected_len = sizeof (*mp) + count * sizeof (mp->r[0]);
+
+ if ((session_main.is_enabled == 0) || (session_sdl_is_enabled () == 0))
+ {
+ rv = VNET_API_ERROR_FEATURE_DISABLED;
+ goto done;
+ }
+
+ if (!verify_message_len (mp, expected_len, "session_sdl_add_del"))
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto done;
+ }
+
+ clib_memset (&args, 0, sizeof (args));
+ table_args->is_add = mp->is_add;
+ args.scope = SESSION_RULE_SCOPE_GLOBAL;
+ args.appns_index = clib_net_to_host_u32 (mp->appns_index);
+ for (int i = 0; i < count; i++)
+ {
+ mp->r[i].tag[sizeof (mp->r[i].tag) - 1] = 0;
+ table_args->tag = format (0, "%s", mp->r[i].tag);
+ ip_prefix_decode (&mp->r[i].lcl, &table_args->lcl);
+ /*
+ * Need to set fp_proto for vnet_session_rule_add_del to find the
+ * correct table
+ */
+ table_args->rmt.fp_proto = table_args->lcl.fp_proto;
+ table_args->action_index = clib_net_to_host_u32 (mp->r[i].action_index);
+
+ rv = vnet_session_rule_add_del (&args);
+ vec_free (table_args->tag);
+ if (rv)
+ {
+ log_err ("session_sdl add del returned on %U @index %d: %U",
+ format_ip46_address, &table_args->lcl.fp_addr,
+ IP46_TYPE_ANY, i, format_session_error, rv);
+
+ /* roll back */
+ table_args->is_add = !mp->is_add;
+ for (int j = i - 1; j >= 0; j--)
+ {
+ mp->r[j].tag[sizeof (mp->r[j].tag) - 1] = 0;
+ table_args->tag = format (0, "%s", mp->r[j].tag);
+ ip_prefix_decode (&mp->r[j].lcl, &table_args->lcl);
+ table_args->rmt.fp_proto = table_args->lcl.fp_proto;
+ table_args->action_index =
+ clib_net_to_host_u32 (mp->r[j].action_index);
+ int rv2 = vnet_session_rule_add_del (&args);
+ vec_free (table_args->tag);
+ if (rv2)
+ log_err ("rollback session_sdl add del returned on %U "
+ "@index %d: %U",
+ format_ip46_address, &table_args->lcl.fp_addr,
+ IP46_TYPE_ANY, j, format_session_error, rv2);
+ }
+ break;
+ }
+ }
+
+done:
+ REPLY_MACRO (VL_API_SESSION_SDL_ADD_DEL_REPLY);
+}
+
static transport_proto_t
api_session_transport_proto_decode (const vl_api_transport_proto_t * api_tp)
{
@@ -520,12 +620,54 @@ vl_api_session_enable_disable_t_handler (vl_api_session_enable_disable_t * mp)
vl_api_session_enable_disable_reply_t *rmp;
vlib_main_t *vm = vlib_get_main ();
int rv = 0;
+ session_enable_disable_args_t args;
+
+ args.is_en = mp->is_enable;
+ if (mp->is_enable)
+ args.rt_engine_type = RT_BACKEND_ENGINE_RULE_TABLE;
+ else
+ args.rt_engine_type = RT_BACKEND_ENGINE_DISABLE;
- vnet_session_enable_disable (vm, mp->is_enable);
+ if (vnet_session_enable_disable (vm, &args))
+ rv = VNET_API_ERROR_INVALID_ARGUMENT;
REPLY_MACRO (VL_API_SESSION_ENABLE_DISABLE_REPLY);
}
static void
+vl_api_session_enable_disable_v2_t_handler (
+ vl_api_session_enable_disable_v2_t *mp)
+{
+ vl_api_session_enable_disable_v2_reply_t *rmp;
+ vlib_main_t *vm = vlib_get_main ();
+ int rv = 0;
+ session_enable_disable_args_t args;
+
+ STATIC_ASSERT ((session_rt_engine_type_t) RT_BACKEND_ENGINE_API_DISABLE ==
+ RT_BACKEND_ENGINE_DISABLE,
+ "API value mismatch");
+ STATIC_ASSERT ((session_rt_engine_type_t) RT_BACKEND_ENGINE_API_NONE ==
+ RT_BACKEND_ENGINE_NONE,
+ "API value mismatch");
+ STATIC_ASSERT ((session_rt_engine_type_t) RT_BACKEND_ENGINE_API_RULE_TABLE ==
+ RT_BACKEND_ENGINE_RULE_TABLE,
+ "API value mismatch");
+ STATIC_ASSERT ((session_rt_engine_type_t) RT_BACKEND_ENGINE_API_SDL ==
+ RT_BACKEND_ENGINE_SDL,
+ "API value mismatch");
+
+ args.rt_engine_type = (session_rt_engine_type_t) mp->rt_engine_type;
+ if (args.rt_engine_type == RT_BACKEND_ENGINE_DISABLE)
+ args.is_en = 0;
+ else
+ args.is_en = 1;
+
+ if (vnet_session_enable_disable (vm, &args))
+ rv = VNET_API_ERROR_INVALID_VALUE;
+
+ REPLY_MACRO (VL_API_SESSION_ENABLE_DISABLE_V2_REPLY);
+}
+
+static void
vl_api_session_sapi_enable_disable_t_handler (
vl_api_session_sapi_enable_disable_t *mp)
{
@@ -1131,14 +1273,89 @@ vl_api_session_rules_dump_t_handler (vl_api_session_rules_dump_t * mp)
return;
session_table_foreach (st, ({
- for (tp = 0; tp < TRANSPORT_N_PROTOS; tp++)
- {
- send_session_rules_table_details (&st->session_rules[tp],
- st->active_fib_proto, tp,
- st->is_local, st->appns_index, reg,
- mp->context);
- }
- }));
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
+ for (tp = 0; tp < TRANSPORT_N_PROTOS; tp++)
+ {
+ session_rules_table_t *srt =
+ srtg_handle_to_srt (st->srtg_handle, tp);
+ send_session_rules_table_details (
+ srt, st->active_fib_proto, tp, st->is_local,
+ st->appns_index, reg, mp->context);
+ }
+ }));
+}
+
+typedef struct session_sdl_table_walk_ctx_
+{
+ vl_api_registration_t *reg;
+ u32 mp_context;
+ u32 appns_index;
+} session_sdl_table_walk_ctx;
+
+static void
+send_session_sdl_details (u32 fei, ip46_address_t *lcl_ip, u16 fp_len,
+ u32 action_index, u32 fp_proto, u8 *tag, void *args)
+{
+ session_sdl_table_walk_ctx *ctx = args;
+ vl_api_registration_t *reg = ctx->reg;
+ u32 appns_index = ctx->appns_index;
+ u32 context = ctx->mp_context;
+ vl_api_session_sdl_details_t *rmp = 0;
+ fib_prefix_t lcl;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_DETAILS);
+ rmp->context = context;
+
+ clib_memset (&lcl, 0, sizeof (lcl));
+ if (fp_proto == FIB_PROTOCOL_IP4)
+ ip_set (&lcl.fp_addr, &lcl_ip->ip4, 1);
+ else
+ ip_set (&lcl.fp_addr, &lcl_ip->ip6, 0);
+ lcl.fp_len = fp_len;
+ lcl.fp_proto = fp_proto,
+
+ ip_prefix_encode (&lcl, &rmp->lcl);
+ rmp->action_index = clib_host_to_net_u32 (action_index);
+ rmp->appns_index = clib_host_to_net_u32 (appns_index);
+ if (tag)
+ {
+ clib_memcpy_fast (rmp->tag, tag, vec_len (tag));
+ rmp->tag[vec_len (tag)] = 0;
+ }
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_session_sdl_dump_t_handler (vl_api_session_rules_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ session_table_t *st;
+ session_sdl_table_walk_ctx ctx;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ ctx.reg = reg;
+ ctx.mp_context = mp->context;
+
+ session_table_foreach (
+ st, ({
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
+ {
+ ctx.appns_index = st->appns_index;
+
+ if (st->active_fib_proto == FIB_PROTOCOL_IP4)
+ session_sdl_table_walk4 (st->srtg_handle, send_session_sdl_details,
+ &ctx);
+ else
+ session_sdl_table_walk6 (st->srtg_handle, send_session_sdl_details,
+ &ctx);
+ }
+ }));
}
static void
@@ -1836,11 +2053,21 @@ appns_sapi_add_ns_socket (app_namespace_t * app_ns)
static clib_error_t *
session_api_hookup (vlib_main_t *vm)
{
+ api_main_t *am = vlibapi_get_main ();
+
/*
* Set up the (msg_name, crc, message-id) table
*/
REPLY_MSG_ID_BASE = setup_message_id_table ();
+ vl_api_set_msg_thread_safe (
+ am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_ADD_DEL, 1);
+ vl_api_set_msg_thread_safe (
+ am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_ADD_DEL_REPLY, 1);
+ vl_api_set_msg_thread_safe (am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_DUMP,
+ 1);
+ vl_api_set_msg_thread_safe (
+ am, REPLY_MSG_ID_BASE + VL_API_SESSION_SDL_DETAILS, 1);
return 0;
}
diff --git a/src/vnet/session/session_cli.c b/src/vnet/session/session_cli.c
index 569a77bccc1..76ecfeae243 100644
--- a/src/vnet/session/session_cli.c
+++ b/src/vnet/session/session_cli.c
@@ -482,6 +482,25 @@ session_cli_print_session_states (vlib_main_t * vm)
#undef _
}
+static u8 *
+format_rt_backend (u8 *s, va_list *args)
+{
+ u32 i = va_arg (*args, u32);
+ u8 *t = 0;
+
+ switch (i)
+ {
+#define _(v, s) \
+ case RT_BACKEND_ENGINE_##v: \
+ t = (u8 *) s; \
+ break;
+ foreach_rt_engine
+#undef _
+ default : return format (s, "unknown");
+ }
+ return format (s, "%s", t);
+}
+
static clib_error_t *
show_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
@@ -573,6 +592,11 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_output (vm, "%U", format_transport_protos);
goto done;
}
+ else if (unformat (input, "rt-backend"))
+ {
+ vlib_cli_output (vm, "%U", format_rt_backend, smm->rt_engine_type);
+ goto done;
+ }
else if (unformat (input, "states"))
{
session_cli_print_session_states (vm);
@@ -654,13 +678,12 @@ done:
return error;
}
-VLIB_CLI_COMMAND (vlib_cli_show_session_command) =
-{
+VLIB_CLI_COMMAND (vlib_cli_show_session_command) = {
.path = "show session",
.short_help = "show session [verbose [n]] [listeners <proto>] "
"[<session-id> [elog]] [thread <n> [index <n>] "
"[proto <proto>] [state <state>] [range <min> [<max>]] "
- "[protos] [states] ",
+ "[protos] [states] [rt-backend]",
.function = show_session_command_fn,
};
@@ -829,29 +852,47 @@ static clib_error_t *
session_enable_disable_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
{
- u8 is_en = 2;
+ session_enable_disable_args_t args;
+ session_main_t *smm = &session_main;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "enable"))
- is_en = 1;
+ {
+ args.is_en = 1;
+ if (unformat (input, "rt-backend"))
+ if (unformat (input, "sdl"))
+ args.rt_engine_type = RT_BACKEND_ENGINE_SDL;
+ else if (unformat (input, "rule-table"))
+ args.rt_engine_type = RT_BACKEND_ENGINE_RULE_TABLE;
+ else
+ return clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, input);
+ else
+ args.rt_engine_type = RT_BACKEND_ENGINE_NONE;
+ }
else if (unformat (input, "disable"))
- is_en = 0;
+ {
+ args.rt_engine_type = RT_BACKEND_ENGINE_DISABLE;
+ args.is_en = 0;
+ }
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
}
- if (is_en > 1)
- return clib_error_return (0, "expected enable | disable");
+ if (smm->is_enabled && args.is_en)
+ if (args.rt_engine_type != smm->rt_engine_type)
+ return clib_error_return (
+ 0, "session is already enable. Must disable first");
- return vnet_session_enable_disable (vm, is_en);
+ return vnet_session_enable_disable (vm, &args);
}
-VLIB_CLI_COMMAND (session_enable_disable_command, static) =
-{
+VLIB_CLI_COMMAND (session_enable_disable_command, static) = {
.path = "session",
- .short_help = "session [enable|disable]",
+ .short_help =
+ "session { enable [ rt-backend sdl | rule-table ] } | { disable }",
.function = session_enable_disable_fn,
};
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c
index 217fe9ad209..0d580ba35c6 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -28,6 +28,7 @@
#include <vnet/session/session_lookup.h>
#include <vnet/session/session.h>
#include <vnet/session/application.h>
+#include <vnet/session/session_rules_table.h>
static session_lookup_main_t sl_main;
@@ -241,7 +242,7 @@ session_table_get_for_connection (transport_connection_t * tc)
session_table_get (fib_index_to_table_index[fib_proto][tc->fib_index]);
}
-static session_table_t *
+session_table_t *
session_table_get_for_fib_index (u32 fib_proto, u32 fib_index)
{
if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index)
@@ -478,10 +479,10 @@ session_lookup_rules_table_session4 (session_table_t * st, u8 proto,
ip4_address_t * lcl, u16 lcl_port,
ip4_address_t * rmt, u16 rmt_port)
{
- session_rules_table_t *srt = &st->session_rules[proto];
u32 action_index, app_index;
- action_index = session_rules_table_lookup4 (srt, lcl, rmt, lcl_port,
- rmt_port);
+
+ action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl, rmt,
+ lcl_port, rmt_port);
app_index = session_lookup_action_to_handle (action_index);
/* Nothing sophisticated for now, action index is app index */
return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP4,
@@ -494,10 +495,10 @@ session_lookup_rules_table_session6 (session_table_t * st, u8 proto,
ip6_address_t * lcl, u16 lcl_port,
ip6_address_t * rmt, u16 rmt_port)
{
- session_rules_table_t *srt = &st->session_rules[proto];
u32 action_index, app_index;
- action_index = session_rules_table_lookup6 (srt, lcl, rmt, lcl_port,
- rmt_port);
+
+ action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl, rmt,
+ lcl_port, rmt_port);
app_index = session_lookup_action_to_handle (action_index);
return session_lookup_app_listen_session (app_index, FIB_PROTOCOL_IP6,
proto);
@@ -517,7 +518,6 @@ u64
session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
u8 use_rules)
{
- session_rules_table_t *srt;
session_table_t *st;
u32 ai;
int rv;
@@ -537,10 +537,12 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
return kv4.value;
if (use_rules)
{
+ if (st->srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return SESSION_INVALID_HANDLE;
clib_memset (&lcl4, 0, sizeof (lcl4));
- srt = &st->session_rules[sep->transport_proto];
- ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
- sep->port);
+ ai =
+ session_rules_table_lookup4 (st->srtg_handle, sep->transport_proto,
+ &lcl4, &sep->ip.ip4, 0, sep->port);
if (session_lookup_action_index_is_valid (ai))
return session_lookup_action_to_handle (ai);
}
@@ -558,10 +560,12 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
if (use_rules)
{
+ if (st->srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return SESSION_INVALID_HANDLE;
clib_memset (&lcl6, 0, sizeof (lcl6));
- srt = &st->session_rules[sep->transport_proto];
- ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
- sep->port);
+ ai =
+ session_rules_table_lookup6 (st->srtg_handle, sep->transport_proto,
+ &lcl6, &sep->ip.ip6, 0, sep->port);
if (session_lookup_action_index_is_valid (ai))
return session_lookup_action_to_handle (ai);
}
@@ -588,7 +592,6 @@ session_lookup_endpoint_listener (u32 table_index, session_endpoint_t * sep,
u64
session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
{
- session_rules_table_t *srt;
session_table_t *st;
u32 ai;
int rv;
@@ -603,15 +606,18 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
session_kv4_t kv4;
ip4_address_t lcl4;
- /*
- * Check if endpoint has special rules associated
- */
- clib_memset (&lcl4, 0, sizeof (lcl4));
- srt = &st->session_rules[sep->transport_proto];
- ai = session_rules_table_lookup4 (srt, &lcl4, &sep->ip.ip4, 0,
- sep->port);
- if (session_lookup_action_index_is_valid (ai))
- return session_lookup_action_to_handle (ai);
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
+ {
+ /*
+ * Check if endpoint has special rules associated
+ */
+ clib_memset (&lcl4, 0, sizeof (lcl4));
+ ai =
+ session_rules_table_lookup4 (st->srtg_handle, sep->transport_proto,
+ &lcl4, &sep->ip.ip4, 0, sep->port);
+ if (session_lookup_action_index_is_valid (ai))
+ return session_lookup_action_to_handle (ai);
+ }
/*
* Check if session endpoint is a listener
@@ -651,12 +657,15 @@ session_lookup_local_endpoint (u32 table_index, session_endpoint_t * sep)
session_kv6_t kv6;
ip6_address_t lcl6;
- clib_memset (&lcl6, 0, sizeof (lcl6));
- srt = &st->session_rules[sep->transport_proto];
- ai = session_rules_table_lookup6 (srt, &lcl6, &sep->ip.ip6, 0,
- sep->port);
- if (session_lookup_action_index_is_valid (ai))
- return session_lookup_action_to_handle (ai);
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
+ {
+ clib_memset (&lcl6, 0, sizeof (lcl6));
+ ai =
+ session_rules_table_lookup6 (st->srtg_handle, sep->transport_proto,
+ &lcl6, &sep->ip.ip6, 0, sep->port);
+ if (session_lookup_action_index_is_valid (ai))
+ return session_lookup_action_to_handle (ai);
+ }
make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port,
sep->transport_proto);
@@ -984,22 +993,25 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
if (rv == 0)
return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
- /*
- * Check the session rules table
- */
- action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
- rmt, lcl_port, rmt_port);
- if (session_lookup_action_index_is_valid (action_index))
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
{
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ /*
+ * Check the session rules table
+ */
+ action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl,
+ rmt, lcl_port, rmt_port);
+ if (session_lookup_action_index_is_valid (action_index))
{
- *result = SESSION_LOOKUP_RESULT_FILTERED;
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ {
+ *result = SESSION_LOOKUP_RESULT_FILTERED;
+ return 0;
+ }
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP4, proto)))
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
- if ((s = session_lookup_action_to_session (action_index,
- FIB_PROTOCOL_IP4, proto)))
- return transport_get_listener (proto, s->connection_index);
- return 0;
}
/*
@@ -1061,19 +1073,22 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
if (rv == 0)
return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
- /*
- * Check the session rules table
- */
- action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
- rmt, lcl_port, rmt_port);
- if (session_lookup_action_index_is_valid (action_index))
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
{
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if ((s = session_lookup_action_to_session (action_index,
- FIB_PROTOCOL_IP4, proto)))
- return transport_get_listener (proto, s->connection_index);
- return 0;
+ /*
+ * Check the session rules table
+ */
+ action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl,
+ rmt, lcl_port, rmt_port);
+ if (session_lookup_action_index_is_valid (action_index))
+ {
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP4, proto)))
+ return transport_get_listener (proto, s->connection_index);
+ return 0;
+ }
}
/*
@@ -1119,17 +1134,20 @@ session_lookup_safe4 (u32 fib_index, ip4_address_t * lcl, ip4_address_t * rmt,
if (rv == 0)
return session_get_from_handle_safe (kv4.value);
- /*
- * Check the session rules table
- */
- action_index = session_rules_table_lookup4 (&st->session_rules[proto], lcl,
- rmt, lcl_port, rmt_port);
- if (session_lookup_action_index_is_valid (action_index))
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
{
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP4,
- proto);
+ /*
+ * Check the session rules table
+ */
+ action_index = session_rules_table_lookup4 (st->srtg_handle, proto, lcl,
+ rmt, lcl_port, rmt_port);
+ if (session_lookup_action_index_is_valid (action_index))
+ {
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ return session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP4, proto);
+ }
}
/*
@@ -1201,20 +1219,23 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
if (rv == 0)
return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
- /* Check the session rules table */
- action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
- rmt, lcl_port, rmt_port);
- if (session_lookup_action_index_is_valid (action_index))
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
{
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ /* Check the session rules table */
+ action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl,
+ rmt, lcl_port, rmt_port);
+ if (session_lookup_action_index_is_valid (action_index))
{
- *result = SESSION_LOOKUP_RESULT_FILTERED;
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ {
+ *result = SESSION_LOOKUP_RESULT_FILTERED;
+ return 0;
+ }
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP6, proto)))
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
- if ((s = session_lookup_action_to_session (action_index,
- FIB_PROTOCOL_IP6, proto)))
- return transport_get_listener (proto, s->connection_index);
- return 0;
}
/* If nothing is found, check if any listener is available */
@@ -1270,17 +1291,20 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl,
if (rv == 0)
return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
- /* Check the session rules table */
- action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
- rmt, lcl_port, rmt_port);
- if (session_lookup_action_index_is_valid (action_index))
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
{
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- if ((s = session_lookup_action_to_session (action_index,
- FIB_PROTOCOL_IP6, proto)))
- return transport_get_listener (proto, s->connection_index);
- return 0;
+ /* Check the session rules table */
+ action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl,
+ rmt, lcl_port, rmt_port);
+ if (session_lookup_action_index_is_valid (action_index))
+ {
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ if ((s = session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP6, proto)))
+ return transport_get_listener (proto, s->connection_index);
+ return 0;
+ }
}
/* If nothing is found, check if any listener is available */
@@ -1323,15 +1347,18 @@ session_lookup_safe6 (u32 fib_index, ip6_address_t * lcl, ip6_address_t * rmt,
if (rv == 0)
return session_get_from_handle_safe (kv6.value);
- /* Check the session rules table */
- action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
- rmt, lcl_port, rmt_port);
- if (session_lookup_action_index_is_valid (action_index))
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
{
- if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
- return 0;
- return session_lookup_action_to_session (action_index, FIB_PROTOCOL_IP6,
- proto);
+ /* Check the session rules table */
+ action_index = session_rules_table_lookup6 (st->srtg_handle, proto, lcl,
+ rmt, lcl_port, rmt_port);
+ if (session_lookup_action_index_is_valid (action_index))
+ {
+ if (action_index == SESSION_RULES_TABLE_ACTION_DROP)
+ return 0;
+ return session_lookup_action_to_session (action_index,
+ FIB_PROTOCOL_IP6, proto);
+ }
}
/* If nothing is found, check if any listener is available */
@@ -1357,7 +1384,6 @@ session_error_t
vnet_session_rule_add_del (session_rule_add_del_args_t *args)
{
app_namespace_t *app_ns = app_namespace_get (args->appns_index);
- session_rules_table_t *srt;
session_table_t *st;
u32 fib_index;
u8 fib_proto;
@@ -1378,8 +1404,9 @@ vnet_session_rule_add_del (session_rule_add_del_args_t *args)
fib_proto = args->table_args.rmt.fp_proto;
fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
st = session_table_get_for_fib_index (fib_proto, fib_index);
- srt = &st->session_rules[args->transport_proto];
- if ((rv = session_rules_table_add_del (srt, &args->table_args)))
+ session_rules_table_init (st, fib_proto);
+ if ((rv = session_rules_table_add_del (
+ st->srtg_handle, args->transport_proto, &args->table_args)))
return rv;
}
if (args->scope & SESSION_RULE_SCOPE_LOCAL)
@@ -1388,8 +1415,9 @@ vnet_session_rule_add_del (session_rule_add_del_args_t *args)
args->table_args.lcl.fp_proto = args->table_args.rmt.fp_proto;
args->table_args.lcl_port = 0;
st = app_namespace_get_local_table (app_ns);
- srt = &st->session_rules[args->transport_proto];
- rv = session_rules_table_add_del (srt, &args->table_args);
+ session_rules_table_init (st, args->table_args.rmt.fp_proto);
+ rv = session_rules_table_add_del (st->srtg_handle, args->transport_proto,
+ &args->table_args);
}
return rv;
}
@@ -1523,6 +1551,9 @@ session_rule_command_fn (vlib_main_t * vm, unformat_input_t * input,
session_cli_return_if_not_enabled ();
+ if (session_rule_table_is_enabled () == 0)
+ return clib_error_return (0, "session rule table engine is not enabled");
+
clib_memset (&lcl_ip, 0, sizeof (lcl_ip));
clib_memset (&rmt_ip, 0, sizeof (rmt_ip));
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -1644,11 +1675,12 @@ session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto,
u8 transport_proto)
{
vlib_main_t *vm = vlib_get_main ();
- session_rules_table_t *srt;
session_table_t *st;
st = session_table_get_for_fib_index (fib_index, fib_proto);
- srt = &st->session_rules[transport_proto];
- session_rules_table_cli_dump (vm, srt, fib_proto);
+ if (st == 0)
+ return;
+ session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto,
+ fib_proto);
}
void
@@ -1656,11 +1688,12 @@ session_lookup_dump_local_rules_table (u32 table_index, u8 fib_proto,
u8 transport_proto)
{
vlib_main_t *vm = vlib_get_main ();
- session_rules_table_t *srt;
session_table_t *st;
st = session_table_get (table_index);
- srt = &st->session_rules[transport_proto];
- session_rules_table_cli_dump (vm, srt, fib_proto);
+ if (st == 0)
+ return;
+ session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto,
+ fib_proto);
}
static clib_error_t *
@@ -1672,7 +1705,6 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
ip46_address_t lcl_ip, rmt_ip;
u8 is_ip4 = 1, show_one = 0;
app_namespace_t *app_ns;
- session_rules_table_t *srt;
session_table_t *st;
u8 *ns_id = 0, fib_proto;
@@ -1745,11 +1777,18 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
st = app_namespace_get_local_table (app_ns);
}
+ if (session_rule_table_is_enabled () == 0)
+ {
+ vlib_cli_output (vm, "session rule table engine is not enabled");
+ goto done;
+ }
+
if (show_one)
{
- srt = &st->session_rules[transport_proto];
- session_rules_table_show_rule (vm, srt, &lcl_ip, lcl_port, &rmt_ip,
- rmt_port, is_ip4);
+ if (st)
+ session_rules_table_show_rule (vm, st->srtg_handle, transport_proto,
+ &lcl_ip, lcl_port, &rmt_ip, rmt_port,
+ is_ip4);
goto done;
}
@@ -1759,9 +1798,10 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
{
if (st)
{
- srt = &st->session_rules[transport_proto];
- session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
- session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6);
+ session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto,
+ FIB_PROTOCOL_IP4);
+ session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto,
+ FIB_PROTOCOL_IP6);
}
}
else
@@ -1772,18 +1812,14 @@ show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4,
app_ns->ip4_fib_index);
if (st)
- {
- srt = &st->session_rules[transport_proto];
- session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP4);
- }
+ session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto,
+ FIB_PROTOCOL_IP4);
st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6,
app_ns->ip6_fib_index);
if (st)
- {
- srt = &st->session_rules[transport_proto];
- session_rules_table_cli_dump (vm, srt, FIB_PROTOCOL_IP6);
- }
+ session_rules_table_cli_dump (vm, st->srtg_handle, transport_proto,
+ FIB_PROTOCOL_IP6);
}
done:
vec_free (ns_id);
diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h
index 95fcca6ff69..9f56af20a87 100644
--- a/src/vnet/session/session_lookup.h
+++ b/src/vnet/session/session_lookup.h
@@ -19,6 +19,8 @@
#include <vnet/session/session_table.h>
#include <vnet/session/session_types.h>
#include <vnet/session/application_namespace.h>
+#include <vnet/fib/fib_table.h>
+#include <vnet/fib/fib_source.h>
#define HALF_OPEN_LOOKUP_INVALID_VALUE ((u64)~0)
@@ -115,6 +117,17 @@ typedef enum _session_rule_scope
SESSION_RULE_SCOPE_LOCAL = 2,
} session_rule_scope_e;
+typedef struct _session_rules_table_add_del_args
+{
+ fib_prefix_t lcl;
+ fib_prefix_t rmt;
+ u16 lcl_port;
+ u16 rmt_port;
+ u32 action_index;
+ u8 *tag;
+ u8 is_add;
+} session_rule_table_add_del_args_t;
+
typedef struct _session_rule_add_del_args
{
/**
@@ -140,6 +153,8 @@ session_error_t vnet_session_rule_add_del (session_rule_add_del_args_t *args);
void session_lookup_set_tables_appns (app_namespace_t * app_ns);
void session_lookup_init (void);
+session_table_t *session_table_get_for_fib_index (u32 fib_proto,
+ u32 fib_index);
#endif /* SRC_VNET_SESSION_SESSION_LOOKUP_H_ */
diff --git a/src/vnet/session/session_rules_table.c b/src/vnet/session/session_rules_table.c
index d15df48d7b5..acb575b0f7c 100644
--- a/src/vnet/session/session_rules_table.c
+++ b/src/vnet/session/session_rules_table.c
@@ -17,8 +17,23 @@
#include <vnet/session/mma_template.c>
#include <vnet/session/mma_40.h>
#include <vnet/session/mma_template.c>
-#include <vnet/session/session_rules_table.h>
#include <vnet/session/transport.h>
+#include <vnet/session/session.h>
+#include <vnet/session/session_table.h>
+#include <vnet/session/session_rules_table.h>
+#include <vnet/session/session_sdl.h>
+
+VLIB_REGISTER_LOG_CLASS (session_rt_log, static) = { .class_name = "session",
+ .subclass_name = "rt" };
+
+#define log_debug(fmt, ...) \
+ vlib_log_debug (session_rt_log.class, "%s: " fmt, __func__, __VA_ARGS__)
+#define log_warn(fmt, ...) \
+ vlib_log_warn (session_rt_log.class, fmt, __VA_ARGS__)
+#define log_err(fmt, ...) vlib_log_err (session_rt_log.class, fmt, __VA_ARGS__)
+
+static session_rules_table_group_t *srt_instances;
+const session_rt_engine_vft_t *session_rt_engine_vft;
u32
session_rule_tag_key_index (u32 ri, u8 is_ip4)
@@ -119,13 +134,25 @@ fib_pref_normalize (fib_prefix_t * pref)
}
u8 *
+format_session_rule_tag (u8 *s, va_list *args)
+{
+ static u8 *null_tag = 0;
+ u8 *tag = va_arg (*args, u8 *);
+
+ if (!null_tag)
+ null_tag = format (0, "none");
+ s = format (s, "%v", (tag != 0) ? tag : null_tag);
+ return s;
+}
+
+u8 *
format_session_rule4 (u8 * s, va_list * args)
{
session_rules_table_t *srt = va_arg (*args, session_rules_table_t *);
mma_rule_16_t *sr = va_arg (*args, mma_rule_16_t *);
session_mask_or_match_4_t *mask, *match;
mma_rules_table_16_t *srt4;
- u8 *tag = 0, *null_tag = format (0, "none");
+ u8 *tag = 0;
u32 ri;
int i;
@@ -135,20 +162,18 @@ format_session_rule4 (u8 * s, va_list * args)
match = (session_mask_or_match_4_t *) & sr->match;
mask = (session_mask_or_match_4_t *) & sr->mask;
- s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri,
+ s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %U", ri,
format_ip4_address, &match->lcl_ip,
- ip4_mask_to_preflen (&mask->lcl_ip),
- clib_net_to_host_u16 (match->lcl_port), format_ip4_address,
- &match->rmt_ip, ip4_mask_to_preflen (&mask->rmt_ip),
- clib_net_to_host_u16 (match->rmt_port), sr->action_index,
- tag ? tag : null_tag);
+ ip4_mask_to_preflen (&mask->lcl_ip), match->lcl_port,
+ format_ip4_address, &match->rmt_ip,
+ ip4_mask_to_preflen (&mask->rmt_ip), match->rmt_port,
+ sr->action_index, format_session_rule_tag, tag);
if (vec_len (sr->next_indices))
{
s = format (s, "\n children: ");
for (i = 0; i < vec_len (sr->next_indices); i++)
s = format (s, "%d ", sr->next_indices[i]);
}
- vec_free (null_tag);
return s;
}
@@ -159,7 +184,7 @@ format_session_rule6 (u8 * s, va_list * args)
mma_rule_40_t *sr = va_arg (*args, mma_rule_40_t *);
session_mask_or_match_6_t *mask, *match;
mma_rules_table_40_t *srt6;
- u8 *tag = 0, *null_tag = format (0, "none");
+ u8 *tag = 0;
u32 ri;
int i;
@@ -169,20 +194,18 @@ format_session_rule6 (u8 * s, va_list * args)
match = (session_mask_or_match_6_t *) & sr->match;
mask = (session_mask_or_match_6_t *) & sr->mask;
- s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %v", ri,
+ s = format (s, "[%d] rule: %U/%d %d %U/%d %d action: %d tag: %U", ri,
format_ip6_address, &match->lcl_ip,
- ip6_mask_to_preflen (&mask->lcl_ip),
- clib_net_to_host_u16 (match->lcl_port), format_ip6_address,
- &match->rmt_ip, ip6_mask_to_preflen (&mask->rmt_ip),
- clib_net_to_host_u16 (match->rmt_port), sr->action_index,
- tag ? tag : null_tag);
+ ip6_mask_to_preflen (&mask->lcl_ip), match->lcl_port,
+ format_ip6_address, &match->rmt_ip,
+ ip6_mask_to_preflen (&mask->rmt_ip), match->rmt_port,
+ sr->action_index, format_session_rule_tag, tag);
if (vec_len (sr->next_indices))
{
s = format (s, "\n children: ");
for (i = 0; i < vec_len (sr->next_indices); i++)
s = format (s, "%d ", sr->next_indices[i]);
}
- vec_free (null_tag);
return s;
}
@@ -313,11 +336,10 @@ session_rules_table_alloc_rule_40 (mma_rules_table_40_t * srt,
return rule;
}
-u32
-session_rules_table_lookup_rule4 (session_rules_table_t * srt,
- ip4_address_t * lcl_ip,
- ip4_address_t * rmt_ip, u16 lcl_port,
- u16 rmt_port)
+static u32
+session_rules_table_lookup_rule4 (session_rules_table_t *srt,
+ ip4_address_t *lcl_ip, ip4_address_t *rmt_ip,
+ u16 lcl_port, u16 rmt_port)
{
mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16;
session_mask_or_match_4_t key = {
@@ -326,16 +348,20 @@ session_rules_table_lookup_rule4 (session_rules_table_t * srt,
.lcl_port = lcl_port,
.rmt_port = rmt_port,
};
+
+ if (srt4->rules == 0)
+ return SESSION_TABLE_INVALID_INDEX;
return mma_rules_table_lookup_rule_16 (srt4,
(mma_mask_or_match_16_t *) & key,
srt4->root_index);
}
u32
-session_rules_table_lookup4 (session_rules_table_t * srt,
- ip4_address_t * lcl_ip, ip4_address_t * rmt_ip,
- u16 lcl_port, u16 rmt_port)
+session_rules_table_lookup4_ (u32 srtg_handle, u32 proto,
+ ip4_address_t *lcl_ip, ip4_address_t *rmt_ip,
+ u16 lcl_port, u16 rmt_port)
{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, proto);
mma_rules_table_16_t *srt4 = &srt->session_rules_tables_16;
session_mask_or_match_4_t key = {
.lcl_ip.as_u32 = lcl_ip->as_u32,
@@ -343,21 +369,36 @@ session_rules_table_lookup4 (session_rules_table_t * srt,
.lcl_port = lcl_port,
.rmt_port = rmt_port,
};
+
+ if (srt4->rules == 0)
+ return SESSION_TABLE_INVALID_INDEX;
return mma_rules_table_lookup_16 (srt4, (mma_mask_or_match_16_t *) & key,
srt4->root_index);
}
-u32
-session_rules_table_lookup_rule6 (session_rules_table_t * srt,
- ip6_address_t * lcl_ip,
- ip6_address_t * rmt_ip, u16 lcl_port,
- u16 rmt_port)
+session_rules_table_t *
+srtg_handle_to_srt (u32 srtg_handle, u32 proto)
+{
+ session_rules_table_group_t *srtg =
+ pool_elt_at_index (srt_instances, srtg_handle);
+ session_rules_table_t *srt = &srtg->session_rules[proto];
+
+ return srt;
+}
+
+static u32
+session_rules_table_lookup_rule6 (session_rules_table_t *srt,
+ ip6_address_t *lcl_ip, ip6_address_t *rmt_ip,
+ u16 lcl_port, u16 rmt_port)
{
mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40;
session_mask_or_match_6_t key = {
.lcl_port = lcl_port,
.rmt_port = rmt_port,
};
+
+ if (srt6->rules == 0)
+ return SESSION_TABLE_INVALID_INDEX;
clib_memcpy_fast (&key.lcl_ip, lcl_ip, sizeof (*lcl_ip));
clib_memcpy_fast (&key.rmt_ip, rmt_ip, sizeof (*rmt_ip));
return mma_rules_table_lookup_rule_40 (srt6,
@@ -366,15 +407,19 @@ session_rules_table_lookup_rule6 (session_rules_table_t * srt,
}
u32
-session_rules_table_lookup6 (session_rules_table_t * srt,
- ip6_address_t * lcl_ip, ip6_address_t * rmt_ip,
- u16 lcl_port, u16 rmt_port)
+session_rules_table_lookup6_ (u32 srtg_handle, u32 proto,
+ ip6_address_t *lcl_ip, ip6_address_t *rmt_ip,
+ u16 lcl_port, u16 rmt_port)
{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, proto);
mma_rules_table_40_t *srt6 = &srt->session_rules_tables_40;
session_mask_or_match_6_t key = {
.lcl_port = lcl_port,
.rmt_port = rmt_port,
};
+
+ if (srt6->rules == 0)
+ return SESSION_TABLE_INVALID_INDEX;
clib_memcpy_fast (&key.lcl_ip, lcl_ip, sizeof (*lcl_ip));
clib_memcpy_fast (&key.rmt_ip, rmt_ip, sizeof (*rmt_ip));
return mma_rules_table_lookup_40 (srt6, (mma_mask_or_match_40_t *) & key,
@@ -390,9 +435,10 @@ session_rules_table_lookup6 (session_rules_table_t * srt,
* @return 0 if success, session_error_t error otherwise
*/
session_error_t
-session_rules_table_add_del (session_rules_table_t *srt,
- session_rule_table_add_del_args_t *args)
+session_rules_table_add_del_ (u32 srtg_handle, u32 proto,
+ session_rule_table_add_del_args_t *args)
{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, proto);
u8 fib_proto = args->rmt.fp_proto, *rt;
u32 ri_from_tag, ri;
int rv;
@@ -515,50 +561,90 @@ session_rules_table_add_del (session_rules_table_t *srt,
}
void
-session_rules_table_free (session_rules_table_t *srt)
+session_rules_table_free_ (session_table_t *st, u8 fib_proto)
+{
+ session_rules_table_group_t *srtg =
+ pool_elt_at_index (srt_instances, st->srtg_handle);
+ session_rules_table_t *srt;
+
+ vec_foreach (srt, srtg->session_rules)
+ {
+ mma_rules_table_free_16 (&srt->session_rules_tables_16);
+ mma_rules_table_free_40 (&srt->session_rules_tables_40);
+
+ hash_free (srt->tags_by_rules);
+ hash_free (srt->rules_by_tag);
+ }
+ srtg_instance_free (st);
+}
+
+void
+srtg_instance_free (session_table_t *st)
{
- mma_rules_table_free_16 (&srt->session_rules_tables_16);
- mma_rules_table_free_40 (&srt->session_rules_tables_40);
+ session_rules_table_group_t *srtg =
+ pool_elt_at_index (srt_instances, st->srtg_handle);
- hash_free (srt->tags_by_rules);
- hash_free (srt->rules_by_tag);
+ vec_free (srtg->session_rules);
+ pool_put (srt_instances, srtg);
+ st->srtg_handle = SESSION_SRTG_HANDLE_INVALID;
+}
+
+session_rules_table_group_t *
+srtg_instance_alloc (session_table_t *st, u32 n_proto)
+{
+ session_rules_table_group_t *srtg;
+
+ pool_get (srt_instances, srtg);
+ vec_validate (srtg->session_rules, n_proto);
+ st->srtg_handle = srtg - srt_instances;
+ return (srtg);
}
void
-session_rules_table_init (session_rules_table_t * srt)
+session_rules_table_init_ (session_table_t *st, u8 fib_proto)
{
mma_rules_table_16_t *srt4;
mma_rules_table_40_t *srt6;
mma_rule_16_t *rule4;
mma_rule_40_t *rule6;
fib_prefix_t null_prefix;
+ session_rules_table_t *srt;
+ session_rules_table_group_t *srtg;
- clib_memset (&null_prefix, 0, sizeof (null_prefix));
+ srtg = srtg_instance_alloc (st, TRANSPORT_N_PROTOS - 1);
- srt4 = &srt->session_rules_tables_16;
- rule4 = session_rules_table_alloc_rule_16 (srt4, &null_prefix, 0,
- &null_prefix, 0);
- rule4->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
- srt4->root_index = mma_rules_table_rule_index_16 (srt4, rule4);
- srt4->rule_cmp_fn = rule_cmp_16;
+ clib_memset (&null_prefix, 0, sizeof (null_prefix));
+ vec_foreach (srt, srtg->session_rules)
+ {
+ srt4 = &srt->session_rules_tables_16;
- srt6 = &srt->session_rules_tables_40;
- rule6 = session_rules_table_alloc_rule_40 (srt6, &null_prefix, 0,
- &null_prefix, 0);
- rule6->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
- srt6->root_index = mma_rules_table_rule_index_40 (srt6, rule6);
- srt6->rule_cmp_fn = rule_cmp_40;
+ ASSERT (srt4->rules == 0);
+ rule4 = session_rules_table_alloc_rule_16 (srt4, &null_prefix, 0,
+ &null_prefix, 0);
+ rule4->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
+ srt4->root_index = mma_rules_table_rule_index_16 (srt4, rule4);
+ srt4->rule_cmp_fn = rule_cmp_16;
- srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
- srt->tags_by_rules = hash_create (0, sizeof (uword));
+ srt6 = &srt->session_rules_tables_40;
+ ASSERT (srt6->rules == 0);
+ rule6 = session_rules_table_alloc_rule_40 (srt6, &null_prefix, 0,
+ &null_prefix, 0);
+ rule6->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
+ srt6->root_index = mma_rules_table_rule_index_40 (srt6, rule6);
+ srt6->rule_cmp_fn = rule_cmp_40;
+
+ srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
+ srt->tags_by_rules = hash_create (0, sizeof (uword));
+ }
}
void
-session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt,
- ip46_address_t * lcl_ip, u16 lcl_port,
- ip46_address_t * rmt_ip, u16 rmt_port,
- u8 is_ip4)
+session_rules_table_show_rule_ (vlib_main_t *vm, u32 srtg_handle, u32 proto,
+ ip46_address_t *lcl_ip, u16 lcl_port,
+ ip46_address_t *rmt_ip, u16 rmt_port,
+ u8 is_ip4)
{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, proto);
mma_rules_table_16_t *srt4;
mma_rules_table_40_t *srt6;
mma_rule_16_t *sr4;
@@ -599,9 +685,10 @@ session_rules_table_show_rule (vlib_main_t * vm, session_rules_table_t * srt,
}
void
-session_rules_table_cli_dump (vlib_main_t * vm, session_rules_table_t * srt,
- u8 fib_proto)
+session_rules_table_cli_dump_ (vlib_main_t *vm, u32 srtg_handle, u32 proto,
+ u8 fib_proto)
{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, proto);
if (fib_proto == FIB_PROTOCOL_IP4)
{
mma_rules_table_16_t *srt4;
@@ -628,6 +715,108 @@ session_rules_table_cli_dump (vlib_main_t * vm, session_rules_table_t * srt,
}
}
+static const session_rt_engine_vft_t session_rules_table_vft = {
+ .backend_engine = RT_BACKEND_ENGINE_RULE_TABLE,
+ .table_lookup4 = session_rules_table_lookup4_,
+ .table_lookup6 = session_rules_table_lookup6_,
+ .table_cli_dump = session_rules_table_cli_dump_,
+ .table_show_rule = session_rules_table_show_rule_,
+ .table_add_del = session_rules_table_add_del_,
+ .table_init = session_rules_table_init_,
+ .table_free = session_rules_table_free_,
+};
+
+static void
+session_rules_table_app_namespace_walk_cb (app_namespace_t *app_ns, void *ctx)
+{
+ u32 fib_index, table_index;
+ session_table_t *st;
+
+ log_debug ("disable app_ns %s", app_ns->ns_id);
+ st = session_table_get (app_ns->local_table_index);
+ if (st)
+ session_rules_table_free (st, FIB_PROTOCOL_MAX);
+
+ fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
+ table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP4, fib_index);
+ st = session_table_get (table_index);
+ if (st)
+ session_rules_table_free (st, FIB_PROTOCOL_IP4);
+
+ fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
+ table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP6, fib_index);
+ st = session_table_get (table_index);
+ if (st)
+ session_rules_table_free (st, FIB_PROTOCOL_IP6);
+}
+
+clib_error_t *
+session_rules_table_enable_disable (int enable)
+{
+ clib_error_t *error;
+
+ if (enable)
+ error = session_rule_table_register_engine (&session_rules_table_vft);
+ else
+ {
+ app_namespace_walk (session_rules_table_app_namespace_walk_cb, 0);
+ error = session_rule_table_deregister_engine (&session_rules_table_vft);
+ }
+
+ return error;
+}
+
+clib_error_t *
+session_rt_backend_enable_disable (session_rt_engine_type_t rt_engine_type)
+{
+ session_main_t *smm = &session_main;
+ clib_error_t *error = 0;
+
+ if (rt_engine_type < RT_BACKEND_ENGINE_DISABLE ||
+ rt_engine_type > RT_BACKEND_ENGINE_SDL)
+ return clib_error_return (0, "invalid rt-backend %d", rt_engine_type);
+
+ if (rt_engine_type == RT_BACKEND_ENGINE_SDL)
+ error = session_sdl_enable_disable (1);
+ else if (rt_engine_type == RT_BACKEND_ENGINE_RULE_TABLE)
+ error = session_rules_table_enable_disable (1);
+ else if (rt_engine_type == RT_BACKEND_ENGINE_DISABLE)
+ {
+ if (session_sdl_is_enabled ())
+ error = session_sdl_enable_disable (0);
+ else if (session_rule_table_is_enabled ())
+ error = session_rules_table_enable_disable (0);
+ }
+
+ if (!error)
+ smm->rt_engine_type = rt_engine_type;
+ return error;
+}
+
+clib_error_t *
+session_rule_table_register_engine (const session_rt_engine_vft_t *vft)
+{
+ if (session_rt_engine_vft == vft)
+ return 0;
+ if (session_rt_engine_vft)
+ return clib_error_return (0, "session rule engine is already registered");
+
+ session_rt_engine_vft = vft;
+ return 0;
+}
+
+clib_error_t *
+session_rule_table_deregister_engine (const session_rt_engine_vft_t *vft)
+{
+ if (session_rt_engine_vft == vft)
+ session_rt_engine_vft = 0;
+ else
+ return clib_error_return (
+ 0, "session rule engine is not registered to this engine");
+
+ return 0;
+}
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/vnet/session/session_rules_table.h b/src/vnet/session/session_rules_table.h
index 010d50a6398..a61438bb9fd 100644
--- a/src/vnet/session/session_rules_table.h
+++ b/src/vnet/session/session_rules_table.h
@@ -22,6 +22,10 @@
#include <vnet/session/transport.h>
#include <vnet/session/mma_16.h>
#include <vnet/session/mma_40.h>
+#include <vnet/session/session_lookup.h>
+#include <vnet/session/session_table.h>
+
+#define SESSION_SRTG_HANDLE_INVALID ~0
typedef CLIB_PACKED (struct
{
@@ -58,29 +62,36 @@ typedef CLIB_PACKED (struct
#define SESSION_RULES_TABLE_ACTION_DROP (MMA_TABLE_INVALID_INDEX - 1)
#define SESSION_RULES_TABLE_ACTION_ALLOW (MMA_TABLE_INVALID_INDEX - 2)
-typedef struct _session_rules_table_add_del_args
-{
- fib_prefix_t lcl;
- fib_prefix_t rmt;
- u16 lcl_port;
- u16 rmt_port;
- u32 action_index;
- u8 *tag;
- u8 is_add;
-} session_rule_table_add_del_args_t;
-
typedef struct _rule_tag
{
u8 *tag;
} session_rule_tag_t;
+typedef struct session_sdl_block
+{
+ u32 ip_table_id;
+ u32 ip6_table_id;
+ u32 ip_fib_index;
+ u32 ip6_fib_index;
+} session_sdl_block_t;
+
typedef struct _session_rules_table_t
{
- /**
- * Per fib proto session rules tables
- */
- mma_rules_table_16_t session_rules_tables_16;
- mma_rules_table_40_t session_rules_tables_40;
+ union
+ {
+ /**
+ * Per fib proto session rules tables
+ */
+ struct
+ {
+ mma_rules_table_16_t session_rules_tables_16;
+ mma_rules_table_40_t session_rules_tables_40;
+ };
+ /**
+ * sdl table
+ */
+ struct session_sdl_block sdl_block;
+ };
/**
* Hash table that maps tags to rules
*/
@@ -95,28 +106,163 @@ typedef struct _session_rules_table_t
uword *tags_by_rules;
} session_rules_table_t;
-u32 session_rules_table_lookup4 (session_rules_table_t * srt,
- ip4_address_t * lcl_ip,
- ip4_address_t * rmt_ip, u16 lcl_port,
- u16 rmt_port);
-u32 session_rules_table_lookup6 (session_rules_table_t * srt,
- ip6_address_t * lcl_ip,
- ip6_address_t * rmt_ip, u16 lcl_port,
- u16 rmt_port);
-void session_rules_table_cli_dump (vlib_main_t * vm,
- session_rules_table_t * srt, u8 fib_proto);
-void session_rules_table_show_rule (vlib_main_t * vm,
- session_rules_table_t * srt,
- ip46_address_t * lcl_ip, u16 lcl_port,
- ip46_address_t * rmt_ip, u16 rmt_port,
- u8 is_ip4);
+typedef struct _session_rules_table_group_t
+{
+ session_rules_table_t *session_rules;
+} session_rules_table_group_t;
+
session_error_t
-session_rules_table_add_del (session_rules_table_t *srt,
- session_rule_table_add_del_args_t *args);
+session_rules_table_add_del_ (u32 srtg_handle, u32 proto,
+ session_rule_table_add_del_args_t *args);
u8 *session_rules_table_rule_tag (session_rules_table_t * srt, u32 ri,
u8 is_ip4);
-void session_rules_table_init (session_rules_table_t * srt);
-void session_rules_table_free (session_rules_table_t *srt);
+void session_rules_table_init_ (struct _session_lookup_table *st,
+ u8 fib_proto);
+void session_rules_table_free_ (struct _session_lookup_table *st,
+ u8 fib_proto);
+
+typedef u32 (*rules_table_lookup4) (u32 srtg_handle, u32 proto,
+ ip4_address_t *lcl_ip,
+ ip4_address_t *rmt_ip, u16 lcl_port,
+ u16 rmt_port);
+typedef u32 (*rules_table_lookup6) (u32 srtg_handle, u32 proto,
+ ip6_address_t *lcl_ip,
+ ip6_address_t *rmt_ip, u16 lcl_port,
+ u16 rmt_port);
+typedef void (*rules_table_cli_dump) (vlib_main_t *vm, u32 srtg_handle,
+ u32 proto, u8 fib_proto);
+typedef void (*rules_table_show_rule) (vlib_main_t *vm, u32 srtg_handle,
+ u32 proto, ip46_address_t *lcl_ip,
+ u16 lcl_port, ip46_address_t *rmt_ip,
+ u16 rmt_port, u8 is_ip4);
+typedef session_error_t (*rules_table_add_del) (
+ u32 srtg_handle, u32 proto, session_rule_table_add_del_args_t *args);
+typedef void (*rules_table_init) (struct _session_lookup_table *st,
+ u8 fib_proto);
+typedef void (*rules_table_free) (struct _session_lookup_table *st,
+ u8 fib_proto);
+
+#define foreach_session_rt_engine_vft_method_name \
+ _ (lookup4) \
+ _ (lookup6) \
+ _ (cli_dump) \
+ _ (show_rule) \
+ _ (add_del) \
+ _ (init) \
+ _ (free)
+
+#define _(name) rules_table_##name table_##name;
+typedef struct session_rt_engine_vft
+{
+ u32 backend_engine;
+ foreach_session_rt_engine_vft_method_name
+} session_rt_engine_vft_t;
+#undef _
+
+extern u8 *format_session_rule_tag (u8 *s, va_list *args);
+extern u8 *session_rules_table_rule_tag (session_rules_table_t *srt, u32 ri,
+ u8 is_ip4);
+extern u32 session_rules_table_rule_for_tag (session_rules_table_t *srt,
+ u8 *tag);
+extern void session_rules_table_add_tag (session_rules_table_t *srt, u8 *tag,
+ u32 rule_index, u8 is_ip4);
+extern void session_rules_table_del_tag (session_rules_table_t *srt, u8 *tag,
+ u8 is_ip4);
+
+extern const session_rt_engine_vft_t *session_rt_engine_vft;
+extern clib_error_t *session_rules_table_enable_disable (int enable);
+extern clib_error_t *
+session_rt_backend_enable_disable (session_rt_engine_type_t rt_engine_type);
+
+static_always_inline void
+session_rules_table_init (struct _session_lookup_table *st, u8 fib_proto)
+{
+ if (!session_rt_engine_vft)
+ return;
+ if (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID)
+ return;
+ session_rt_engine_vft->table_init (st, fib_proto);
+}
+
+static_always_inline void
+session_rules_table_free (struct _session_lookup_table *st, u8 fib_proto)
+{
+ if (!session_rt_engine_vft)
+ return;
+ if (st->srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return;
+ session_rt_engine_vft->table_free (st, fib_proto);
+}
+
+static_always_inline void
+session_rules_table_show_rule (vlib_main_t *vm, u32 srtg_handle, u32 proto,
+ ip46_address_t *lcl_ip, u16 lcl_port,
+ ip46_address_t *rmt_ip, u16 rmt_port, u8 is_ip4)
+{
+ if (!session_rt_engine_vft)
+ return;
+ if (srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return;
+ session_rt_engine_vft->table_show_rule (vm, srtg_handle, proto, lcl_ip,
+ lcl_port, rmt_ip, rmt_port, is_ip4);
+}
+
+static_always_inline u32
+session_rules_table_lookup6 (u32 srtg_handle, u32 proto, ip6_address_t *lcl_ip,
+ ip6_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
+{
+ if (!session_rt_engine_vft)
+ return SESSION_RULES_TABLE_ACTION_ALLOW;
+ if (srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return SESSION_RULES_TABLE_ACTION_ALLOW;
+ return session_rt_engine_vft->table_lookup6 (srtg_handle, proto, lcl_ip,
+ rmt_ip, lcl_port, rmt_port);
+}
+
+static_always_inline void
+session_rules_table_cli_dump (vlib_main_t *vm, u32 srtg_handle, u32 proto,
+ u8 fib_proto)
+{
+ if (!session_rt_engine_vft)
+ return;
+ if (srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return;
+ session_rt_engine_vft->table_cli_dump (vm, srtg_handle, proto, fib_proto);
+}
+
+static_always_inline u32
+session_rules_table_lookup4 (u32 srtg_handle, u32 proto, ip4_address_t *lcl_ip,
+ ip4_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
+{
+ if (!session_rt_engine_vft)
+ return SESSION_RULES_TABLE_ACTION_ALLOW;
+ if (srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return SESSION_RULES_TABLE_ACTION_ALLOW;
+ return session_rt_engine_vft->table_lookup4 (srtg_handle, proto, lcl_ip,
+ rmt_ip, lcl_port, rmt_port);
+}
+
+static_always_inline session_error_t
+session_rules_table_add_del (u32 srtg_handle, u32 proto,
+ session_rule_table_add_del_args_t *args)
+{
+ if (!session_rt_engine_vft)
+ return SESSION_E_NOSUPPORT;
+ if (srtg_handle == SESSION_SRTG_HANDLE_INVALID)
+ return SESSION_E_NOSUPPORT;
+ return session_rt_engine_vft->table_add_del (srtg_handle, proto, args);
+}
+
+clib_error_t *
+session_rule_table_register_engine (const session_rt_engine_vft_t *vft);
+clib_error_t *
+session_rule_table_deregister_engine (const session_rt_engine_vft_t *vft);
+
+extern session_rules_table_t *srtg_handle_to_srt (u32 srtg_handle, u32 proto);
+extern session_rules_table_group_t *srtg_instance_alloc (session_table_t *st,
+ u32 n_proto);
+extern void srtg_instance_free (session_table_t *st);
+
#endif /* SRC_VNET_SESSION_SESSION_RULES_TABLE_H_ */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/session/session_sdl.c b/src/vnet/session/session_sdl.c
new file mode 100644
index 00000000000..45ab705fb62
--- /dev/null
+++ b/src/vnet/session/session_sdl.c
@@ -0,0 +1,768 @@
+/*
+ * Copyright (c) 2024 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/session/session.h>
+#include <vnet/ip/ip4_forward.h>
+#include <vnet/ip/ip6_forward.h>
+#include <vnet/session/session_rules_table.h>
+#include <vnet/session/session_sdl.h>
+
+VLIB_REGISTER_LOG_CLASS (session_sdl_log, static) = { .class_name = "session",
+ .subclass_name = "sdl" };
+
+#define log_debug(fmt, ...) \
+ vlib_log_debug (session_sdl_log.class, "%s: " fmt, __func__, __VA_ARGS__)
+#define log_warn(fmt, ...) \
+ vlib_log_warn (session_sdl_log.class, fmt, __VA_ARGS__)
+#define log_err(fmt, ...) \
+ vlib_log_err (session_sdl_log.class, fmt, __VA_ARGS__)
+
+static fib_source_t sdl_fib_src;
+static dpo_type_t sdl_dpo_type;
+
+const static char *const *const session_sdl_dpo_nodes[DPO_PROTO_NUM] = {
+ [DPO_PROTO_IP4] = (const char *const[]){ "ip4-drop", 0 },
+ [DPO_PROTO_IP6] = (const char *const[]){ "ip6-drop", 0 },
+};
+
+static fib_route_path_t *
+session_sdl_fib_create_route_paths (u32 fib_index, dpo_proto_t dpo_proto)
+{
+ fib_route_path_t *paths = 0;
+ fib_route_path_t path = {
+ .frp_proto = dpo_proto,
+ .frp_flags = FIB_ROUTE_PATH_EXCLUSIVE,
+ .frp_fib_index = fib_index,
+ .frp_sw_if_index = ~0,
+ .frp_weight = 1,
+ };
+ vec_add1 (paths, path);
+ return paths;
+}
+
+static void
+session_sdl_dpo_lock (dpo_id_t *dpo)
+{
+}
+
+static void
+session_sdl_dpo_unlock (dpo_id_t *dpo)
+{
+}
+
+static u8 *
+format_session_sdl_dpo (u8 *s, va_list *va)
+{
+ index_t index = va_arg (*va, index_t);
+
+ return format (s, "sdl: [index: %u, deny]", index);
+}
+
+static const dpo_vft_t session_sdl_dpo_vft = {
+ .dv_lock = session_sdl_dpo_lock,
+ .dv_unlock = session_sdl_dpo_unlock,
+ .dv_format = format_session_sdl_dpo,
+};
+
+static u32
+session_sdl_lookup6 (u32 srtg_handle, u32 proto, ip6_address_t *lcl_ip,
+ ip6_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
+{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
+ session_sdl_block_t *sdlb = &srt->sdl_block;
+ index_t lbi;
+ const dpo_id_t *dpo;
+
+ if (sdlb->ip6_fib_index == ~0)
+ return SESSION_TABLE_INVALID_INDEX;
+ lbi = ip6_fib_table_fwding_lookup (sdlb->ip6_fib_index, lcl_ip);
+ dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
+ if (dpo->dpoi_type != sdl_dpo_type)
+ return SESSION_TABLE_INVALID_INDEX;
+ return (dpo->dpoi_index);
+}
+
+static u32
+session_sdl_lookup4 (u32 srtg_handle, u32 proto, ip4_address_t *lcl_ip,
+ ip4_address_t *rmt_ip, u16 lcl_port, u16 rmt_port)
+{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
+ session_sdl_block_t *sdlb = &srt->sdl_block;
+ index_t lbi;
+ const dpo_id_t *dpo;
+
+ if (sdlb->ip_fib_index == ~0)
+ return SESSION_TABLE_INVALID_INDEX;
+ lbi = ip4_fib_forwarding_lookup (sdlb->ip_fib_index, lcl_ip);
+ dpo = load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
+ if (dpo->dpoi_type != sdl_dpo_type)
+ return SESSION_TABLE_INVALID_INDEX;
+ return (dpo->dpoi_index);
+}
+
+typedef struct session_sdl4_fib_show_walk_ctx_t_
+{
+ fib_node_index_t *ifsw_indicies;
+} session_sdl4_fib_show_walk_ctx_t;
+
+static fib_table_walk_rc_t
+session_sdl4_fib_show_walk_cb (fib_node_index_t fei, void *arg)
+{
+ session_sdl4_fib_show_walk_ctx_t *ctx = arg;
+
+ vec_add1 (ctx->ifsw_indicies, fei);
+
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+typedef struct session_sdl6_fib_show_ctx_t_
+{
+ fib_node_index_t *entries;
+} session_sdl6_fib_show_ctx_t;
+
+static fib_table_walk_rc_t
+session_sdl6_fib_table_show_walk (fib_node_index_t fei, void *arg)
+{
+ session_sdl6_fib_show_ctx_t *ctx = arg;
+
+ vec_add1 (ctx->entries, fei);
+
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+static void
+session_sdl_fib_table_show (u32 fei, ip46_address_t *lcl_ip, u16 fp_len,
+ u32 action_index, u32 fp_proto, u8 *tag,
+ void *args)
+{
+ vlib_main_t *vm = args;
+ u32 type = (fp_proto == FIB_PROTOCOL_IP4) ? IP46_TYPE_IP4 : IP46_TYPE_IP6;
+
+ vlib_cli_output (vm, "[%d] rule: %U/%d action: %d tag %U", fei,
+ format_ip46_address, lcl_ip, type, fp_len, action_index,
+ format_session_rule_tag, tag);
+}
+
+static void
+session_sdl_cli_dump (vlib_main_t *vm, u32 srtg_handle, u32 proto,
+ u8 fib_proto)
+{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
+ session_sdl_block_t *sdlb = &srt->sdl_block;
+
+ if (fib_proto == FIB_PROTOCOL_IP4)
+ {
+ vlib_cli_output (vm, "IP4 rules, fib index %d", sdlb->ip_fib_index);
+ session_sdl_table_walk4 (srtg_handle, session_sdl_fib_table_show, vm);
+ }
+ else if (fib_proto == FIB_PROTOCOL_IP6)
+ {
+ vlib_cli_output (vm, "IP6 rules, fib index %d", sdlb->ip6_fib_index);
+ session_sdl_table_walk6 (srtg_handle, session_sdl_fib_table_show, vm);
+ }
+}
+
+static void
+session_sdl4_fib_table_show_one (session_rules_table_t *srt, u32 fib_index,
+ vlib_main_t *vm, ip4_address_t *address,
+ u32 mask_len)
+{
+ ip4_fib_t *fib;
+ fib_node_index_t fei;
+
+ fib = ip4_fib_get (fib_index);
+ fei = ip4_fib_table_lookup (fib, address, mask_len);
+ if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src))
+ {
+ u8 *tag = session_rules_table_rule_tag (srt, fei, 1);
+ fib_entry_t *fib_entry = fib_entry_get (fei);
+ fib_prefix_t pfx = fib_entry->fe_prefix;
+ index_t lbi = ip4_fib_forwarding_lookup (fib_index, &pfx.fp_addr.ip4);
+ const dpo_id_t *dpo =
+ load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
+
+ session_sdl_fib_table_show (fei, &pfx.fp_addr, pfx.fp_len,
+ dpo->dpoi_index, FIB_PROTOCOL_IP4, tag, vm);
+ }
+}
+
+static void
+session_sdl6_fib_table_show_one (session_rules_table_t *srt, u32 fib_index,
+ vlib_main_t *vm, ip6_address_t *address,
+ u32 mask_len)
+{
+ fib_node_index_t fei;
+
+ fei = ip6_fib_table_lookup (fib_index, address, mask_len);
+ if (fei != FIB_NODE_INDEX_INVALID && fib_entry_is_sourced (fei, sdl_fib_src))
+ {
+ u8 *tag = session_rules_table_rule_tag (srt, fei, 0);
+ fib_entry_t *fib_entry = fib_entry_get (fei);
+ fib_prefix_t pfx = fib_entry->fe_prefix;
+ index_t lbi = ip6_fib_table_fwding_lookup (fib_index, &pfx.fp_addr.ip6);
+ const dpo_id_t *dpo =
+ load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
+
+ session_sdl_fib_table_show (fei, &pfx.fp_addr, pfx.fp_len,
+ dpo->dpoi_index, FIB_PROTOCOL_IP6, tag, vm);
+ }
+}
+
+static void
+session_sdl_show_rule (vlib_main_t *vm, u32 srtg_handle, u32 proto,
+ ip46_address_t *lcl_ip, u16 lcl_port,
+ ip46_address_t *rmt_ip, u16 rmt_port, u8 is_ip4)
+{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
+ session_sdl_block_t *sdlb;
+
+ sdlb = &srt->sdl_block;
+ if (is_ip4)
+ session_sdl4_fib_table_show_one (srt, sdlb->ip_fib_index, vm, &lcl_ip->ip4,
+ 32);
+ else
+ session_sdl6_fib_table_show_one (srt, sdlb->ip6_fib_index, vm,
+ &lcl_ip->ip6, 128);
+}
+
+static void
+session_sdl_table_init (session_table_t *st, u8 fib_proto)
+{
+ session_rules_table_t *srt;
+ session_sdl_block_t *sdlb;
+ u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
+ char name[80];
+ app_namespace_t *app_ns = app_namespace_get (st->appns_index);
+ session_rules_table_group_t *srtg;
+
+ /* Don't support local table */
+ if (st->is_local == 1)
+ return;
+
+ srtg = srtg_instance_alloc (st, 0);
+ srt = srtg->session_rules;
+ sdlb = &srt->sdl_block;
+
+ if (fib_proto == FIB_PROTOCOL_IP4 || all)
+ {
+ snprintf (name, sizeof (name), "sdl4 %s", app_ns->ns_id);
+ sdlb->ip_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP4);
+ sdlb->ip_fib_index = fib_table_find_or_create_and_lock_w_name (
+ FIB_PROTOCOL_IP4, sdlb->ip_table_id, sdl_fib_src, (const u8 *) name);
+ }
+
+ if (fib_proto == FIB_PROTOCOL_IP6 || all)
+ {
+ snprintf (name, sizeof (name), "sdl6 %s", app_ns->ns_id);
+ sdlb->ip6_table_id = ip_table_get_unused_id (FIB_PROTOCOL_IP6);
+ sdlb->ip6_fib_index = fib_table_find_or_create_and_lock_w_name (
+ FIB_PROTOCOL_IP6, sdlb->ip6_table_id, sdl_fib_src, (const u8 *) name);
+ }
+
+ srt->rules_by_tag = hash_create_vec (0, sizeof (u8), sizeof (uword));
+ srt->tags_by_rules = hash_create (0, sizeof (uword));
+}
+
+static void
+session_sdl_table_free (session_table_t *st, u8 fib_proto)
+{
+ session_rules_table_t *srt = srtg_handle_to_srt (st->srtg_handle, 0);
+ session_sdl_block_t *sdlb;
+ u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
+
+ ASSERT (st->is_local == 0);
+ sdlb = &srt->sdl_block;
+ if ((fib_proto == FIB_PROTOCOL_IP4 || all) && (sdlb->ip_fib_index != ~0))
+ {
+ fib_table_flush (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
+ fib_table_unlock (sdlb->ip_fib_index, FIB_PROTOCOL_IP4, sdl_fib_src);
+ }
+ if ((fib_proto == FIB_PROTOCOL_IP6 || all) && (sdlb->ip6_fib_index != ~0))
+ {
+ fib_table_flush (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
+ fib_table_unlock (sdlb->ip6_fib_index, FIB_PROTOCOL_IP6, sdl_fib_src);
+ }
+
+ hash_free (srt->tags_by_rules);
+ hash_free (srt->rules_by_tag);
+
+ srtg_instance_free (st);
+}
+
+static session_error_t
+session_sdl_add_del (u32 srtg_handle, u32 proto,
+ session_rule_table_add_del_args_t *args)
+{
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
+ session_sdl_block_t *sdlb = &srt->sdl_block;
+ u32 fib_index;
+ dpo_proto_t dpo_proto;
+ fib_route_path_t *paths = 0;
+ fib_prefix_t pfx = args->lcl;
+ session_error_t err = SESSION_E_NONE;
+ fib_node_index_t fei;
+ int is_ip4;
+
+ if (!(args->lcl_port == 0 && args->rmt_port == 0 &&
+ args->rmt.fp_addr.ip4.as_u32 == 0))
+ return SESSION_E_NOSUPPORT;
+
+ fei = session_rules_table_rule_for_tag (srt, args->tag);
+ if (args->is_add && fei != SESSION_RULES_TABLE_INVALID_INDEX)
+ return SESSION_E_INVALID;
+
+ if (args->lcl.fp_proto == FIB_PROTOCOL_IP4)
+ {
+ fib_index = sdlb->ip_fib_index;
+ dpo_proto = DPO_PROTO_IP4;
+ is_ip4 = 1;
+ }
+ else
+ {
+ fib_index = sdlb->ip6_fib_index;
+ dpo_proto = DPO_PROTO_IP6;
+ is_ip4 = 0;
+ }
+
+ paths = session_sdl_fib_create_route_paths (fib_index, dpo_proto);
+ if (args->is_add)
+ {
+ fei = fib_table_lookup_exact_match (fib_index, &pfx);
+ if (fei != FIB_NODE_INDEX_INVALID)
+ {
+ err = SESSION_E_IPINUSE;
+ goto done;
+ }
+ dpo_set (&paths->dpo, sdl_dpo_type, dpo_proto, args->action_index);
+ fei = fib_table_entry_path_add2 (fib_index, &pfx, sdl_fib_src,
+ FIB_ENTRY_FLAG_EXCLUSIVE, paths);
+ session_rules_table_add_tag (srt, args->tag, fei, is_ip4);
+ dpo_reset (&paths->dpo);
+ }
+ else
+ {
+ if (fei == SESSION_RULES_TABLE_INVALID_INDEX)
+ {
+ fei = fib_table_lookup_exact_match (fib_index, &pfx);
+
+ if (fei == FIB_NODE_INDEX_INVALID)
+ {
+ err = SESSION_E_NOROUTE;
+ goto done;
+ }
+ }
+
+ if (!fib_entry_is_sourced (fei, sdl_fib_src))
+ {
+ err = SESSION_E_NOROUTE;
+ goto done;
+ }
+
+ fib_entry_t *fib_entry = fib_entry_get (fei);
+ pfx = fib_entry->fe_prefix;
+ fib_table_entry_special_remove (fib_index, &pfx, sdl_fib_src);
+ session_rules_table_del_tag (srt, args->tag, is_ip4);
+ }
+done:
+ vec_free (paths);
+
+ return err;
+}
+
+static const session_rt_engine_vft_t session_sdl_vft = {
+ .backend_engine = RT_BACKEND_ENGINE_SDL,
+ .table_lookup4 = session_sdl_lookup4,
+ .table_lookup6 = session_sdl_lookup6,
+ .table_cli_dump = session_sdl_cli_dump,
+ .table_show_rule = session_sdl_show_rule,
+ .table_add_del = session_sdl_add_del,
+ .table_init = session_sdl_table_init,
+ .table_free = session_sdl_table_free,
+};
+
+static void
+session_sdl_fib_init (void)
+{
+ static u32 session_fib_inited = 0;
+
+ if (session_fib_inited)
+ return;
+ session_fib_inited = 1;
+ sdl_fib_src = fib_source_allocate ("session sdl", FIB_SOURCE_PRIORITY_LOW,
+ FIB_SOURCE_BH_SIMPLE);
+ sdl_dpo_type =
+ dpo_register_new_type (&session_sdl_dpo_vft, session_sdl_dpo_nodes);
+}
+
+static void
+session_sdl_app_namespace_walk_cb (app_namespace_t *app_ns, void *ctx)
+{
+ u32 fib_index, table_index;
+ session_table_t *st;
+
+ log_debug ("disable app_ns %s", app_ns->ns_id);
+
+ fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
+ table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP4, fib_index);
+ st = session_table_get (table_index);
+ if (st)
+ session_rules_table_free (st, FIB_PROTOCOL_IP4);
+
+ fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
+ table_index = session_lookup_get_index_for_fib (FIB_PROTOCOL_IP6, fib_index);
+ st = session_table_get (table_index);
+ if (st)
+ session_rules_table_free (st, FIB_PROTOCOL_IP6);
+}
+
+clib_error_t *
+session_sdl_enable_disable (int enable)
+{
+ clib_error_t *error = 0;
+
+ if (enable)
+ {
+ error = session_rule_table_register_engine (&session_sdl_vft);
+ if (error)
+ {
+ log_err ("error in enabling sdl: %U", format_clib_error, error);
+ return error;
+ }
+ session_sdl_fib_init ();
+ }
+ else
+ {
+ app_namespace_walk (session_sdl_app_namespace_walk_cb, 0);
+
+ error = session_rule_table_deregister_engine (&session_sdl_vft);
+ if (error)
+ log_err ("error in disabling sdl: %U", format_clib_error, error);
+ }
+
+ return error;
+}
+
+/*
+ * Source Deny List
+ */
+static clib_error_t *
+session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ u32 appns_index;
+ app_namespace_t *app_ns;
+ u32 lcl_plen = 0, action = 0;
+ clib_error_t *error = 0;
+ ip46_address_t lcl_ip;
+ u8 conn_set = 0;
+ u8 fib_proto = -1, is_add = 1, *ns_id = 0;
+ u8 *tag = 0, tag_only = 0;
+ int rv;
+ session_rule_add_del_args_t args;
+
+ session_cli_return_if_not_enabled ();
+
+ if (session_sdl_is_enabled () == 0)
+ return clib_error_return (0, "session sdl engine is not enabled");
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "del"))
+ is_add = 0;
+ else if (unformat (input, "add"))
+ ;
+ else if (unformat (input, "appns %_%v%_", &ns_id))
+ ;
+ else if (unformat (input, "%U/%d", unformat_ip4_address, &lcl_ip.ip4,
+ &lcl_plen))
+ {
+ fib_proto = FIB_PROTOCOL_IP4;
+ conn_set = 1;
+ }
+ else if (unformat (input, "%U/%d", unformat_ip6_address, &lcl_ip.ip6,
+ &lcl_plen))
+ {
+ fib_proto = FIB_PROTOCOL_IP6;
+ conn_set = 1;
+ }
+ else if (unformat (input, "action %d", &action))
+ ;
+ else if (unformat (input, "tag %_%v%_", &tag))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, input);
+ goto done;
+ }
+ }
+
+ if (ns_id)
+ {
+ app_ns = app_namespace_get_from_id (ns_id);
+ if (!app_ns)
+ {
+ vlib_cli_output (vm, "namespace %v does not exist", ns_id);
+ goto done;
+ }
+ }
+ else
+ {
+ app_ns = app_namespace_get_default ();
+ }
+ appns_index = app_namespace_index (app_ns);
+
+ if (is_add && !conn_set && action == 0)
+ {
+ vlib_cli_output (vm, "connection and action must be set for add");
+ goto done;
+ }
+ if (!is_add && !tag && !conn_set)
+ {
+ vlib_cli_output (vm, "connection or tag must be set for delete");
+ goto done;
+ }
+ if (vec_len (tag) > SESSION_RULE_TAG_MAX_LEN)
+ {
+ vlib_cli_output (vm, "tag too long (max u64)");
+ goto done;
+ }
+
+ /* Delete with only tag entered. Try v4 first and then v6 if failed */
+ if ((is_add == 0) && (fib_proto == (u8) ~0))
+ {
+ fib_proto = FIB_PROTOCOL_IP4;
+ tag_only = 1;
+ }
+
+ memset (&args, 0, sizeof (args));
+ args.transport_proto = TRANSPORT_PROTO_TCP;
+ args.table_args.lcl.fp_addr = lcl_ip;
+ args.table_args.lcl.fp_len = lcl_plen;
+ args.table_args.lcl.fp_proto = fib_proto;
+ args.table_args.rmt.fp_proto = fib_proto;
+ args.table_args.action_index = action;
+ args.table_args.is_add = is_add;
+ args.table_args.tag = tag;
+ args.appns_index = appns_index;
+ args.scope = SESSION_RULE_SCOPE_GLOBAL;
+
+ if ((rv = vnet_session_rule_add_del (&args)))
+ {
+ /* Try tag only delete on v6 */
+ if (rv && tag_only)
+ {
+ args.table_args.rmt.fp_proto = FIB_PROTOCOL_IP6;
+ args.table_args.lcl.fp_proto = FIB_PROTOCOL_IP6;
+ if ((rv = vnet_session_rule_add_del (&args)))
+ {
+ error = clib_error_return (0, "sdl add del returned %u", rv);
+ }
+ }
+ else
+ {
+ error = clib_error_return (0, "sdl add del returned %u", rv);
+ }
+ }
+
+done:
+ vec_free (ns_id);
+ vec_free (tag);
+ return error;
+}
+
+VLIB_CLI_COMMAND (session_sdl_command, static) = {
+ .path = "session sdl",
+ .short_help = "session sdl [add|del] [appns <ns_id>] <lcl-ip/plen> action "
+ "<action> [tag <tag>]",
+ .function = session_sdl_command_fn,
+ .is_mp_safe = 1,
+};
+
+static clib_error_t *
+show_session_sdl_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ u32 fib_index;
+ ip46_address_t lcl_ip;
+ u8 show_one = 0;
+ app_namespace_t *app_ns;
+ session_table_t *st;
+ u8 *ns_id = 0, fib_proto = FIB_PROTOCOL_IP4;
+
+ session_cli_return_if_not_enabled ();
+
+ clib_memset (&lcl_ip, 0, sizeof (lcl_ip));
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "appns %_%s%_", &ns_id))
+ ;
+ else if (unformat (input, "%U", unformat_ip4_address, &lcl_ip.ip4))
+ {
+ fib_proto = FIB_PROTOCOL_IP4;
+ show_one = 1;
+ }
+ else if (unformat (input, "%U", unformat_ip6_address, &lcl_ip.ip6))
+ {
+ fib_proto = FIB_PROTOCOL_IP6;
+ show_one = 1;
+ }
+ else
+ {
+ vec_free (ns_id);
+ return clib_error_return (0, "unknown input `%U'",
+ format_unformat_error, input);
+ }
+ }
+
+ if (ns_id)
+ {
+ app_ns = app_namespace_get_from_id (ns_id);
+ if (!app_ns)
+ {
+ vlib_cli_output (vm, "appns %v doesn't exist", ns_id);
+ goto done;
+ }
+ }
+ else
+ {
+ app_ns = app_namespace_get_default ();
+ }
+
+ if (session_sdl_is_enabled () == 0)
+ {
+ vlib_cli_output (vm, "session sdl engine is not enabled");
+ goto done;
+ }
+
+ if (show_one)
+ {
+ fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
+ st = session_table_get_for_fib_index (fib_proto, fib_index);
+ if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
+ session_rules_table_show_rule (vm, st->srtg_handle, 0, &lcl_ip, 0, 0,
+ 0, (fib_proto == FIB_PROTOCOL_IP4));
+ goto done;
+ }
+
+ /* 2 separate session tables for global entries, 1 for ip4 and 1 for ip6 */
+ fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP4);
+ st = session_table_get_for_fib_index (FIB_PROTOCOL_IP4, fib_index);
+ if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
+ session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP4);
+
+ fib_index = app_namespace_get_fib_index (app_ns, FIB_PROTOCOL_IP6);
+ st = session_table_get_for_fib_index (FIB_PROTOCOL_IP6, fib_index);
+ if (st && (st->srtg_handle != SESSION_SRTG_HANDLE_INVALID))
+ session_rules_table_cli_dump (vm, st->srtg_handle, 0, FIB_PROTOCOL_IP6);
+done:
+ vec_free (ns_id);
+ return 0;
+}
+
+void
+session_sdl_table_walk4 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
+ void *args)
+{
+ ip4_fib_t *fib;
+ session_sdl4_fib_show_walk_ctx_t ctx = {
+ .ifsw_indicies = NULL,
+ };
+ fib_node_index_t *fei;
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
+ session_sdl_block_t *sdlb = &srt->sdl_block;
+ u32 fib_index = sdlb->ip_fib_index;
+
+ if (fib_index == ~0)
+ return;
+ fib = ip4_fib_get (fib_index);
+ ip4_fib_table_walk (fib, session_sdl4_fib_show_walk_cb, &ctx);
+ vec_sort_with_function (ctx.ifsw_indicies, fib_entry_cmp_for_sort);
+
+ vec_foreach (fei, ctx.ifsw_indicies)
+ {
+ if (*fei != FIB_NODE_INDEX_INVALID &&
+ fib_entry_is_sourced (*fei, sdl_fib_src))
+ {
+ u8 *tag = session_rules_table_rule_tag (srt, *fei, 1);
+ fib_entry_t *fib_entry = fib_entry_get (*fei);
+ fib_prefix_t pfx = fib_entry->fe_prefix;
+ index_t lbi =
+ ip4_fib_forwarding_lookup (fib_index, &pfx.fp_addr.ip4);
+ const dpo_id_t *dpo =
+ load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
+
+ fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
+ FIB_PROTOCOL_IP4, tag, args);
+ }
+ }
+
+ vec_free (ctx.ifsw_indicies);
+}
+
+void
+session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
+ void *args)
+{
+ ip6_fib_t *fib;
+ fib_node_index_t *fei;
+ session_sdl6_fib_show_ctx_t ctx = {
+ .entries = NULL,
+ };
+ session_rules_table_t *srt = srtg_handle_to_srt (srtg_handle, 0);
+ session_sdl_block_t *sdlb = &srt->sdl_block;
+ u32 fib_index = sdlb->ip6_fib_index;
+
+ if (fib_index == ~0)
+ return;
+ fib = ip6_fib_get (fib_index);
+ ip6_fib_table_walk (fib->index, session_sdl6_fib_table_show_walk, &ctx);
+ vec_sort_with_function (ctx.entries, fib_entry_cmp_for_sort);
+
+ vec_foreach (fei, ctx.entries)
+ {
+ if (*fei != FIB_NODE_INDEX_INVALID &&
+ fib_entry_is_sourced (*fei, sdl_fib_src))
+ {
+ u8 *tag = session_rules_table_rule_tag (srt, *fei, 0);
+ fib_entry_t *fib_entry = fib_entry_get (*fei);
+ fib_prefix_t pfx = fib_entry->fe_prefix;
+ index_t lbi =
+ ip6_fib_table_fwding_lookup (fib_index, &pfx.fp_addr.ip6);
+ const dpo_id_t *dpo =
+ load_balance_get_fwd_bucket (load_balance_get (lbi), 0);
+
+ fn (*fei, &pfx.fp_addr, pfx.fp_len, dpo->dpoi_index,
+ FIB_PROTOCOL_IP6, tag, args);
+ }
+ }
+
+ vec_free (ctx.entries);
+}
+
+VLIB_CLI_COMMAND (show_session_sdl_command, static) = {
+ .path = "show session sdl",
+ .short_help = "show session sdl [appns <id> <lcl-ip>]",
+ .function = show_session_sdl_command_fn,
+ .is_mp_safe = 1,
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/session/session_sdl.h b/src/vnet/session/session_sdl.h
new file mode 100644
index 00000000000..8d8b5b2d29e
--- /dev/null
+++ b/src/vnet/session/session_sdl.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2024 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_VNET_SESSION_SESSION_SDL_H_
+#define SRC_VNET_SESSION_SESSION_SDL_H_
+
+clib_error_t *session_sdl_enable_disable (int enable);
+
+typedef void (*session_sdl_table_walk_fn_t) (u32 fei, ip46_address_t *lcl_ip,
+ u16 fp_len, u32 action_index,
+ u32 fb_proto, u8 *tag, void *ctx);
+void session_sdl_table_walk4 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
+ void *args);
+void session_sdl_table_walk6 (u32 srtg_handle, session_sdl_table_walk_fn_t fn,
+ void *args);
+
+#endif /* SRC_VNET_SESSION_SESSION_SDL_H_ */
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/session/session_table.c b/src/vnet/session/session_table.c
index dbbe771979c..5dafe0e633c 100644
--- a/src/vnet/session/session_table.c
+++ b/src/vnet/session/session_table.c
@@ -15,6 +15,7 @@
#include <vnet/session/session_table.h>
#include <vnet/session/session.h>
+#include <vnet/session/session_rules_table.h>
/**
* Pool of session tables
@@ -64,12 +65,8 @@ void
session_table_free (session_table_t *slt, u8 fib_proto)
{
u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
- int i;
- for (i = 0; i < TRANSPORT_N_PROTOS; i++)
- session_rules_table_free (&slt->session_rules[i]);
-
- vec_free (slt->session_rules);
+ session_rules_table_free (slt, fib_proto);
if (fib_proto == FIB_PROTOCOL_IP4 || all)
{
@@ -92,10 +89,9 @@ session_table_free (session_table_t *slt, u8 fib_proto)
* otherwise it uses defaults above.
*/
void
-session_table_init (session_table_t * slt, u8 fib_proto)
+session_table_init (session_table_t *slt, u8 fib_proto)
{
u8 all = fib_proto > FIB_PROTOCOL_IP6 ? 1 : 0;
- int i;
#define _(af,table,parm,value) \
u32 configured_##af##_##table##_table_##parm = value;
@@ -109,6 +105,7 @@ session_table_init (session_table_t * slt, u8 fib_proto)
foreach_hash_table_parameter;
#undef _
+ slt->srtg_handle = SESSION_SRTG_HANDLE_INVALID;
if (fib_proto == FIB_PROTOCOL_IP4 || all)
{
clib_bihash_init2_args_16_8_t _a, *a = &_a;
@@ -153,10 +150,6 @@ session_table_init (session_table_t * slt, u8 fib_proto)
a->instantiate_immediately = 1;
clib_bihash_init2_48_8 (a);
}
-
- vec_validate (slt->session_rules, TRANSPORT_N_PROTOS - 1);
- for (i = 0; i < TRANSPORT_N_PROTOS; i++)
- session_rules_table_init (&slt->session_rules[i]);
}
typedef struct _ip4_session_table_walk_ctx_t
diff --git a/src/vnet/session/session_table.h b/src/vnet/session/session_table.h
index bcbb6ec3037..aae4a1c2af5 100644
--- a/src/vnet/session/session_table.h
+++ b/src/vnet/session/session_table.h
@@ -18,7 +18,6 @@
#include <vppinfra/bihash_16_8.h>
#include <vppinfra/bihash_48_8.h>
-#include <vnet/session/session_rules_table.h>
typedef struct _session_lookup_table
{
@@ -37,7 +36,7 @@ typedef struct _session_lookup_table
/**
* Per fib proto and transport proto session rules tables
*/
- session_rules_table_t *session_rules;
+ u32 srtg_handle;
/** Flag that indicates if table has local scope */
u8 is_local;
diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c
index 770e7263024..1c865b877b5 100644
--- a/src/vnet/session/session_test.c
+++ b/src/vnet/session/session_test.c
@@ -271,6 +271,12 @@ api_session_enable_disable (vat_main_t *vat)
}
static int
+api_session_enable_disable_v2 (vat_main_t *vat)
+{
+ return -1;
+}
+
+static int
api_app_worker_add_del (vat_main_t *vat)
{
return -1;
@@ -354,6 +360,23 @@ api_session_sapi_enable_disable (vat_main_t *vat)
return -1;
}
+static int
+api_session_sdl_add_del (vat_main_t *vam)
+{
+ return -1;
+}
+
+static void
+vl_api_session_sdl_details_t_handler (vl_api_session_rules_details_t *mp)
+{
+}
+
+static int
+api_session_sdl_dump (vat_main_t *vam)
+{
+ return -1;
+}
+
#include <vnet/session/session.api_test.c>
/*
diff --git a/test/asf/test_session_sdl.py b/test/asf/test_session_sdl.py
new file mode 100644
index 00000000000..15d696350bc
--- /dev/null
+++ b/test/asf/test_session_sdl.py
@@ -0,0 +1,297 @@
+#!/usr/bin/env python3
+
+import unittest
+
+from framework import VppTestCase
+from asfframework import VppTestRunner, tag_fixme_vpp_workers
+from ipaddress import IPv4Network, IPv6Network
+
+from vpp_ip_route import (
+ VppIpRoute,
+ VppRoutePath,
+ VppIpTable,
+)
+
+from vpp_papi import VppEnum
+
+
+from vpp_session_sdl import VppSessionSdl
+from vpp_session_sdl import SessionSdl
+
+
+@tag_fixme_vpp_workers
+class TestSessionSDL(VppTestCase):
+ """Session SDL Test Case"""
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestSessionSDL, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestSessionSDL, cls).tearDownClass()
+
+ def setUp(self):
+ super(TestSessionSDL, self).setUp()
+ self.create_loopback_interfaces(2)
+
+ table_id = 0
+
+ for i in self.lo_interfaces:
+ i.admin_up()
+
+ if table_id != 0:
+ tbl = VppIpTable(self, table_id)
+ tbl.add_vpp_config()
+ tbl = VppIpTable(self, table_id, is_ip6=1)
+ tbl.add_vpp_config()
+
+ i.set_table_ip4(table_id)
+ i.set_table_ip6(table_id)
+ i.config_ip4()
+ i.config_ip6()
+ table_id += 1
+
+ def tearDown(self):
+ for i in self.lo_interfaces:
+ i.unconfig_ip4()
+ i.set_table_ip4(0)
+ i.unconfig_ip6()
+ i.set_table_ip6(0)
+ i.admin_down()
+ self.loop0.remove_vpp_config()
+ self.loop1.remove_vpp_config()
+ super(TestSessionSDL, self).tearDown()
+
+ def create_rule(self, lcl, action_index, tag):
+ return SessionSdl(lcl=lcl, action_index=action_index, tag=tag)
+
+ def apply_rules(self, rules, is_add, appns_index):
+ r = VppSessionSdl(self, rules, is_add=is_add, appns_index=appns_index)
+ r.add_vpp_config()
+
+ def test_session_sdl_ip4(self):
+ """Session SDL IP4 test"""
+
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Configure namespaces
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
+ # Add inter-table routes
+ uri = "tcp://" + self.loop0.local_ip4 + "/1234"
+ server_cmd = "test echo server appns 0 fifo-size 4k " + "uri " + uri
+ client_cmd = (
+ "test echo client bytes 100000 appns 1 "
+ + "fifo-size 4k "
+ + "syn-timeout 2 uri "
+ + uri
+ )
+ ip_t01 = VppIpRoute(
+ self,
+ self.loop1.local_ip4,
+ 32,
+ [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=1)],
+ )
+ ip_t10 = VppIpRoute(
+ self,
+ self.loop0.local_ip4,
+ 32,
+ [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=0)],
+ table_id=1,
+ )
+ ip_t01.add_vpp_config()
+ ip_t10.add_vpp_config()
+
+ # Start builtin server for ip4
+ self.logger.info(self.vapi.cli(server_cmd))
+
+ # Add session filter to block loop0
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip4 + "/32", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=1, appns_index=0)
+
+ filter = self.vapi.session_sdl_dump()
+ self.assertEqual(filter[0].lcl, IPv4Network(self.loop0.local_ip4 + "/32"))
+
+ # irrelevant rules - add 64k entries in one API call
+ rules = []
+ for i in range(255):
+ for j in range(255):
+ prefix = "10.1.{0}.{1}/32".format(i, j)
+ rules.append(self.create_rule(lcl=prefix, action_index=0, tag=""))
+ self.apply_rules(rules, is_add=1, appns_index=0)
+
+ error = self.vapi.cli_return_response(server_cmd)
+ # Expecting an error because loop0 is blocked
+ self.assertEqual(-1, error.retval)
+
+ # Remove the session filter
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip4 + "/32", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=0, appns_index=0)
+
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ # Add a session filter not matching loop0
+ rules = []
+ rules.append(self.create_rule(lcl="172.100.1.0/24", action_index=0, tag=""))
+ self.apply_rules(rules, is_add=1, appns_index=0)
+
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ self.logger.info(self.vapi.cli(server_cmd + " stop"))
+
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+ # Delete inter-table routes
+ ip_t01.remove_vpp_config()
+ ip_t10.remove_vpp_config()
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ def test_session_sdl_ip6(self):
+ """Session SDL IP6 test"""
+
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Configure namespaces
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+
+ # IP6 Test
+ # Add inter-table routes
+ uri = "tcp://" + self.loop0.local_ip6 + "/1235"
+ client_cmd = (
+ "test echo client bytes 100000 appns 1 "
+ + "fifo-size 4k "
+ + "syn-timeout 2 uri "
+ + uri
+ )
+ server_cmd = "test echo server appns 0 fifo-size 4k " + "uri " + uri
+
+ ip_t01 = VppIpRoute(
+ self,
+ self.loop1.local_ip6,
+ 128,
+ [VppRoutePath("0::0", 0xFFFFFFFF, nh_table_id=1)],
+ )
+ ip_t10 = VppIpRoute(
+ self,
+ self.loop0.local_ip6,
+ 128,
+ [VppRoutePath("0::0", 0xFFFFFFFF, nh_table_id=0)],
+ table_id=1,
+ )
+ ip_t01.add_vpp_config()
+ ip_t10.add_vpp_config()
+
+ # Start builtin server for ip6
+ self.logger.info(self.vapi.cli(server_cmd))
+
+ # case 1: No filter
+
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ # case 2: filter to block
+ # Add session filter to block loop0
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip6 + "/128", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=1, appns_index=0)
+ filter = self.vapi.session_sdl_dump()
+ self.assertEqual(filter[0].lcl, IPv6Network(self.loop0.local_ip6 + "/128"))
+
+ error = self.vapi.cli_return_response(client_cmd)
+ # Expecting an error because loop0 is blocked
+ self.assertEqual(-1, error.retval)
+
+ # case 3: remove to block
+ # Add session filter to block loop0
+ rules = []
+ rules.append(
+ self.create_rule(lcl=self.loop0.local_ip6 + "/128", action_index=0, tag="")
+ )
+ self.apply_rules(rules, is_add=0, appns_index=0)
+ # Not expecting an error
+ self.logger.info(self.vapi.cli(client_cmd))
+
+ # stop the server
+ self.logger.info(self.vapi.cli(server_cmd + " stop"))
+
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="0", sw_if_index=self.loop0.sw_if_index
+ )
+ self.vapi.app_namespace_add_del_v4(
+ is_add=0, namespace_id="1", sw_if_index=self.loop1.sw_if_index
+ )
+ # Delete inter-table routes
+ ip_t01.remove_vpp_config()
+ ip_t10.remove_vpp_config()
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ def test_session_enable_disable(self):
+ """Session SDL enable/disable test"""
+
+ for i in range(10):
+ # Enable sdl
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Disable
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ # Enable rule-table
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_RULE_TABLE
+ )
+
+ # Disable
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+ # Enable sdl
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_SDL
+ )
+
+ # Disable
+ self.vapi.session_enable_disable_v2(
+ rt_engine_type=VppEnum.vl_api_rt_backend_engine_t.RT_BACKEND_ENGINE_API_DISABLE
+ )
+
+
+if __name__ == "__main__":
+ unittest.main(testRunner=VppTestRunner)
diff --git a/test/asf/vpp_session_sdl.py b/test/asf/vpp_session_sdl.py
new file mode 100644
index 00000000000..b10c11d1e15
--- /dev/null
+++ b/test/asf/vpp_session_sdl.py
@@ -0,0 +1,75 @@
+from ipaddress import IPv4Network
+
+from vpp_object import VppObject
+from vpp_papi import VppEnum
+from vpp_ip import INVALID_INDEX
+from vpp_papi_provider import UnexpectedApiReturnValueError
+
+
+class SessionSdl:
+ """Session SDL"""
+
+ def __init__(
+ self,
+ lcl,
+ action_index,
+ tag,
+ ):
+
+ self.action_index = action_index
+ self.lcl = lcl
+ self.tag = tag
+
+ def encode(self):
+ return {
+ "lcl": self.lcl,
+ "action_index": self.action_index,
+ "tag": self.tag,
+ }
+
+
+class VppSessionSdl(VppObject):
+ """VPP Session SDL"""
+
+ def __init__(self, test, rules, is_add, appns_index):
+ self._test = test
+ self._rules = rules
+ self.is_add = is_add
+ self.appns_index = appns_index
+
+ @property
+ def rules(self):
+ return self._rules
+
+ @property
+ def count(self):
+ return len(self._rules)
+
+ def encode_rules(self):
+ rules = []
+ for rule in self._rules:
+ rules.append(rule.encode())
+ return rules
+
+ def add_vpp_config(self, expect_error=False):
+ try:
+ reply = self._test.vapi.session_sdl_add_del(
+ is_add=self.is_add,
+ appns_index=self.appns_index,
+ count=self.count,
+ r=self.encode_rules(),
+ )
+ self._test.registry.register(self, self._test.logger)
+ if expect_error:
+ self._test.fail("Unexpected api reply")
+ return self
+ except UnexpectedApiReturnValueError:
+ if not expect_error:
+ self._test.fail("Unexpected api reply")
+ return None
+
+ def query_vpp_config(self):
+ pass
+
+ def remove_vpp_config(self, expect_error=False):
+ pass