aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/memif
diff options
context:
space:
mode:
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>2021-12-15 19:15:32 +0100
committerDamjan Marion <dmarion@0xa5.net>2023-03-06 13:54:06 +0000
commit8b213ee652dd69d941865fa59e1f780843016475 (patch)
treef37774b199588dcace4b1c4277b8398fc3cc0498 /src/plugins/memif
parentec5c40b83acae400a8cc1a18ad897b6365774559 (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>
Diffstat (limited to 'src/plugins/memif')
-rw-r--r--src/plugins/memif/memif.api34
-rw-r--r--src/plugins/memif/memif.c30
-rw-r--r--src/plugins/memif/memif_api.c36
-rw-r--r--src/plugins/memif/memif_test.c80
-rw-r--r--src/plugins/memif/private.h1
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);