From 4e4531e4b10883be8c320ff3b9acd4950135f5f0 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Mon, 6 Nov 2017 23:27:56 -0800 Subject: [PATCH] session: fix v6 double binds Change-Id: Ie747b490901254e962cf61814491851b891129ee Signed-off-by: Florin Coras --- src/vnet/session/segment_manager.c | 7 +++ src/vnet/session/segment_manager.h | 1 + src/vnet/session/session_lookup.c | 8 ++-- src/vnet/session/session_test.c | 92 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 100 insertions(+), 8 deletions(-) diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index cb83d8e53bc..f5a40244400 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -217,6 +217,12 @@ segment_manager_app_detached (segment_manager_t * sm) return (sm->app_index == SEGMENT_MANAGER_INVALID_APP_INDEX); } +void +segment_manager_app_detach (segment_manager_t * sm) +{ + sm->app_index = SEGMENT_MANAGER_INVALID_APP_INDEX; +} + static void segment_manager_del_segment (segment_manager_t * sm, u32 segment_index) { @@ -325,6 +331,7 @@ segment_manager_del (segment_manager_t * sm) void segment_manager_init_del (segment_manager_t * sm) { + segment_manager_app_detach (sm); if (segment_manager_has_fifos (sm)) segment_manager_del_sessions (sm); else diff --git a/src/vnet/session/segment_manager.h b/src/vnet/session/segment_manager.h index 6e5b8989891..8c438801a4a 100644 --- a/src/vnet/session/segment_manager.h +++ b/src/vnet/session/segment_manager.h @@ -120,6 +120,7 @@ unix_shared_memory_queue_t *segment_manager_alloc_queue (segment_manager_t * sm, u32 queue_size); void segment_manager_dealloc_queue (segment_manager_t * sm, unix_shared_memory_queue_t * q); +void segment_manager_app_detach (segment_manager_t * sm); #endif /* SRC_VNET_SESSION_SEGMENT_MANAGER_H_ */ /* diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 6cdb839ceff..afbb8dada52 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -407,14 +407,15 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) ip6_address_t lcl6; u32 ai; int rv; + u8 sst; + sst = session_type_from_proto_and_ip (sep->transport_proto, sep->is_ip4); st = session_table_get (table_index); if (!st) return SESSION_INVALID_HANDLE; if (sep->is_ip4) { - make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port, - sep->transport_proto); + make_v4_listener_kv (&kv4, &sep->ip.ip4, sep->port, sst); rv = clib_bihash_search_inline_16_8 (&st->v4_session_hash, &kv4); if (rv == 0) return kv4.value; @@ -428,8 +429,7 @@ session_lookup_session_endpoint (u32 table_index, session_endpoint_t * sep) } else { - make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port, - sep->transport_proto); + make_v6_listener_kv (&kv6, &sep->ip.ip6, sep->port, sst); rv = clib_bihash_search_inline_48_8 (&st->v6_session_hash, &kv6); if (rv == 0) return kv6.value; diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c index 8d18619067f..56d40b81ef8 100644 --- a/src/vnet/session/session_test.c +++ b/src/vnet/session/session_test.c @@ -98,6 +98,72 @@ static session_cb_vft_t dummy_session_cbs = { }; /* *INDENT-ON* */ +static int +session_test_basic (vlib_main_t * vm, unformat_input_t * input) +{ + session_endpoint_t server_sep = SESSION_ENDPOINT_NULL; + u64 options[SESSION_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle; + u8 segment_name[128]; + clib_error_t *error = 0; + u32 server_index; + + memset (options, 0, sizeof (options)); + 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; + 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, + }; + + error = vnet_application_attach (&attach_args); + SESSION_TEST ((error == 0), "app attached"); + server_index = attach_args.app_index; + + server_sep.is_ip4 = 1; + vnet_bind_args_t bind_args = { + .sep = server_sep, + .app_index = 0, + }; + + bind_args.app_index = server_index; + error = vnet_bind (&bind_args); + SESSION_TEST ((error == 0), "server bind4 should work"); + bind4_handle = bind_args.handle; + + error = vnet_bind (&bind_args); + SESSION_TEST ((error != 0), "double server bind4 should not work"); + + bind_args.sep.is_ip4 = 0; + error = vnet_bind (&bind_args); + SESSION_TEST ((error == 0), "server bind6 should work"); + bind6_handle = bind_args.handle; + + error = vnet_bind (&bind_args); + SESSION_TEST ((error != 0), "double server bind6 should not work"); + + vnet_unbind_args_t unbind_args = { + .handle = bind4_handle, + .app_index = server_index, + }; + error = vnet_unbind (&unbind_args); + SESSION_TEST ((error == 0), "unbind4 should work"); + + unbind_args.handle = bind6_handle; + error = vnet_unbind (&unbind_args); + SESSION_TEST ((error == 0), "unbind6 should work"); + + vnet_app_detach_args_t detach_args = { + .app_index = server_index, + }; + vnet_application_detach (&detach_args); + return 0; +} + static int session_test_namespace (vlib_main_t * vm, unformat_input_t * input) { @@ -976,6 +1042,10 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) SESSION_TEST ((error == 0), "Del 1.2.3.4/32 1234 5.6.7.8/32 4321 drop " "tag test_rule"); + vnet_app_detach_args_t detach_args = { + .app_index = server_index, + }; + vnet_application_detach (&detach_args); return 0; } @@ -1114,20 +1184,34 @@ session_test (vlib_main_t * vm, while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - if (unformat (input, "namespace")) - { - res = session_test_namespace (vm, input); - } + if (unformat (input, "basic")) + res = session_test_basic (vm, input); + else if (unformat (input, "namespace")) + res = session_test_namespace (vm, input); else if (unformat (input, "rules-table")) 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 if (unformat (input, "all")) + { + if ((res = session_test_basic (vm, input))) + goto done; + if ((res = session_test_namespace (vm, input))) + goto done; + if ((res = session_test_rule_table (vm, input))) + goto done; + if ((res = session_test_rules (vm, input))) + goto done; + if ((res = session_test_proxy (vm, input))) + goto done; + } else break; } +done: if (res) return clib_error_return (0, "Session unit test failed"); return 0; -- 2.16.6