aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/session
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/session')
-rw-r--r--src/vnet/session/application.c146
-rw-r--r--src/vnet/session/application.h17
-rw-r--r--src/vnet/session/application_interface.c26
-rw-r--r--src/vnet/session/application_interface.h3
-rw-r--r--src/vnet/session/mma_template.c6
-rw-r--r--src/vnet/session/session.c2
-rw-r--r--src/vnet/session/session_lookup.c40
-rw-r--r--src/vnet/session/session_lookup.h5
-rw-r--r--src/vnet/session/session_test.c131
9 files changed, 344 insertions, 32 deletions
diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c
index df68ce01597..6d8ae653074 100644
--- a/src/vnet/session/application.c
+++ b/src/vnet/session/application.c
@@ -147,8 +147,8 @@ void
application_del (application_t * app)
{
segment_manager_t *sm;
- u64 handle;
- u32 index, *handles = 0;
+ u64 handle, *handles = 0;
+ u32 index;
int i;
vnet_unbind_args_t _a, *a = &_a;
@@ -159,6 +159,9 @@ application_del (application_t * app)
if (CLIB_DEBUG > 1)
clib_warning ("[%d] Delete app (%d)", getpid (), app->index);
+ if (application_is_proxy (app))
+ application_remove_proxy (app);
+
/*
* Listener cleanup
*/
@@ -251,7 +254,7 @@ application_init (application_t * app, u32 api_client_index, u64 * options,
props->add_segment = props->add_segment_size != 0;
props->preallocated_fifo_pairs = options[APP_OPTIONS_PREALLOC_FIFO_PAIRS];
props->use_private_segment = options[APP_OPTIONS_FLAGS]
- & APP_OPTIONS_FLAGS_BUILTIN_APP;
+ & APP_OPTIONS_FLAGS_IS_BUILTIN;
props->private_segment_count = options[APP_OPTIONS_PRIVATE_SEGMENT_COUNT];
props->private_segment_size = options[APP_OPTIONS_PRIVATE_SEGMENT_SIZE];
@@ -268,6 +271,8 @@ application_init (application_t * app, u32 api_client_index, u64 * options,
app->flags = options[APP_OPTIONS_FLAGS];
app->cb_fns = *cb_fns;
app->ns_index = options[APP_OPTIONS_NAMESPACE];
+ app->listeners_table = hash_create (0, sizeof (u64));
+ app->proxied_transports = options[APP_OPTIONS_PROXY_TRANSPORT];
/* If no scope enabled, default to global */
if (!application_has_global_scope (app)
@@ -452,7 +457,19 @@ application_get_listen_segment_manager (application_t * app,
int
application_is_proxy (application_t * app)
{
- return !(app->flags & APP_OPTIONS_FLAGS_IS_PROXY);
+ return (app->flags & APP_OPTIONS_FLAGS_IS_PROXY);
+}
+
+int
+application_is_builtin (application_t * app)
+{
+ return (app->flags & APP_OPTIONS_FLAGS_IS_BUILTIN);
+}
+
+int
+application_is_builtin_proxy (application_t * app)
+{
+ return (application_is_proxy (app) && application_is_builtin (app));
}
int
@@ -489,20 +506,137 @@ application_n_listeners (application_t * app)
}
stream_session_t *
-application_first_listener (application_t * app)
+application_first_listener (application_t * app, u8 fib_proto,
+ u8 transport_proto)
{
+ stream_session_t *listener;
u64 handle;
u32 sm_index;
+ u8 sst;
+
+ sst = session_type_from_proto_and_ip (transport_proto,
+ fib_proto == FIB_PROTOCOL_IP4);
/* *INDENT-OFF* */
hash_foreach (handle, sm_index, app->listeners_table, ({
- return listen_session_get_from_handle (handle);
+ listener = listen_session_get_from_handle (handle);
+ if (listener->session_type == sst)
+ return listener;
}));
/* *INDENT-ON* */
return 0;
}
+static clib_error_t *
+application_start_stop_proxy_fib_proto (application_t * app, u8 fib_proto,
+ u8 transport_proto, u8 is_start)
+{
+ session_rule_add_del_args_t args;
+ fib_prefix_t lcl_pref, rmt_pref;
+ app_namespace_t *app_ns = app_namespace_get (app->ns_index);
+ u8 is_ip4 = (fib_proto == FIB_PROTOCOL_IP4);
+ session_endpoint_t sep = SESSION_ENDPOINT_NULL;
+ transport_connection_t *tc;
+ stream_session_t *s;
+ u64 handle;
+
+ if (is_start)
+ {
+ sep.is_ip4 = is_ip4;
+ sep.fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
+ sep.sw_if_index = app_ns->sw_if_index;
+ sep.transport_proto = transport_proto;
+ application_start_listen (app, &sep, &handle);
+ s = listen_session_get_from_handle (handle);
+ }
+ else
+ {
+ s = application_first_listener (app, fib_proto, transport_proto);
+ }
+ tc = listen_session_get_transport (s);
+
+ if (!ip_is_zero (&tc->lcl_ip, 1))
+ {
+ ip_copy (&lcl_pref.fp_addr, &tc->lcl_ip, is_ip4);
+ lcl_pref.fp_len = is_ip4 ? 32 : 128;
+ lcl_pref.fp_proto = fib_proto;
+ memset (&rmt_pref.fp_addr, 0, sizeof (rmt_pref.fp_addr));
+ rmt_pref.fp_len = 0;
+ rmt_pref.fp_proto = fib_proto;
+
+ args.table_args.lcl = lcl_pref;
+ args.table_args.rmt = rmt_pref;
+ args.table_args.lcl_port = 0;
+ args.table_args.rmt_port = 0;
+ args.table_args.action_index = app->index;
+ args.table_args.is_add = is_start;
+ args.table_args.transport_proto = transport_proto;
+ args.appns_index = app->ns_index;
+ args.scope = SESSION_RULE_SCOPE_GLOBAL;
+ return vnet_session_rule_add_del (&args);
+ }
+ return 0;
+}
+
+void
+application_start_stop_proxy (application_t * app, u8 transport_proto,
+ u8 is_start)
+{
+ session_rule_add_del_args_t args;
+
+ if (application_has_local_scope (app))
+ {
+ memset (&args, 0, sizeof (args));
+ args.table_args.lcl.fp_proto = FIB_PROTOCOL_IP4;
+ args.table_args.rmt.fp_proto = FIB_PROTOCOL_IP4;
+ args.table_args.lcl_port = 0;
+ args.table_args.rmt_port = 0;
+ args.table_args.action_index = app->index;
+ args.table_args.is_add = is_start;
+ args.table_args.transport_proto = transport_proto;
+ args.appns_index = app->ns_index;
+ args.scope = SESSION_RULE_SCOPE_LOCAL;
+ vnet_session_rule_add_del (&args);
+
+ args.table_args.lcl.fp_proto = FIB_PROTOCOL_IP6;
+ args.table_args.rmt.fp_proto = FIB_PROTOCOL_IP6;
+ vnet_session_rule_add_del (&args);
+ }
+
+ if (application_has_global_scope (app))
+ {
+ application_start_stop_proxy_fib_proto (app, FIB_PROTOCOL_IP4,
+ transport_proto, is_start);
+ application_start_stop_proxy_fib_proto (app, FIB_PROTOCOL_IP6,
+ transport_proto, is_start);
+ }
+}
+
+void
+application_setup_proxy (application_t * app)
+{
+ u16 transports = app->proxied_transports;
+ ASSERT (application_is_proxy (app));
+ if (application_is_builtin (app))
+ return;
+ if (transports & (1 << TRANSPORT_PROTO_TCP))
+ application_start_stop_proxy (app, TRANSPORT_PROTO_TCP, 1);
+ if (transports & (1 << TRANSPORT_PROTO_UDP))
+ application_start_stop_proxy (app, TRANSPORT_PROTO_UDP, 1);
+}
+
+void
+application_remove_proxy (application_t * app)
+{
+ u16 transports = app->proxied_transports;
+ ASSERT (application_is_proxy (app));
+ if (transports & (1 << TRANSPORT_PROTO_TCP))
+ application_start_stop_proxy (app, TRANSPORT_PROTO_TCP, 0);
+ if (transports & (1 << TRANSPORT_PROTO_UDP))
+ application_start_stop_proxy (app, TRANSPORT_PROTO_UDP, 0);
+}
+
u8 *
format_application_listener (u8 * s, va_list * args)
{
diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h
index b05e1e17b4f..b9852131fae 100644
--- a/src/vnet/session/application.h
+++ b/src/vnet/session/application.h
@@ -88,14 +88,18 @@ typedef struct _application
/** Lookup tables for listeners. Value is segment manager index */
uword *listeners_table;
- /** First segment manager has in the the first segment the application's
+ /**
+ * First segment manager has in the the first segment the application's
* event fifo. Depending on what the app does, it may be either used for
- * a listener or for connects. */
+ * a listener or for connects.
+ */
u32 first_segment_manager;
u8 first_segment_manager_in_use;
/** Segment manager properties. Shared by all segment managers */
segment_manager_properties_t sm_properties;
+
+ u16 proxied_transports;
} application_t;
#define APP_INVALID_INDEX ((u32)~0)
@@ -125,6 +129,8 @@ segment_manager_t *application_get_listen_segment_manager (application_t *
segment_manager_t *application_get_connect_segment_manager (application_t *
app);
int application_is_proxy (application_t * app);
+int application_is_builtin (application_t * app);
+int application_is_builtin_proxy (application_t * app);
int application_add_segment_notify (u32 app_index, u32 fifo_segment_index);
u32 application_session_table (application_t * app, u8 fib_proto);
u32 application_local_session_table (application_t * app);
@@ -133,7 +139,12 @@ u8 *application_name_from_index (u32 app_index);
u8 application_has_local_scope (application_t * app);
u8 application_has_global_scope (application_t * app);
u32 application_n_listeners (application_t * app);
-stream_session_t *application_first_listener (application_t * app);
+stream_session_t *application_first_listener (application_t * app,
+ u8 fib_proto,
+ u8 transport_proto);
+void application_setup_proxy (application_t * app);
+void application_remove_proxy (application_t * app);
+
#endif /* SRC_VNET_SESSION_APPLICATION_H_ */
/*
diff --git a/src/vnet/session/application_interface.c b/src/vnet/session/application_interface.c
index 8599c74fe46..a9dda022751 100644
--- a/src/vnet/session/application_interface.c
+++ b/src/vnet/session/application_interface.c
@@ -206,7 +206,7 @@ vnet_connect_i (u32 app_index, u32 api_context, session_endpoint_t * sep,
void *mp)
{
application_t *server, *app;
- u32 table_index;
+ u32 table_index, server_index;
stream_session_t *listener;
if (session_endpoint_is_zero (sep))
@@ -223,14 +223,23 @@ vnet_connect_i (u32 app_index, u32 api_context, session_endpoint_t * sep,
if (application_has_local_scope (app))
{
table_index = application_local_session_table (app);
- app_index = session_lookup_local_session_endpoint (table_index, sep);
- server = application_get (app_index);
+ server_index = session_lookup_local_session_endpoint (table_index, sep);
+
/*
- * Server is willing to have a direct fifo connection created
- * instead of going through the state machine, etc.
+ * Break loop if rule in local table points to connecting app. This
+ * can happen if client is a generic proxy. Route connect through
+ * global table instead.
*/
- if (server && (server->flags & APP_OPTIONS_FLAGS_ACCEPT_REDIRECT))
- return app_connect_redirect (server, mp);
+ if (server_index != app_index)
+ {
+ server = application_get (server_index);
+ /*
+ * Server is willing to have a direct fifo connection created
+ * instead of going through the state machine, etc.
+ */
+ if (server && (server->flags & APP_OPTIONS_FLAGS_ACCEPT_REDIRECT))
+ return app_connect_redirect (server, mp);
+ }
}
/*
@@ -414,6 +423,9 @@ vnet_application_attach (vnet_app_attach_args_t * a)
segment_manager_get_segment_info (sm->segment_indices[0],
&seg_name, &a->segment_size);
+ if (application_is_proxy (app))
+ application_setup_proxy (app);
+
a->segment_name_length = vec_len (seg_name);
a->segment_name = seg_name;
ASSERT (vec_len (a->segment_name) <= 128);
diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h
index 0251c3bc311..686b4181a7c 100644
--- a/src/vnet/session/application_interface.h
+++ b/src/vnet/session/application_interface.h
@@ -108,6 +108,7 @@ typedef enum
APP_OPTIONS_PRIVATE_SEGMENT_SIZE,
APP_OPTIONS_NAMESPACE,
APP_OPTIONS_NAMESPACE_SECRET,
+ APP_OPTIONS_PROXY_TRANSPORT,
SESSION_OPTIONS_SEGMENT_SIZE,
SESSION_OPTIONS_ADD_SEGMENT_SIZE,
SESSION_OPTIONS_RX_FIFO_SIZE,
@@ -120,7 +121,7 @@ typedef enum
#define foreach_app_options_flags \
_(ACCEPT_REDIRECT, "Use FIFO with redirects") \
_(ADD_SEGMENT, "Add segment and signal app if needed") \
- _(BUILTIN_APP, "Application is builtin") \
+ _(IS_BUILTIN, "Application is builtin") \
_(IS_PROXY, "Application is proxying") \
_(USE_GLOBAL_SCOPE, "App can use global session scope") \
_(USE_LOCAL_SCOPE, "App can use local session scope")
diff --git a/src/vnet/session/mma_template.c b/src/vnet/session/mma_template.c
index 81333a73ee5..a8386695944 100644
--- a/src/vnet/session/mma_template.c
+++ b/src/vnet/session/mma_template.c
@@ -220,7 +220,11 @@ RT (mma_rules_table_del_rule) (RTT (mma_rules_table) * srt,
if (!RT (rule_is_match_for_key) (&rule->match, rp))
return ~0;
if (RT (rule_is_exact_match) (rule, rp))
- return 1;
+ {
+ if (rule_index == srt->root_index)
+ rp->action_index = SESSION_RULES_TABLE_INVALID_INDEX;
+ return 1;
+ }
for (i = 0; i < vec_len (rp->next_indices); i++)
{
rv = RT (mma_rules_table_del_rule) (srt, rule, rp->next_indices[i]);
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 34707e007e9..c214b81042f 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -581,7 +581,7 @@ session_stream_connect_notify (transport_connection_t * tc, u8 is_fail)
if (!is_fail)
{
sm = application_get_connect_segment_manager (app);
- alloc_fifos = application_is_proxy (app);
+ alloc_fifos = !application_is_builtin_proxy (app);
if (session_alloc_and_init (sm, tc, alloc_fifos, &new_s))
{
is_fail = 1;
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c
index 2168c61257c..58af2bc02d0 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -340,21 +340,15 @@ session_lookup_del_session (stream_session_t * s)
}
static stream_session_t *
-session_lookup_app_listen_session (u32 app_index)
+session_lookup_app_listen_session (u32 app_index, u8 fib_proto,
+ u8 transport_proto)
{
application_t *app;
app = application_get (app_index);
if (!app)
return 0;
- if (application_n_listeners (app) != 1)
- {
- clib_warning ("there should be one and only one listener %d",
- hash_elts (app->listeners_table));
- return 0;
- }
-
- return application_first_listener (app);
+ return application_first_listener (app, fib_proto, transport_proto);
}
stream_session_t *
@@ -366,7 +360,8 @@ session_lookup_rules_table4 (session_rules_table_t * srt, u8 proto,
action_index = session_rules_table_lookup4 (srt, proto, lcl, rmt, lcl_port,
rmt_port);
/* Nothing sophisticated for now, action index is app index */
- return session_lookup_app_listen_session (action_index);
+ return session_lookup_app_listen_session (action_index, FIB_PROTOCOL_IP4,
+ proto);
}
stream_session_t *
@@ -377,7 +372,8 @@ session_lookup_rules_table6 (session_rules_table_t * srt, u8 proto,
u32 action_index;
action_index = session_rules_table_lookup6 (srt, proto, lcl, rmt, lcl_port,
rmt_port);
- return session_lookup_app_listen_session (action_index);
+ return session_lookup_app_listen_session (action_index, FIB_PROTOCOL_IP6,
+ proto);
}
u64
@@ -1290,6 +1286,28 @@ VLIB_CLI_COMMAND (session_rule_command, static) =
};
/* *INDENT-ON* */
+void
+session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto,
+ u8 transport_proto)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ session_table_t *st;
+ st = session_table_get_for_fib_index (fib_index, fib_proto);
+ session_rules_table_cli_dump (vm, &st->session_rules, fib_proto,
+ transport_proto);
+}
+
+void
+session_lookup_dump_local_rules_table (u32 table_index, u8 fib_proto,
+ u8 transport_proto)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ session_table_t *st;
+ st = session_table_get (table_index);
+ session_rules_table_cli_dump (vm, &st->session_rules, fib_proto,
+ transport_proto);
+}
+
static clib_error_t *
show_session_rules_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h
index 46af302d12c..d8f0518c192 100644
--- a/src/vnet/session/session_lookup.h
+++ b/src/vnet/session/session_lookup.h
@@ -86,6 +86,11 @@ void session_lookup_show_table_entries (vlib_main_t * vm,
session_table_t * table, u8 type,
u8 is_local);
+void session_lookup_dump_rules_table (u32 fib_index, u8 fib_proto,
+ u8 transport_proto);
+void session_lookup_dump_local_rules_table (u32 fib_index, u8 fib_proto,
+ u8 transport_proto);
+
enum _session_rule_scope
{
SESSION_RULE_SCOPE_GLOBAL = 1,
diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c
index bdd4f052adc..4b47754464d 100644
--- a/src/vnet/session/session_test.c
+++ b/src/vnet/session/session_test.c
@@ -124,7 +124,7 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input)
memset (options, 0, sizeof (options));
memset (intf_mac, 0, sizeof (intf_mac));
- options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_BUILTIN_APP;
+ options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
vnet_app_attach_args_t attach_args = {
.api_client_index = ~0,
@@ -753,7 +753,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
/*
* Attach server with global and local default scope
*/
- options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_BUILTIN_APP;
+ options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
@@ -896,6 +896,131 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input)
return 0;
}
+static int
+session_test_proxy (vlib_main_t * vm, unformat_input_t * input)
+{
+ u64 options[SESSION_OPTIONS_N_OPTIONS];
+ u32 server_index, app_index;
+ u32 dummy_server_api_index = ~0, sw_if_index = 0;
+ clib_error_t *error = 0;
+ u8 segment_name[128], intf_mac[6], sst;
+ stream_session_t *s;
+ transport_connection_t *tc;
+ u16 lcl_port = 1234, rmt_port = 4321;
+ app_namespace_t *app_ns;
+ int verbose = 0;
+
+ 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;
+ }
+ }
+
+ ip4_address_t lcl_ip = {
+ .as_u32 = clib_host_to_net_u32 (0x01020304),
+ };
+ ip4_address_t rmt_ip = {
+ .as_u32 = clib_host_to_net_u32 (0x05060708),
+ };
+ fib_prefix_t rmt_pref = {
+ .fp_addr.ip4.as_u32 = rmt_ip.as_u32,
+ .fp_len = 16,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ };
+ session_endpoint_t sep = {
+ .ip = rmt_pref.fp_addr,
+ .is_ip4 = 1,
+ .port = rmt_port,
+ .transport_proto = TRANSPORT_PROTO_TCP,
+ };
+
+ /*
+ * Create loopback interface
+ */
+ memset (intf_mac, 0, sizeof (intf_mac));
+ if (vnet_create_loopback_interface (&sw_if_index, intf_mac, 0, 0))
+ {
+ clib_warning ("couldn't create loopback. stopping the test!");
+ return 0;
+ }
+ vnet_sw_interface_set_flags (vnet_get_main (), sw_if_index,
+ VNET_SW_INTERFACE_FLAG_ADMIN_UP);
+ ip4_add_del_interface_address (vlib_get_main (), sw_if_index, &lcl_ip,
+ 24, 0);
+
+ app_ns = app_namespace_get_default ();
+ app_ns->sw_if_index = sw_if_index;
+
+ memset (options, 0, sizeof (options));
+ options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_ACCEPT_REDIRECT;
+ options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_IS_PROXY;
+ options[APP_OPTIONS_PROXY_TRANSPORT] = 1 << TRANSPORT_PROTO_TCP;
+ options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
+ options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
+ vnet_app_attach_args_t attach_args = {
+ .api_client_index = ~0,
+ .options = options,
+ .namespace_id = 0,
+ .session_cb_vft = &dummy_session_cbs,
+ .segment_name = segment_name,
+ };
+
+ attach_args.api_client_index = dummy_server_api_index;
+ error = vnet_application_attach (&attach_args);
+ SESSION_TEST ((error == 0), "server attachment should work");
+ server_index = attach_args.app_index;
+
+ if (verbose)
+ session_lookup_dump_rules_table (0, FIB_PROTOCOL_IP4,
+ TRANSPORT_PROTO_TCP);
+
+ tc = session_lookup_connection_wt4 (0, &lcl_ip, &rmt_ip, lcl_port, rmt_port,
+ TRANSPORT_PROTO_TCP, 0);
+ SESSION_TEST ((tc != 0), "lookup 1.2.3.4 1234 5.6.7.8 4321 should be "
+ "successful");
+ sst = session_type_from_proto_and_ip (TRANSPORT_PROTO_TCP, 1);
+ s = listen_session_get (sst, tc->s_index);
+ SESSION_TEST ((s->app_index == server_index), "lookup should return the"
+ " server");
+
+ tc = session_lookup_connection_wt4 (0, &rmt_ip, &rmt_ip, lcl_port, rmt_port,
+ TRANSPORT_PROTO_TCP, 0);
+ SESSION_TEST ((tc == 0), "lookup 5.6.7.8 1234 5.6.7.8 4321 should"
+ " not work");
+
+ if (verbose)
+ session_lookup_dump_local_rules_table (app_ns->local_table_index,
+ FIB_PROTOCOL_IP4,
+ TRANSPORT_PROTO_TCP);
+ app_index =
+ session_lookup_local_session_endpoint (app_ns->local_table_index, &sep);
+ SESSION_TEST ((app_index == server_index), "local session endpoint lookup"
+ " should work");
+
+ vnet_app_detach_args_t detach_args = {
+ .app_index = server_index,
+ };
+ vnet_application_detach (&detach_args);
+
+ if (verbose)
+ session_lookup_dump_local_rules_table (app_ns->local_table_index,
+ FIB_PROTOCOL_IP4,
+ TRANSPORT_PROTO_TCP);
+
+ app_index =
+ session_lookup_local_session_endpoint (app_ns->local_table_index, &sep);
+ SESSION_TEST ((app_index == SESSION_RULES_TABLE_INVALID_INDEX),
+ "local session endpoint lookup should not work after detach");
+
+ return 0;
+}
+
static clib_error_t *
session_test (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd_arg)
@@ -914,6 +1039,8 @@ session_test (vlib_main_t * vm,
res = session_test_rule_table (vm, input);
else if (unformat (input, "rules"))
res = session_test_rules (vm, input);
+ else if (unformat (input, "proxy"))
+ res = session_test_proxy (vm, input);
else
break;
}