diff options
author | Nathan Skrzypczak <nathan.skrzypczak@gmail.com> | 2021-12-15 19:15:32 +0100 |
---|---|---|
committer | Damjan Marion <dmarion@0xa5.net> | 2023-03-06 13:54:06 +0000 |
commit | 8b213ee652dd69d941865fa59e1f780843016475 (patch) | |
tree | f37774b199588dcace4b1c4277b8398fc3cc0498 | |
parent | ec5c40b83acae400a8cc1a18ad897b6365774559 (diff) |
memif: autogenerate socket_ids
This patch adds an API memif_socket_filename_add_del_v2
that allows autogenerating memif socket_id when passing
~0 in the socket_id field.
It opportunistically walks the hash to find a free ID
to use, and returns it in the reply.
socket_filename also becomes a variable length string,
to accomodate for longer names (in case a netns gets
passed)
Type: feature
Change-Id: I33fc3e1cf553af27579d6bad8691b22b530531cc
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
-rw-r--r-- | src/plugins/memif/memif.api | 34 | ||||
-rw-r--r-- | src/plugins/memif/memif.c | 30 | ||||
-rw-r--r-- | src/plugins/memif/memif_api.c | 36 | ||||
-rw-r--r-- | src/plugins/memif/memif_test.c | 80 | ||||
-rw-r--r-- | src/plugins/memif/private.h | 1 |
5 files changed, 181 insertions, 0 deletions
diff --git a/src/plugins/memif/memif.api b/src/plugins/memif/memif.api index 9e32db5b470..91e72f73ab4 100644 --- a/src/plugins/memif/memif.api +++ b/src/plugins/memif/memif.api @@ -51,6 +51,40 @@ autoreply define memif_socket_filename_add_del option vat_help = "[add|del] id <id> filename <file>"; }; +/** \brief Create or remove named socket file for memif interfaces + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_add - 0 = remove, 1 = add association + @param socket_id - non-0 32-bit integer used to identify a socket file + ~0 means autogenerate + @param socket_filename - filename of the socket to be used for connection + establishment; id 0 always maps to default "/var/vpp/memif.sock"; + no socket filename needed when is_add == 0. + socket_filename starting with '@' will create an abstract socket + in the given namespace +*/ +define memif_socket_filename_add_del_v2 +{ + u32 client_index; + u32 context; + bool is_add; /* 0 = remove, 1 = add association */ + u32 socket_id [default=0xffffffff]; /* unique non-0 id for given socket file name */ + string socket_filename[]; /* NUL terminated filename */ + option vat_help = "[add|del] id <id> filename <file>"; +}; + +/** \brief Create memory interface socket file response + @param context - sender context, to match reply w/ request + @param retval - return value for request + @param socket_id - non-0 32-bit integer used to identify a socket file +*/ +define memif_socket_filename_add_del_v2_reply +{ + u32 context; + i32 retval; + u32 socket_id; +}; + /** \brief Create memory interface @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/src/plugins/memif/memif.c b/src/plugins/memif/memif.c index eee38f09a5b..c9d2f008cca 100644 --- a/src/plugins/memif/memif.c +++ b/src/plugins/memif/memif.c @@ -681,6 +681,36 @@ VLIB_REGISTER_NODE (memif_process_node,static) = { .name = "memif-process", }; +/* + * Returns an unused socket id, and ~0 if it can't find one. + */ +u32 +memif_get_unused_socket_id () +{ + memif_main_t *mm = &memif_main; + uword *p; + int i, j; + + static u32 seed = 0; + /* limit to 1M tries */ + for (j = 0; j < 1 << 10; j++) + { + seed = random_u32 (&seed); + for (i = 0; i < 1 << 10; i++) + { + /* look around randomly generated id */ + seed += (2 * (i % 2) - 1) * i; + if (seed == (u32) ~0) + continue; + p = hash_get (mm->socket_file_index_by_sock_id, seed); + if (!p) + return seed; + } + } + + return ~0; +} + clib_error_t * memif_socket_filename_add_del (u8 is_add, u32 sock_id, char *sock_filename) { diff --git a/src/plugins/memif/memif_api.c b/src/plugins/memif/memif_api.c index 9a2f42a5bc7..819350a6795 100644 --- a/src/plugins/memif/memif_api.c +++ b/src/plugins/memif/memif_api.c @@ -72,6 +72,42 @@ reply: REPLY_MACRO (VL_API_MEMIF_SOCKET_FILENAME_ADD_DEL_REPLY); } +/** + * @brief Message handler for memif_socket_filename_add_del API. + * @param mp the vl_api_memif_socket_filename_add_del_t API message + */ +void +vl_api_memif_socket_filename_add_del_v2_t_handler ( + vl_api_memif_socket_filename_add_del_v2_t *mp) +{ + vl_api_memif_socket_filename_add_del_v2_reply_t *rmp; + memif_main_t *mm = &memif_main; + char *socket_filename = 0; + u32 socket_id; + int rv; + + /* socket_id */ + socket_id = clib_net_to_host_u32 (mp->socket_id); + if (socket_id == 0) + { + rv = VNET_API_ERROR_INVALID_ARGUMENT; + goto reply; + } + + /* socket filename */ + socket_filename = vl_api_from_api_to_new_c_string (&mp->socket_filename); + if (mp->is_add && socket_id == (u32) ~0) + socket_id = memif_get_unused_socket_id (); + + rv = vnet_api_error ( + memif_socket_filename_add_del (mp->is_add, socket_id, socket_filename)); + + vec_free (socket_filename); + +reply: + REPLY_MACRO2 (VL_API_MEMIF_SOCKET_FILENAME_ADD_DEL_V2_REPLY, + ({ rmp->socket_id = htonl (socket_id); })); +} /** * @brief Message handler for memif_create API. diff --git a/src/plugins/memif/memif_test.c b/src/plugins/memif/memif_test.c index 98c9354a95e..07d68924b86 100644 --- a/src/plugins/memif/memif_test.c +++ b/src/plugins/memif/memif_test.c @@ -121,6 +121,86 @@ api_memif_socket_filename_add_del (vat_main_t * vam) return ret; } +/* memif_socket_filename_add_del API */ +static int +api_memif_socket_filename_add_del_v2 (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_memif_socket_filename_add_del_v2_t *mp; + u8 is_add; + u32 socket_id; + u8 *socket_filename; + int ret; + + is_add = 1; + socket_id = ~0; + socket_filename = 0; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "id %u", &socket_id)) + ; + else if (unformat (i, "filename %s", &socket_filename)) + ; + else if (unformat (i, "del")) + is_add = 0; + else if (unformat (i, "add")) + is_add = 1; + else + { + vec_free (socket_filename); + clib_warning ("unknown input `%U'", format_unformat_error, i); + return -99; + } + } + + if (socket_id == 0 || socket_id == ~0) + { + vec_free (socket_filename); + errmsg ("Invalid socket id"); + return -99; + } + + if (is_add && (!socket_filename || *socket_filename == 0)) + { + vec_free (socket_filename); + errmsg ("Invalid socket filename"); + return -99; + } + + M2 (MEMIF_SOCKET_FILENAME_ADD_DEL_V2, mp, strlen ((char *) socket_filename)); + + mp->is_add = is_add; + mp->socket_id = htonl (socket_id); + char *p = (char *) &mp->socket_filename; + p += vl_api_vec_to_api_string (socket_filename, (vl_api_string_t *) p); + + vec_free (socket_filename); + + S (mp); + W (ret); + + return ret; +} + +/* memif socket-create reply handler */ +static void +vl_api_memif_socket_filename_add_del_v2_reply_t_handler ( + vl_api_memif_socket_filename_add_del_v2_reply_t *mp) +{ + vat_main_t *vam = memif_test_main.vat_main; + i32 retval = ntohl (mp->retval); + + if (retval == 0) + { + fformat (vam->ofp, "created memif socket with socket_id %d\n", + ntohl (mp->socket_id)); + } + + vam->retval = retval; + vam->result_ready = 1; +} + /* memif_socket_filename_add_del reply handler */ #define VL_API_MEMIF_SOCKET_FILENAME_ADD_DEL_REPLY_T_HANDLER static void vl_api_memif_socket_filename_add_del_reply_t_handler diff --git a/src/plugins/memif/private.h b/src/plugins/memif/private.h index ba77cc1c5dd..5d8718dd669 100644 --- a/src/plugins/memif/private.h +++ b/src/plugins/memif/private.h @@ -321,6 +321,7 @@ typedef struct u32 sw_if_index; } memif_create_if_args_t; +u32 memif_get_unused_socket_id (); clib_error_t *memif_socket_filename_add_del (u8 is_add, u32 sock_id, char *sock_filename); clib_error_t *memif_create_if (vlib_main_t *vm, memif_create_if_args_t *args); |