diff options
author | Steven Luong <sluong@cisco.com> | 2024-09-24 16:17:00 -0700 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2024-09-28 01:49:53 +0000 |
commit | 6b3b6072e078c999382e371d63bc6c8732394244 (patch) | |
tree | f985311e0cd115b6310f7d4c5138e6409983e90f | |
parent | e3ad5aa68a3a8338c7ee27eaf0b45fa7e56841f4 (diff) |
hsa: Add multiple listeners support
It is desirable that http cli server can support multiple listeners.
This is needed for supporting both ip4 and ip6 at the same time.
Added the optional keyword listener add | del to the
http cli server command.
Example usage: start ip4 default uri and then add ip6 uri
http cli server
http cli server uri http://2001::2/80 listener add
Type: improvement
Change-Id: I884a4cd64ff676f9759a062b6d607a1742f610f3
Signed-off-by: Steven Luong <sluong@cisco.com>
-rw-r--r-- | src/plugins/hs_apps/http_cli.c | 133 |
1 files changed, 123 insertions, 10 deletions
diff --git a/src/plugins/hs_apps/http_cli.c b/src/plugins/hs_apps/http_cli.c index e0bb9afba4a..18b57f6c29d 100644 --- a/src/plugins/hs_apps/http_cli.c +++ b/src/plugins/hs_apps/http_cli.c @@ -30,6 +30,12 @@ typedef struct { + u32 handle; + u8 *uri; +} hcs_uri_map_t; + +typedef struct +{ u32 hs_index; u32 thread_index; u64 node_index; @@ -62,6 +68,12 @@ typedef struct u32 fifo_size; u8 *uri; vlib_main_t *vlib_main; + + /* hash table to store uri -> uri map pool index */ + uword *index_by_uri; + + /* pool of uri maps */ + hcs_uri_map_t *uri_map_pool; } hcs_main_t; static hcs_main_t hcs_main; @@ -619,15 +631,15 @@ hcs_listen () session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL; hcs_main_t *hcm = &hcs_main; vnet_listen_args_t _a, *a = &_a; - char *uri = "tcp://0.0.0.0/80"; u8 need_crypto; int rv; + char *uri; clib_memset (a, 0, sizeof (*a)); a->app_index = hcm->app_index; - if (hcm->uri) - uri = (char *) hcm->uri; + uri = (char *) hcm->uri; + ASSERT (uri); if (parse_uri (uri, &sep)) return -1; @@ -645,6 +657,14 @@ hcs_listen () } rv = vnet_listen (a); + if (rv == 0) + { + hcs_uri_map_t *map; + pool_get_zero (hcm->uri_map_pool, map); + map->uri = vec_dup (uri); + map->handle = a->handle; + hash_set_mem (hcm->index_by_uri, map->uri, map - hcm->uri_map_pool); + } if (need_crypto) clib_mem_free (a->sep_ext.ext_cfg); @@ -652,6 +672,44 @@ hcs_listen () return rv; } +static int +hcs_unlisten () +{ + session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL; + hcs_main_t *hcm = &hcs_main; + vnet_unlisten_args_t _a, *a = &_a; + char *uri; + int rv = 0; + uword *value; + + clib_memset (a, 0, sizeof (*a)); + a->app_index = hcm->app_index; + + uri = (char *) hcm->uri; + ASSERT (uri); + + if (parse_uri (uri, &sep)) + return -1; + + value = hash_get_mem (hcm->index_by_uri, uri); + if (value) + { + hcs_uri_map_t *map = pool_elt_at_index (hcm->uri_map_pool, *value); + + a->handle = map->handle; + rv = vnet_unlisten (a); + if (rv == 0) + { + vec_free (map->uri); + pool_put (hcm->uri_map_pool, map); + } + } + else + return -1; + + return rv; +} + static void hcs_detach () { @@ -696,6 +754,8 @@ hcs_create_command_fn (vlib_main_t *vm, unformat_input_t *input, hcs_main_t *hcm = &hcs_main; u64 seg_size; int rv; + u32 listener_add = ~0; + clib_error_t *error = 0; hcm->prealloc_fifos = 0; hcm->private_segment_size = 0; @@ -714,13 +774,28 @@ hcs_create_command_fn (vlib_main_t *vm, unformat_input_t *input, hcm->private_segment_size = seg_size; else if (unformat (line_input, "fifo-size %d", &hcm->fifo_size)) hcm->fifo_size <<= 10; - else if (unformat (line_input, "uri %s", &hcm->uri)) + else if (unformat (line_input, "uri %_%v%_", &hcm->uri)) ; + else if (unformat (line_input, "listener")) + { + if (unformat (line_input, "add")) + listener_add = 1; + else if (unformat (line_input, "del")) + listener_add = 0; + else + { + unformat_free (line_input); + error = clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + goto done; + } + } else { unformat_free (line_input); - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, line_input); + error = clib_error_return (0, "unknown input `%U'", + format_unformat_error, line_input); + goto done; } } @@ -728,8 +803,39 @@ hcs_create_command_fn (vlib_main_t *vm, unformat_input_t *input, start_server: + if (hcm->uri == 0) + hcm->uri = format (0, "tcp://0.0.0.0/80%c", 0); + if (hcm->app_index != (u32) ~0) - return clib_error_return (0, "test http server is already running"); + { + if (listener_add == 1) + { + if (hcs_listen ()) + { + error = clib_error_return (0, "failed to start listening %v", + hcm->uri); + goto done; + } + else + goto done; + } + else if (listener_add == 0) + { + if (hcs_unlisten () != 0) + { + error = + clib_error_return (0, "failed to stop listening %v", hcm->uri); + goto done; + } + else + goto done; + } + else + { + error = clib_error_return (0, "test http server is already running"); + goto done; + } + } session_enable_disable_args_t args = { .is_en = 1, .rt_engine_type = @@ -742,16 +848,22 @@ start_server: case 0: break; default: - return clib_error_return (0, "server_create returned %d", rv); + { + error = clib_error_return (0, "server_create returned %d", rv); + goto done; + } } - return 0; +done: + vec_free (hcm->uri); + return error; } VLIB_CLI_COMMAND (hcs_create_command, static) = { .path = "http cli server", .short_help = "http cli server [uri <uri>] [fifo-size <nbytes>] " - "[private-segment-size <nMG>] [prealloc-fifos <n>]", + "[private-segment-size <nMG>] [prealloc-fifos <n>] " + "[listener <add|del>]", .function = hcs_create_command_fn, }; @@ -762,6 +874,7 @@ hcs_main_init (vlib_main_t *vm) hcs->app_index = ~0; hcs->vlib_main = vm; + hcs->index_by_uri = hash_create_vec (0, sizeof (u8), sizeof (uword)); return 0; } |