summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-12-19 04:50:01 -0800
committerDave Barach <openvpp@barachs.net>2018-01-05 19:00:45 +0000
commit90a63988fa01685626b6d6a01b79ea5370f7fbac (patch)
tree69951111b8f8c43c5dbfc61cc5b133f74a58ddda
parente6bfeab1c352ae73a19361c038e2a06a58c035db (diff)
sock api: add infra for bootstrapping shm clients
- add function to sock client that bootstraps shm api - allow sock clients to request custom shm ring configs Change-Id: Iabc1dd4f0dc8bbf8ba24de37f4966339fcf86107 Signed-off-by: Florin Coras <fcoras@cisco.com>
-rw-r--r--src/tests/vnet/session/tcp_echo.c112
-rw-r--r--src/vat/api_format.c72
-rw-r--r--src/vat/main.c2
-rw-r--r--src/vat/vat.h2
-rw-r--r--src/vlibapi/vat_helper_macros.h64
-rw-r--r--src/vlibmemory/api_common.h38
-rw-r--r--src/vlibmemory/memclnt.api17
-rw-r--r--src/vlibmemory/memory_shared.c82
-rw-r--r--src/vlibmemory/memory_vlib.c4
-rw-r--r--src/vlibmemory/socket_client.c324
-rw-r--r--src/vlibmemory/socksvr_vlib.c200
-rw-r--r--src/vnet/lisp-cp/one_api.c14
-rw-r--r--src/vppinfra/file.h7
13 files changed, 679 insertions, 259 deletions
diff --git a/src/tests/vnet/session/tcp_echo.c b/src/tests/vnet/session/tcp_echo.c
index 8bdcac3a88c..30eb54dcdda 100644
--- a/src/tests/vnet/session/tcp_echo.c
+++ b/src/tests/vnet/session/tcp_echo.c
@@ -15,10 +15,12 @@
#include <stdio.h>
#include <signal.h>
+
+#include <vnet/session/application_interface.h>
#include <svm/svm_fifo_segment.h>
#include <vlibmemory/api.h>
+
#include <vpp/api/vpe_msg_enum.h>
-#include <vnet/session/application_interface.h>
#define vl_typedefs /* define message structures */
#include <vpp/api/vpe_all_api_h.h>
@@ -91,6 +93,8 @@ typedef struct
/* $$$ single thread only for the moment */
unix_shared_memory_queue_t *vpp_event_queue;
+ u8 *socket_name;
+
pid_t my_pid;
/* For deadman timers */
@@ -114,6 +118,11 @@ typedef struct
u8 test_return_packets;
u64 bytes_to_send;
+ /** Flag that decides if socket, instead of svm, api is used to connect to
+ * vpp. If sock api is used, shm binary api is subsequently bootstrapped
+ * and all other messages are exchanged using shm IPC. */
+ u8 use_sock_api;
+
/* convenience */
svm_fifo_segment_main_t *segment_main;
} uri_tcp_test_main_t;
@@ -313,15 +322,33 @@ connect_to_vpp (char *name)
uri_tcp_test_main_t *utm = &uri_tcp_test_main;
api_main_t *am = &api_main;
- if (vl_client_connect_to_vlib ("/vpe-api", name, 32) < 0)
- return -1;
-
- utm->vl_input_queue = am->shmem_hdr->vl_input_queue;
- utm->my_client_index = am->my_client_index;
+ if (utm->use_sock_api)
+ {
+ if (vl_socket_client_connect ((char *) utm->socket_name, name,
+ 0 /* default rx, tx buffer */ ))
+ return -1;
+ return vl_socket_client_init_shm (0);
+ }
+ else
+ {
+ if (vl_client_connect_to_vlib ("/vpe-api", name, 32) < 0)
+ return -1;
+ utm->vl_input_queue = am->shmem_hdr->vl_input_queue;
+ utm->my_client_index = am->my_client_index;
+ }
return 0;
}
+void
+disconnect_from_vpp (uri_tcp_test_main_t * utm)
+{
+ if (utm->use_sock_api)
+ vl_socket_client_disconnect ();
+ else
+ vl_client_disconnect_from_vlib ();
+}
+
static void
vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
{
@@ -733,7 +760,7 @@ client_disconnect (uri_tcp_test_main_t * utm)
}
static void
-client_test (uri_tcp_test_main_t * utm)
+client_run (uri_tcp_test_main_t * utm)
{
int i;
@@ -1085,8 +1112,20 @@ server_unbind (uri_tcp_test_main_t * utm)
}
void
-server_test (uri_tcp_test_main_t * utm)
+server_run (uri_tcp_test_main_t * utm)
{
+ session_t *session;
+ int i;
+
+ /* $$$$ hack preallocation */
+ for (i = 0; i < 200000; i++)
+ {
+ pool_get (utm->sessions, session);
+ memset (session, 0, sizeof (*session));
+ }
+ for (i = 0; i < 200000; i++)
+ pool_put_index (utm->sessions, i);
+
if (application_attach (utm))
return;
@@ -1124,17 +1163,17 @@ vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t *
session_print_stats (utm, session);
}
-#define foreach_uri_msg \
-_(BIND_URI_REPLY, bind_uri_reply) \
-_(UNBIND_URI_REPLY, unbind_uri_reply) \
-_(ACCEPT_SESSION, accept_session) \
-_(CONNECT_SESSION_REPLY, connect_session_reply) \
-_(DISCONNECT_SESSION, disconnect_session) \
-_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
-_(RESET_SESSION, reset_session) \
-_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
-_(APPLICATION_DETACH_REPLY, application_detach_reply) \
-_(MAP_ANOTHER_SEGMENT, map_another_segment) \
+#define foreach_uri_msg \
+_(BIND_URI_REPLY, bind_uri_reply) \
+_(UNBIND_URI_REPLY, unbind_uri_reply) \
+_(ACCEPT_SESSION, accept_session) \
+_(CONNECT_SESSION_REPLY, connect_session_reply) \
+_(DISCONNECT_SESSION, disconnect_session) \
+_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
+_(RESET_SESSION, reset_session) \
+_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
+_(APPLICATION_DETACH_REPLY, application_detach_reply) \
+_(MAP_ANOTHER_SEGMENT, map_another_segment) \
void
uri_api_hookup (uri_tcp_test_main_t * utm)
@@ -1162,8 +1201,6 @@ main (int argc, char **argv)
u64 bytes_to_send = 64 << 10, mbytes;
u32 tmp;
mheap_t *h;
- session_t *session;
- int i;
int i_am_master = 1, drop_packets = 0, test_return_packets = 0;
clib_mem_init (0, 256 << 20);
@@ -1180,6 +1217,8 @@ main (int argc, char **argv)
utm->my_pid = getpid ();
utm->configured_segment_size = 1 << 20;
+ utm->socket_name = 0;
+ utm->use_sock_api = 1;
clib_time_init (&utm->clib_time);
init_error_string_table (utm);
@@ -1214,6 +1253,10 @@ main (int argc, char **argv)
{
bytes_to_send = mbytes << 30;
}
+ else if (unformat (a, "socket-name %s", &utm->socket_name))
+ ;
+ else if (unformat (a, "use-svm-api"))
+ utm->use_sock_api = 0;
else
{
fformat (stderr, "%s: usage [master|slave]\n");
@@ -1221,6 +1264,9 @@ main (int argc, char **argv)
}
}
+ if (!utm->socket_name)
+ utm->socket_name = format (0, "%s%c", API_SOCKET_FILE, 0);
+
if (uri)
{
utm->uri = format (0, "%s%c", uri, 0);
@@ -1242,7 +1288,8 @@ main (int argc, char **argv)
setup_signal_handlers ();
uri_api_hookup (utm);
- if (connect_to_vpp (i_am_master ? "uri_tcp_server" : "uri_tcp_client") < 0)
+ if (connect_to_vpp (i_am_master ? "tcp_echo_server" : "tcp_echo_client") <
+ 0)
{
svm_region_exit ();
fformat (stderr, "Couldn't connect to vpe, exiting...\n");
@@ -1250,24 +1297,11 @@ main (int argc, char **argv)
}
if (i_am_master == 0)
- {
- client_test (utm);
- vl_client_disconnect_from_vlib ();
- exit (0);
- }
-
- /* $$$$ hack preallocation */
- for (i = 0; i < 200000; i++)
- {
- pool_get (utm->sessions, session);
- memset (session, 0, sizeof (*session));
- }
- for (i = 0; i < 200000; i++)
- pool_put_index (utm->sessions, i);
-
- server_test (utm);
+ client_run (utm);
+ else
+ server_run (utm);
- vl_client_disconnect_from_vlib ();
+ disconnect_from_vpp (utm);
exit (0);
}
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index 445b4962b36..88c64473518 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -88,9 +88,9 @@ vl (void *p)
int
vat_socket_connect (vat_main_t * vam)
{
- return vl_socket_client_connect
- (&vam->socket_client_main, (char *) vam->socket_name,
- "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
+ vam->socket_client_main = &socket_client_main;
+ return vl_socket_client_connect ((char *) vam->socket_name, "vpp_api_test",
+ 0 /* default socket rx, tx buffer */ );
}
#else /* vpp built-in case, we don't do sockets... */
int
@@ -99,10 +99,23 @@ vat_socket_connect (vat_main_t * vam)
return 0;
}
-void
-vl_socket_client_read_reply (socket_client_main_t * scm)
+int
+vl_socket_client_read (int wait)
+{
+ return -1;
+};
+
+int
+vl_socket_client_write ()
{
+ return -1;
};
+
+void *
+vl_socket_client_msg_alloc (int nbytes)
+{
+ return 0;
+}
#endif
@@ -1464,7 +1477,8 @@ static void vl_api_control_ping_reply_t_handler
vam->retval = retval;
vam->result_ready = 1;
}
- vam->socket_client_main.control_pings_outstanding--;
+ if (vam->socket_client_main)
+ vam->socket_client_main->control_pings_outstanding--;
}
static void vl_api_control_ping_reply_t_handler_json
@@ -2186,7 +2200,7 @@ static void vl_api_memfd_segment_create_reply_t_handler
#if VPP_API_TEST_BUILTIN == 0
vat_main_t *vam = &vat_main;
api_main_t *am = &api_main;
- socket_client_main_t *scm = &vam->socket_client_main;
+ socket_client_main_t *scm = vam->socket_client_main;
int my_fd = -1;
clib_error_t *error;
memfd_private_t memfd;
@@ -2224,8 +2238,7 @@ static void vl_api_memfd_segment_create_reply_t_handler
32 /* input_queue_length */ );
vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
- vl_socket_client_enable_disable (&vam->socket_client_main,
- 0 /* disable socket */ );
+ vl_socket_client_enable_disable (0 /* disable socket */ );
}
out:
@@ -21866,6 +21879,46 @@ api_memfd_segment_create (vat_main_t * vam)
}
static int
+api_sock_init_shm (vat_main_t * vam)
+{
+#if VPP_API_TEST_BUILTIN == 0
+ unformat_input_t *i = vam->input;
+ vl_api_shm_elem_config_t *config = 0;
+ u64 size = 64 << 20;
+ int rv;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "size %U", unformat_memory_size, &size))
+ ;
+ else
+ break;
+ }
+
+ /* Try customized config to see if it works */
+ vec_validate (config, 3);
+ config[0].type = VL_API_VLIB_RING;
+ config[0].count = 256;
+ config[0].size = 256;
+ config[1].type = VL_API_CLIENT_RING;
+ config[1].count = 256;
+ config[1].size = 1024;
+ config[2].type = VL_API_CLIENT_RING;
+ config[2].count = 8;
+ config[2].size = 4096;
+ config[3].type = VL_API_QUEUE;
+ config[3].count = 256;
+ config[3].size = sizeof (uword);
+ rv = vl_socket_client_init_shm (config);
+ if (!rv)
+ vam->client_index_invalid = 1;
+ return rv;
+#else
+ return -99;
+#endif
+}
+
+static int
api_dns_enable_disable (vat_main_t * vam)
{
unformat_input_t *line_input = vam->input;
@@ -23093,6 +23146,7 @@ _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n
" [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
_(memfd_segment_create,"size <nnn>") \
+_(sock_init_shm, "size <nnn>") \
_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
_(dns_enable_disable, "[enable][disable]") \
_(dns_name_server_add_del, "<ip-address> [del]") \
diff --git a/src/vat/main.c b/src/vat/main.c
index aa990a31d93..723c5e8cc3a 100644
--- a/src/vat/main.c
+++ b/src/vat/main.c
@@ -389,7 +389,7 @@ main (int argc, char **argv)
if (vam->socket_name && vat_socket_connect (vam))
fformat (stderr, "WARNING: socket connection failed");
- if (vam->socket_client_main.socket_fd == 0
+ if ((!vam->socket_client_main || vam->socket_client_main->socket_fd == 0)
&& connect_to_vpe ("vpp_api_test") < 0)
{
svm_region_exit ();
diff --git a/src/vat/vat.h b/src/vat/vat.h
index 1ae46f30a7e..ddb4644848a 100644
--- a/src/vat/vat.h
+++ b/src/vat/vat.h
@@ -209,7 +209,7 @@ typedef struct
ip4_nbr_counter_t **ip4_nbr_counters;
ip6_nbr_counter_t **ip6_nbr_counters;
- socket_client_main_t socket_client_main;
+ socket_client_main_t *socket_client_main;
u8 *socket_name;
/* Convenience */
diff --git a/src/vlibapi/vat_helper_macros.h b/src/vlibapi/vat_helper_macros.h
index fd2e563512f..52fdcb1cb5a 100644
--- a/src/vlibapi/vat_helper_macros.h
+++ b/src/vlibapi/vat_helper_macros.h
@@ -22,13 +22,10 @@
/* M: construct, but don't yet send a message */
#define M(T, mp) \
do { \
- socket_client_main_t *scm = &vam->socket_client_main; \
+ socket_client_main_t *scm = vam->socket_client_main; \
vam->result_ready = 0; \
- if (scm->socket_enable) \
- { \
- mp = (void *)scm->socket_tx_buffer; \
- scm->socket_tx_nbytes = sizeof (*mp); \
- } \
+ if (scm && scm->socket_enable) \
+ mp = vl_socket_client_msg_alloc (sizeof(*mp)); \
else \
mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)); \
memset (mp, 0, sizeof (*mp)); \
@@ -39,30 +36,25 @@ do { \
/* MPING: construct a control-ping message, don't send it yet */
#define MPING(T, mp) \
do { \
- socket_client_main_t *scm = &vam->socket_client_main; \
+ socket_client_main_t *scm = vam->socket_client_main; \
vam->result_ready = 0; \
- if (scm->socket_enable) \
- { \
- mp = (void *)scm->socket_tx_buffer; \
- scm->socket_tx_nbytes = sizeof (*mp); \
- } \
+ if (scm && scm->socket_enable) \
+ mp = vl_socket_client_msg_alloc (sizeof(*mp)); \
else \
mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)); \
memset (mp, 0, sizeof (*mp)); \
mp->_vl_msg_id = ntohs (VL_API_##T+__plugin_msg_base); \
mp->client_index = vam->my_client_index; \
- scm->control_pings_outstanding++; \
+ if (scm) \
+ scm->control_pings_outstanding++; \
} while(0);
#define M2(T, mp, n) \
do { \
- socket_client_main_t *scm = &vam->socket_client_main; \
+ socket_client_main_t *scm = vam->socket_client_main; \
vam->result_ready = 0; \
- if (scm->socket_enable) \
- { \
- mp = (void *)scm->socket_tx_buffer; \
- scm->socket_tx_nbytes = sizeof (*mp) + n; \
- } \
+ if (scm && scm->socket_enable) \
+ mp = vl_socket_client_msg_alloc (sizeof(*mp)); \
else \
mp = vl_msg_api_alloc_as_if_client(sizeof(*mp) + n); \
memset (mp, 0, sizeof (*mp)); \
@@ -73,27 +65,9 @@ do { \
/* S: send a message */
#define S(mp) \
do { \
- int n; \
- socket_client_main_t *scm = &vam->socket_client_main; \
- if (scm->socket_enable) \
- { \
- msgbuf_t msgbuf = \
- { \
- .q = 0, \
- .gc_mark_timestamp = 0, \
- .data_len = htonl(scm->socket_tx_nbytes), \
- }; \
- \
- /* coverity[UNINIT] */ \
- n = write (scm->socket_fd, &msgbuf, sizeof (msgbuf)); \
- if (n < sizeof (msgbuf)) \
- clib_unix_warning ("socket write (msgbuf)"); \
- \
- n = write (scm->socket_fd, scm->socket_tx_buffer, \
- scm->socket_tx_nbytes); \
- if (n < scm->socket_tx_nbytes) \
- clib_unix_warning ("socket write (msg)"); \
- } \
+ socket_client_main_t *scm = vam->socket_client_main; \
+ if (scm && scm->socket_enable) \
+ vl_socket_client_write (); \
else \
vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp); \
} while (0);
@@ -102,10 +76,11 @@ do { \
#define W(ret) \
do { \
f64 timeout = vat_time_now (vam) + 1.0; \
- socket_client_main_t *scm = &vam->socket_client_main; \
+ socket_client_main_t *scm = vam->socket_client_main; \
ret = -99; \
\
- vl_socket_client_read_reply (scm); \
+ if (scm && scm->socket_enable) \
+ vl_socket_client_read (5); \
while (vat_time_now (vam) < timeout) { \
if (vam->result_ready == 1) { \
ret = vam->retval; \
@@ -119,10 +94,11 @@ do { \
#define W2(ret, body) \
do { \
f64 timeout = vat_time_now (vam) + 1.0; \
- socket_client_main_t *scm = &vam->socket_client_main; \
+ socket_client_main_t *scm = vam->socket_client_main; \
ret = -99; \
\
- vl_socket_client_read_reply (scm); \
+ if (scm && scm->socket_enable) \
+ vl_socket_client_read (5); \
while (vat_time_now (vam) < timeout) { \
if (vam->result_ready == 1) { \
(body); \
diff --git a/src/vlibmemory/api_common.h b/src/vlibmemory/api_common.h
index 2080a4bb18e..bd0da10d569 100644
--- a/src/vlibmemory/api_common.h
+++ b/src/vlibmemory/api_common.h
@@ -43,6 +43,24 @@ typedef struct ring_alloc_
u32 misses;
} ring_alloc_t;
+typedef enum
+{
+ VL_API_VLIB_RING,
+ VL_API_CLIENT_RING,
+ VL_API_QUEUE
+} vl_api_shm_config_type_t;
+
+typedef struct vl_api_ring_config_
+{
+ u8 type;
+ u8 _pad;
+ u16 count;
+ u32 size;
+} vl_api_shm_elem_config_t;
+
+STATIC_ASSERT (sizeof (vl_api_shm_elem_config_t) == 8,
+ "Size must be exactly 8 bytes");
+
/*
* Initializers for the (shared-memory) rings
* _(size, n). Note: each msg has space for a header.
@@ -129,8 +147,8 @@ u16 vl_client_get_first_plugin_msg_id (const char *plugin_name);
void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
u32 vl_api_memclnt_create_internal (char *, unix_shared_memory_queue_t *);
-void vl_init_shmem (svm_region_t * vlib_rp, int is_vlib,
- int is_private_region);
+void vl_init_shmem (svm_region_t * vlib_rp, vl_api_shm_elem_config_t * config,
+ int is_vlib, int is_private_region);
void vl_client_install_client_message_handlers (void);
void vl_api_send_pending_rpc_requests (vlib_main_t * vm);
@@ -197,6 +215,9 @@ typedef struct
u8 *socket_rx_buffer;
u32 socket_tx_nbytes;
int control_pings_outstanding;
+
+ u8 *name;
+ clib_time_t clib_time;
} socket_client_main_t;
extern socket_client_main_t socket_client_main;
@@ -226,11 +247,14 @@ vl_api_registration_t *sockclnt_get_registration (u32 index);
void vl_api_socket_process_msg (clib_file_t * uf, vl_api_registration_t * rp,
i8 * input_v);
-int
-vl_socket_client_connect (socket_client_main_t * scm, char *socket_path,
- char *client_name, u32 socket_buffer_size);
-void vl_socket_client_read_reply (socket_client_main_t * scm);
-void vl_socket_client_enable_disable (socket_client_main_t * scm, int enable);
+int vl_socket_client_connect (char *socket_path, char *client_name,
+ u32 socket_buffer_size);
+int vl_socket_client_init_shm (vl_api_shm_elem_config_t * config);
+void vl_socket_client_disconnect (void);
+int vl_socket_client_read (int wait);
+int vl_socket_client_write (void);
+void vl_socket_client_enable_disable (int enable);
+void *vl_socket_client_msg_alloc (int nbytes);
#endif /* included_vlibmemory_api_common_h */
diff --git a/src/vlibmemory/memclnt.api b/src/vlibmemory/memclnt.api
index 6d6a1fe06dc..20a73f2b3c2 100644
--- a/src/vlibmemory/memclnt.api
+++ b/src/vlibmemory/memclnt.api
@@ -184,6 +184,23 @@ define memfd_segment_create_reply
};
/*
+ * Initialize shm api over socket api
+ */
+define sock_init_shm {
+ u32 client_index;
+ u32 context;
+ u32 requested_size;
+ u8 nitems;
+ u64 configs[nitems];
+};
+
+define sock_init_shm_reply {
+ u32 client_index;
+ u32 context;
+ i32 retval;
+};
+
+/*
* Memory client ping / response
* Only sent on inactive connections
*/
diff --git a/src/vlibmemory/memory_shared.c b/src/vlibmemory/memory_shared.c
index 7af2433b44e..0a3c23cbb3e 100644
--- a/src/vlibmemory/memory_shared.c
+++ b/src/vlibmemory/memory_shared.c
@@ -364,21 +364,11 @@ vl_set_api_pvt_heap_size (u64 size)
am->api_pvt_heap_size = size;
}
-void
-vl_init_shmem (svm_region_t * vlib_rp, int is_vlib, int is_private_region)
+static void
+vl_api_default_mem_config (vl_shmem_hdr_t * shmem_hdr)
{
api_main_t *am = &api_main;
- vl_shmem_hdr_t *shmem_hdr = 0;
u32 vlib_input_queue_length;
- void *oldheap;
- ASSERT (vlib_rp);
-
- /* $$$$ need private region config parameters */
-
- oldheap = svm_push_data_heap (vlib_rp);
-
- vec_validate (shmem_hdr, 0);
- shmem_hdr->version = VL_SHM_VERSION;
/* vlib main input queue */
vlib_input_queue_length = 1024;
@@ -389,7 +379,6 @@ vl_init_shmem (svm_region_t * vlib_rp, int is_vlib, int is_private_region)
unix_shared_memory_queue_init (vlib_input_queue_length, sizeof (uword),
getpid (), am->vlib_signal);
- /* Set up the msg ring allocator */
#define _(sz,n) \
do { \
ring_alloc_t _rp; \
@@ -417,6 +406,70 @@ vl_init_shmem (svm_region_t * vlib_rp, int is_vlib, int is_private_region)
foreach_clnt_aring_size;
#undef _
+}
+
+void
+vl_api_mem_config (vl_shmem_hdr_t * hdr, vl_api_shm_elem_config_t * config)
+{
+ api_main_t *am = &api_main;
+ vl_api_shm_elem_config_t *c;
+ ring_alloc_t *rp;
+ u32 size;
+
+ if (!config)
+ {
+ vl_api_default_mem_config (hdr);
+ return;
+ }
+
+ vec_foreach (c, config)
+ {
+ switch (c->type)
+ {
+ case VL_API_QUEUE:
+ hdr->vl_input_queue = unix_shared_memory_queue_init (c->count,
+ c->size,
+ getpid (),
+ am->vlib_signal);
+ continue;
+ case VL_API_VLIB_RING:
+ vec_add2 (hdr->vl_rings, rp, 1);
+ break;
+ case VL_API_CLIENT_RING:
+ vec_add2 (hdr->client_rings, rp, 1);
+ break;
+ default:
+ clib_warning ("unknown config type: %d", c->type);
+ continue;
+ }
+
+ size = sizeof (ring_alloc_t) + c->size;
+ rp->rp = unix_shared_memory_queue_init (c->count, size, 0, 0);
+ rp->size = size;
+ rp->nitems = c->count;
+ rp->hits = 0;
+ rp->misses = 0;
+ }
+}
+
+void
+vl_init_shmem (svm_region_t * vlib_rp, vl_api_shm_elem_config_t * config,
+ int is_vlib, int is_private_region)
+{
+ api_main_t *am = &api_main;
+ vl_shmem_hdr_t *shmem_hdr = 0;
+ void *oldheap;
+ ASSERT (vlib_rp);
+
+ /* $$$$ need private region config parameters */
+
+ oldheap = svm_push_data_heap (vlib_rp);
+
+ vec_validate (shmem_hdr, 0);
+ shmem_hdr->version = VL_SHM_VERSION;
+
+ /* Set up the queue and msg ring allocator */
+ vl_api_mem_config (shmem_hdr, config);
if (is_private_region == 0)
{
@@ -581,7 +634,8 @@ vl_map_shmem (const char *region_name, int is_vlib)
}
/* Nope, it's our problem... */
- vl_init_shmem (vlib_rp, 1 /* is vlib */ , 0 /* is_private_region */ );
+ vl_init_shmem (vlib_rp, 0 /* default config */ , 1 /* is vlib */ ,
+ 0 /* is_private_region */ );
vec_add1 (am->mapped_shmem_regions, vlib_rp);
return 0;
diff --git a/src/vlibmemory/memory_vlib.c b/src/vlibmemory/memory_vlib.c
index 1c099ed0a3e..805438152ce 100644
--- a/src/vlibmemory/memory_vlib.c
+++ b/src/vlibmemory/memory_vlib.c
@@ -1426,7 +1426,7 @@ vl_api_client_command (vlib_main_t * vm,
if (!pool_elts (am->vl_clients))
goto socket_clients;
vlib_cli_output (vm, "Shared memory clients");
- vlib_cli_output (vm, "%16s %8s %14s %18s %s",
+ vlib_cli_output (vm, "%20s %8s %14s %18s %s",
"Name", "PID", "Queue Length", "Queue VA", "Health");
/* *INDENT-OFF* */
@@ -1443,7 +1443,7 @@ vl_api_client_command (vlib_main_t * vm,
q = regp->vl_input_queue;
- vlib_cli_output (vm, "%16s %8d %14d 0x%016llx %s\n",
+ vlib_cli_output (vm, "%20s %8d %14d 0x%016llx %s\n",
regp->name, q->consumer_pid, q->cursize,
q, health);
}
diff --git a/src/vlibmemory/socket_client.c b/src/vlibmemory/socket_client.c
index b60fd4f6229..d7a9ad5fe86 100644
--- a/src/vlibmemory/socket_client.c
+++ b/src/vlibmemory/socket_client.c
@@ -21,6 +21,8 @@
#include <stdlib.h>
#include <setjmp.h>
#include <sys/types.h>
+#define __USE_GNU
+#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <netinet/in.h>
@@ -43,6 +45,7 @@
#include <vlib/vlib.h>
#include <vlib/unix/unix.h>
+#include <svm/memfd.h>
#include <vlibmemory/api.h>
#include <vlibmemory/vl_memory_msg_enum.h>
@@ -65,22 +68,26 @@ socket_client_main_t socket_client_main;
/* Debug aid */
u32 vl (void *p) __attribute__ ((weak));
+
u32
vl (void *p)
{
return vec_len (p);
}
-void
-vl_socket_client_read_reply (socket_client_main_t * scm)
+int
+vl_socket_client_read (int wait)
{
+ socket_client_main_t *scm = &socket_client_main;
int n, current_rx_index;
- msgbuf_t *mbp;
+ msgbuf_t *mbp = 0;
+ f64 timeout;
- if (scm->socket_fd == 0 || scm->socket_enable == 0)
- return;
+ if (scm->socket_fd == 0)
+ return -1;
- mbp = 0;
+ if (wait)
+ timeout = clib_time_now (&scm->clib_time) + wait;
while (1)
{
@@ -96,7 +103,7 @@ vl_socket_client_read_reply (socket_client_main_t * scm)
if (n < 0)
{
clib_unix_warning ("socket_read");
- return;
+ return -1;
}
_vec_len (scm->socket_rx_buffer) += n;
}
@@ -127,20 +134,207 @@ vl_socket_client_read_reply (socket_client_main_t * scm)
&& scm->control_pings_outstanding == 0)
break;
}
+
+ if (wait && clib_time_now (&scm->clib_time) >= timeout)
+ return -1;
+ }
+ return 0;
+}
+
+int
+vl_socket_client_write (void)
+{
+ socket_client_main_t *scm = &socket_client_main;
+ int n;
+
+ msgbuf_t msgbuf = {
+ .q = 0,
+ .gc_mark_timestamp = 0,
+ .data_len = htonl (scm->socket_tx_nbytes),
+ };
+
+ n = write (scm->socket_fd, &msgbuf, sizeof (msgbuf));
+ if (n < sizeof (msgbuf))
+ {
+ clib_unix_warning ("socket write (msgbuf)");
+ return -1;
+ }
+
+ n = write (scm->socket_fd, scm->socket_tx_buffer, scm->socket_tx_nbytes);
+ if (n < scm->socket_tx_nbytes)
+ {
+ clib_unix_warning ("socket write (msg)");
+ return -1;
+ }
+
+ return n;
+}
+
+void *
+vl_socket_client_msg_alloc (int nbytes)
+{
+ socket_client_main.socket_tx_nbytes = nbytes;
+ return ((void *) socket_client_main.socket_tx_buffer);
+}
+
+void
+vl_socket_client_disconnect (void)
+{
+ socket_client_main_t *scm = &socket_client_main;
+ if (scm->socket_fd && (close (scm->socket_fd) < 0))
+ clib_unix_warning ("close");
+ scm->socket_fd = 0;
+}
+
+void
+vl_socket_client_enable_disable (int enable)
+{
+ socket_client_main_t *scm = &socket_client_main;
+ scm->socket_enable = enable;
+}
+
+static clib_error_t *
+receive_fd_msg (int socket_fd, int *my_fd)
+{
+ char msgbuf[16];
+ char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
+ struct msghdr mh = { 0 };
+ struct iovec iov[1];
+ ssize_t size;
+ struct ucred *cr = 0;
+ struct cmsghdr *cmsg;
+ pid_t pid __attribute__ ((unused));
+ uid_t uid __attribute__ ((unused));
+ gid_t gid __attribute__ ((unused));
+
+ iov[0].iov_base = msgbuf;
+ iov[0].iov_len = 5;
+ mh.msg_iov = iov;
+ mh.msg_iovlen = 1;
+ mh.msg_control = ctl;
+ mh.msg_controllen = sizeof (ctl);
+
+ memset (ctl, 0, sizeof (ctl));
+
+ /* receive the incoming message */
+ size = recvmsg (socket_fd, &mh, 0);
+ if (size != 5)
+ {
+ return (size == 0) ? clib_error_return (0, "disconnected") :
+ clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
+ socket_fd);
+ }
+
+ cmsg = CMSG_FIRSTHDR (&mh);
+ while (cmsg)
+ {
+ if (cmsg->cmsg_level == SOL_SOCKET)
+ {
+ if (cmsg->cmsg_type == SCM_CREDENTIALS)
+ {
+ cr = (struct ucred *) CMSG_DATA (cmsg);
+ uid = cr->uid;
+ gid = cr->gid;
+ pid = cr->pid;
+ }
+ else if (cmsg->cmsg_type == SCM_RIGHTS)
+ {
+ clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
+ }
+ }
+ cmsg = CMSG_NXTHDR (&mh, cmsg);
+ }
+ return 0;
+}
+
+static void vl_api_sock_init_shm_reply_t_handler
+ (vl_api_sock_init_shm_reply_t * mp)
+{
+ socket_client_main_t *scm = &socket_client_main;
+ int my_fd = -1;
+ clib_error_t *error;
+ i32 retval = ntohl (mp->retval);
+ memfd_private_t memfd;
+ api_main_t *am = &api_main;
+ u8 *new_name;
+
+ if (retval)
+ {
+ clib_warning ("failed to init shmem");
+ return;
+ }
+
+ /*
+ * Check the socket for the magic fd
+ */
+ error = receive_fd_msg (scm->socket_fd, &my_fd);
+ if (error)
+ {
+ retval = -99;
+ return;
}
+
+ memset (&memfd, 0, sizeof (memfd));
+ memfd.fd = my_fd;
+
+ /* Note: this closes memfd.fd */
+ retval = memfd_slave_init (&memfd);
+ if (retval)
+ clib_warning ("WARNING: segment map returned %d", retval);
+
+ /*
+ * Pivot to the memory client segment that vpp just created
+ */
+ am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
+ am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
+
+ new_name = format (0, "%v[shm]%c", scm->name, 0);
+ vl_client_install_client_message_handlers ();
+ vl_client_connect_to_vlib_no_map ("pvt", (char *) new_name,
+ 32 /* input_queue_length */ );
+ vl_socket_client_enable_disable (0);
+ vec_free (new_name);
+}
+
+static void
+vl_api_sockclnt_create_reply_t_handler (vl_api_sockclnt_create_reply_t * mp)
+{
+ socket_client_main_t *scm = &socket_client_main;
+ if (!mp->response)
+ scm->socket_enable = 1;
+}
+
+#define foreach_sock_client_api_msg \
+_(SOCKCLNT_CREATE_REPLY, sockclnt_create_reply) \
+_(SOCK_INIT_SHM_REPLY, sock_init_shm_reply) \
+
+static void
+noop_handler (void *notused)
+{
+}
+
+void
+vl_sock_client_install_message_handlers (void)
+{
+
+#define _(N,n) \
+ vl_msg_api_set_handlers(VL_API_##N, #n, \
+ vl_api_##n##_t_handler, \
+ noop_handler, \
+ vl_api_##n##_t_endian, \
+ vl_api_##n##_t_print, \
+ sizeof(vl_api_##n##_t), 1);
+ foreach_sock_client_api_msg;
+#undef _
}
int
-vl_socket_client_connect (socket_client_main_t * scm, char *socket_path,
- char *client_name, u32 socket_buffer_size)
+vl_socket_client_connect (char *socket_path, char *client_name,
+ u32 socket_buffer_size)
{
- char buffer[256];
- char *rdptr;
- int n, total_bytes;
- vl_api_sockclnt_create_reply_t *rp;
+ socket_client_main_t *scm = &socket_client_main;
vl_api_sockclnt_create_t *mp;
- clib_socket_t *sock = &scm->client_socket;
- msgbuf_t *mbp;
+ clib_socket_t *sock;
clib_error_t *error;
/* Already connected? */
@@ -151,84 +345,74 @@ vl_socket_client_connect (socket_client_main_t * scm, char *socket_path,
if (socket_path == 0 || client_name == 0)
return (-3);
+ sock = &scm->client_socket;
sock->config = socket_path;
sock->flags = CLIB_SOCKET_F_IS_CLIENT | CLIB_SOCKET_F_SEQPACKET;
- error = clib_socket_init (sock);
-
- if (error)
+ if ((error = clib_socket_init (sock)))
{
clib_error_report (error);
return (-1);
}
- scm->socket_fd = sock->fd;
+ vl_sock_client_install_message_handlers ();
- mbp = (msgbuf_t *) buffer;
- mbp->q = 0;
- mbp->data_len = htonl (sizeof (*mp));
- mbp->gc_mark_timestamp = 0;
+ scm->socket_fd = sock->fd;
+ scm->socket_buffer_size = socket_buffer_size ? socket_buffer_size :
+ SOCKET_CLIENT_DEFAULT_BUFFER_SIZE;
+ vec_validate (scm->socket_tx_buffer, scm->socket_buffer_size - 1);
+ vec_validate (scm->socket_rx_buffer, scm->socket_buffer_size - 1);
+ _vec_len (scm->socket_rx_buffer) = 0;
+ _vec_len (scm->socket_tx_buffer) = 0;
+ scm->name = format (0, "%s", client_name);
- mp = (vl_api_sockclnt_create_t *) mbp->data;
+ mp = vl_socket_client_msg_alloc (sizeof (*mp));
mp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE);
strncpy ((char *) mp->name, client_name, sizeof (mp->name) - 1);
mp->name[sizeof (mp->name) - 1] = 0;
mp->context = 0xfeedface;
- n = write (scm->socket_fd, mbp, sizeof (*mbp) + sizeof (*mp));
- if (n < 0)
- {
- clib_unix_warning ("socket write (msg)");
- return (-1);
- }
+ if (vl_socket_client_write () <= 0)
+ return (-1);
- memset (buffer, 0, sizeof (buffer));
+ if (vl_socket_client_read (1))
+ return (-1);
- total_bytes = 0;
- rdptr = buffer;
- do
+ clib_time_init (&scm->clib_time);
+ return (0);
+}
+
+int
+vl_socket_client_init_shm (vl_api_shm_elem_config_t * config)
+{
+ vl_api_sock_init_shm_t *mp;
+ int rv, i;
+ u64 *cfg;
+
+ mp = vl_socket_client_msg_alloc (sizeof (*mp) +
+ vec_len (config) * sizeof (u64));
+ memset (mp, 0, sizeof (*mp));
+ mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_SOCK_INIT_SHM);
+ mp->client_index = ~0;
+ mp->requested_size = 64 << 20;
+
+ if (config)
{
- n = read (scm->socket_fd, rdptr, sizeof (buffer) - (rdptr - buffer));
- if (n < 0)
+ for (i = 0; i < vec_len (config); i++)
{
- clib_unix_warning ("socket read");
+ cfg = (u64 *) & config[i];
+ mp->configs[i] = *cfg;
}
- total_bytes += n;
- rdptr += n;
- }
- while (total_bytes < sizeof (vl_api_sockclnt_create_reply_t)
- + sizeof (msgbuf_t));
-
- rp = (vl_api_sockclnt_create_reply_t *) (buffer + sizeof (msgbuf_t));
- if (ntohs (rp->_vl_msg_id) != VL_API_SOCKCLNT_CREATE_REPLY)
- {
- clib_warning ("connect reply got msg id %d\n", ntohs (rp->_vl_msg_id));
- return (-1);
+ mp->nitems = vec_len (config);
}
+ rv = vl_socket_client_write ();
+ if (rv <= 0)
+ return rv;
- /* allocate tx, rx buffers */
- scm->socket_buffer_size = socket_buffer_size ? socket_buffer_size :
- SOCKET_CLIENT_DEFAULT_BUFFER_SIZE;
- vec_validate (scm->socket_tx_buffer, scm->socket_buffer_size - 1);
- vec_validate (scm->socket_rx_buffer, scm->socket_buffer_size - 1);
- _vec_len (scm->socket_rx_buffer) = 0;
- scm->socket_enable = 1;
+ if (vl_socket_client_read (1))
+ return -1;
- return (0);
-}
-
-void
-vl_socket_client_disconnect (socket_client_main_t * scm)
-{
- if (scm->socket_fd && (close (scm->socket_fd) < 0))
- clib_unix_warning ("close");
- scm->socket_fd = 0;
-}
-
-void
-vl_socket_client_enable_disable (socket_client_main_t * scm, int enable)
-{
- scm->socket_enable = enable;
+ return 0;
}
/*
diff --git a/src/vlibmemory/socksvr_vlib.c b/src/vlibmemory/socksvr_vlib.c
index 1a263e7bf37..314e2eb60d3 100644
--- a/src/vlibmemory/socksvr_vlib.c
+++ b/src/vlibmemory/socksvr_vlib.c
@@ -62,13 +62,13 @@ dump_socket_clients (vlib_main_t * vm, api_main_t * am)
return;
vlib_cli_output (vm, "Socket clients");
- vlib_cli_output (vm, "%16s %8s", "Name", "Fildesc");
+ vlib_cli_output (vm, "%20s %8s", "Name", "Fildesc");
/* *INDENT-OFF* */
pool_foreach (reg, sm->registration_pool,
({
if (reg->registration_type == REGISTRATION_TYPE_SOCKET_SERVER) {
f = pool_elt_at_index (fm->file_pool, reg->clib_file_index);
- vlib_cli_output (vm, "%16s %8d",
+ vlib_cli_output (vm, "%20s %8d",
reg->name, f->file_descriptor);
}
}));
@@ -78,13 +78,15 @@ dump_socket_clients (vlib_main_t * vm, api_main_t * am)
void
vl_socket_api_send (vl_api_registration_t * rp, u8 * elem)
{
- u16 msg_id = ntohs (*(u16 *) elem);
- api_main_t *am = &api_main;
- msgbuf_t *mb = (msgbuf_t *) (elem - offsetof (msgbuf_t, data));
#if CLIB_DEBUG > 1
u32 output_length;
#endif
- clib_file_t *cf = rp->clib_file_index + file_main.file_pool;
+ socket_main_t *sm = &socket_main;
+ u16 msg_id = ntohs (*(u16 *) elem);
+ api_main_t *am = &api_main;
+ msgbuf_t *mb = (msgbuf_t *) (elem - offsetof (msgbuf_t, data));
+ clib_file_t *cf = clib_file_get (&file_main, rp->clib_file_index);
+ vl_api_registration_t *sock_rp;
ASSERT (rp->registration_type > REGISTRATION_TYPE_SHMEM);
@@ -95,16 +97,15 @@ vl_socket_api_send (vl_api_registration_t * rp, u8 * elem)
return;
}
+ sock_rp = pool_elt_at_index (sm->registration_pool,
+ rp->vl_api_registration_pool_index);
+ ASSERT (sock_rp);
+
/* Add the msgbuf_t to the output vector */
- vl_socket_add_pending_output_no_flush (cf,
- rp->vl_api_registration_pool_index +
- socket_main.registration_pool,
- (u8 *) mb, sizeof (*mb));
+ vl_socket_add_pending_output_no_flush (cf, sock_rp, (u8 *) mb,
+ sizeof (*mb));
/* Send the message */
- vl_socket_add_pending_output (cf,
- rp->vl_api_registration_pool_index
- + socket_main.registration_pool,
- elem, ntohl (mb->data_len));
+ vl_socket_add_pending_output (cf, sock_rp, elem, ntohl (mb->data_len));
#if CLIB_DEBUG > 1
output_length = sizeof (*mb) + ntohl (mb->data_len);
@@ -318,7 +319,6 @@ vl_socket_write_ready (clib_file_t * uf)
/* Flush output vector. */
n = write (uf->file_descriptor,
rp->output_vector, vec_len (rp->output_vector));
-
if (n < 0)
{
#if DEBUG > 2
@@ -402,7 +402,7 @@ vl_api_sockclnt_create_t_handler (vl_api_sockclnt_create_t * mp)
{
vl_api_registration_t *regp;
vl_api_sockclnt_create_reply_t *rp;
- int rv = 1;
+ int rv = 0;
regp = socket_main.current_rp;
@@ -480,54 +480,93 @@ send_fd_msg (int socket_fd, int fd_to_share)
return 0;
}
+vl_api_shm_elem_config_t *
+vl_api_make_shm_config (vl_api_sock_init_shm_t * mp)
+{
+ vl_api_shm_elem_config_t *config = 0, *c;
+ u64 cfg;
+ int i;
+
+ if (!mp->nitems)
+ {
+ vec_validate (config, 3);
+ config[0].type = VL_API_VLIB_RING;
+ config[0].count = 128;
+ config[0].size = 256;
+ config[1].type = VL_API_CLIENT_RING;
+ config[1].count = 128;
+ config[1].size = 1024;
+ config[2].type = VL_API_CLIENT_RING;
+ config[2].count = 8;
+ config[2].size = 4096;
+ config[3].type = VL_API_QUEUE;
+ config[3].count = 128;
+ config[3].size = sizeof (uword);
+ }
+ else
+ {
+ vec_validate (config, mp->nitems - 1);
+ for (i = 0; i < mp->nitems; i++)
+ {
+ cfg = mp->configs[i];
+ /* Pretty much a hack but it avoids defining our own api type
+ * in memclnt.api */
+ c = (vl_api_shm_elem_config_t *) & cfg;
+ config[i].type = c->type;
+ config[i].count = c->count;
+ config[i].size = c->size;
+ }
+ }
+ return config;
+}
+
/*
- * Create a memory-fd segment.
+ * Bootstrap shm api using the socket api
*/
void
-vl_api_memfd_segment_create_t_handler (vl_api_memfd_segment_create_t * mp)
+vl_api_sock_init_shm_t_handler (vl_api_sock_init_shm_t * mp)
{
- vl_api_memfd_segment_create_reply_t *rmp;
- api_main_t *am = &api_main;
- clib_file_t *cf;
+ vl_api_sock_init_shm_reply_t *rmp;
memfd_private_t _memfd_private, *memfd = &_memfd_private;
- vl_api_registration_t *regp;
- vlib_main_t *vm = vlib_get_main ();
svm_map_region_args_t _args, *a = &_args;
+ vl_api_registration_t *regp;
+ api_main_t *am = &api_main;
svm_region_t *vlib_rp;
+ clib_file_t *cf;
+ vl_api_shm_elem_config_t *config = 0;
int rv;
regp = vl_api_client_index_to_registration (mp->client_index);
-
if (regp == 0)
{
clib_warning ("API client disconnected");
return;
}
-
if (regp->registration_type != REGISTRATION_TYPE_SOCKET_SERVER)
{
rv = -31; /* VNET_API_ERROR_INVALID_REGISTRATION */
goto reply;
}
+ /*
+ * Set up a memfd segment of the requested size wherein the
+ * shmem data structures will be initialized
+ */
memset (memfd, 0, sizeof (*memfd));
-
- /* Embed in api_main_t */
memfd->memfd_size = mp->requested_size;
memfd->requested_va = 0ULL;
memfd->i_am_master = 1;
memfd->name = format (0, "%s%c", regp->name, 0);
- /* Set up a memfd segment of the requested size */
- rv = memfd_master_init (memfd, mp->client_index);
-
- if (rv)
+ if ((rv = memfd_master_init (memfd, mp->client_index)))
goto reply;
/* Remember to close this fd when the socket connection goes away */
vec_add1 (regp->additional_fds_to_close, memfd->fd);
- /* And create a plausible svm_region in it */
+ /*
+ * Create a plausible svm_region in the memfd backed segment
+ */
memset (a, 0, sizeof (*a));
a->baseva = memfd->sh->memfd_va + MMAP_PAGESIZE;
a->size = memfd->memfd_size - MMAP_PAGESIZE;
@@ -536,24 +575,77 @@ vl_api_memfd_segment_create_t_handler (vl_api_memfd_segment_create_t * mp)
a->flags = SVM_FLAGS_MHEAP;
svm_region_init_mapped_region (a, (svm_region_t *) a->baseva);
- vlib_rp = (svm_region_t *) a->baseva;
-
/*
* Part deux, initialize the svm_region_t shared-memory header
* api allocation rings, and so on.
*/
- vl_init_shmem (vlib_rp, 1 /* is_vlib (dont-care) */ , 1 /* is_private */ );
-
+ config = vl_api_make_shm_config (mp);
+ vlib_rp = (svm_region_t *) a->baseva;
+ vl_init_shmem (vlib_rp, config, 1 /* is_vlib (dont-care) */ ,
+ 1 /* is_private */ );
vec_add1 (am->vlib_private_rps, vlib_rp);
-
memfd->sh->ready = 1;
+ vec_free (config);
/* Recompute the set of input queues to poll in memclnt_process */
vec_reset_length (vl_api_queue_cursizes);
reply:
- /* send the reply message */
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ rmp->_vl_msg_id = htons (VL_API_SOCK_INIT_SHM_REPLY);
+ rmp->context = mp->context;
+ rmp->retval = htonl (rv);
+
+ vl_msg_api_send (regp, (u8 *) rmp);
+
+ if (rv != 0)
+ return;
+
+ /*
+ * We need the reply message to make it out the back door
+ * before we send the magic fd message so force a flush
+ */
+ cf = clib_file_get (&file_main, regp->clib_file_index);
+ cf->write_function (cf);
+
+ /* Send the magic "here's your sign (aka fd)" socket message */
+ send_fd_msg (cf->file_descriptor, memfd->fd);
+}
+
+/*
+ * Create a memory-fd segment.
+ */
+void
+vl_api_memfd_segment_create_t_handler (vl_api_memfd_segment_create_t * mp)
+{
+ vl_api_memfd_segment_create_reply_t *rmp;
+ clib_file_t *cf;
+ memfd_private_t _memfd_private, *memfd = &_memfd_private;
+ vl_api_registration_t *regp;
+ int rv;
+
+ regp = vl_api_client_index_to_registration (mp->client_index);
+ if (regp == 0)
+ {
+ clib_warning ("API client disconnected");
+ return;
+ }
+
+ memset (memfd, 0, sizeof (*memfd));
+ memfd->memfd_size = mp->requested_size;
+ memfd->requested_va = 0ULL;
+ memfd->i_am_master = 1;
+ memfd->name = format (0, "%s%c", regp->name, 0);
+
+ /* Set up a memfd segment of the requested size */
+ if ((rv = memfd_master_init (memfd, mp->client_index)))
+ goto reply;
+
+ /* Remember to close this fd when the socket connection goes away */
+ vec_add1 (regp->additional_fds_to_close, memfd->fd);
+
+reply:
rmp = vl_msg_api_alloc (sizeof (*rmp));
rmp->_vl_msg_id = htons (VL_API_MEMFD_SEGMENT_CREATE_REPLY);
@@ -569,17 +661,17 @@ reply:
* We need the reply message to make it out the back door
* before we send the magic fd message.
*/
- vlib_process_suspend (vm, 11e-6);
-
cf = file_main.file_pool + regp->clib_file_index;
+ cf->write_function (cf);
/* send the magic "here's your sign (aka fd)" socket message */
send_fd_msg (cf->file_descriptor, memfd->fd);
}
-#define foreach_vlib_api_msg \
-_(SOCKCLNT_CREATE, sockclnt_create) \
-_(SOCKCLNT_DELETE, sockclnt_delete) \
+#define foreach_vlib_api_msg \
+_(SOCKCLNT_CREATE, sockclnt_create) \
+_(SOCKCLNT_DELETE, sockclnt_delete) \
+_(SOCK_INIT_SHM, sock_init_shm) \
_(MEMFD_SEGMENT_CREATE, memfd_segment_create)
clib_error_t *
@@ -588,8 +680,6 @@ socksvr_api_init (vlib_main_t * vm)
clib_file_main_t *fm = &file_main;
clib_file_t template = { 0 };
vl_api_registration_t *rp;
- vl_msg_api_msg_config_t cfg;
- vl_msg_api_msg_config_t *c = &cfg;
socket_main_t *sm = &socket_main;
clib_socket_t *sock = &sm->socksvr_listen_socket;
clib_error_t *error;
@@ -598,19 +688,13 @@ socksvr_api_init (vlib_main_t * vm)
if (sm->socket_name == 0)
return 0;
-#define _(N,n) do { \
- c->id = VL_API_##N; \
- c->name = #n; \
- c->handler = vl_api_##n##_t_handler; \
- c->cleanup = vl_noop_handler; \
- c->endian = vl_api_##n##_t_endian; \
- c->print = vl_api_##n##_t_print; \
- c->size = sizeof(vl_api_##n##_t); \
- c->traced = 1; /* trace, so these msgs print */ \
- c->replay = 0; /* don't replay client create/delete msgs */ \
- c->message_bounce = 0; /* don't bounce this message */ \
- vl_msg_api_config(c);} while (0);
-
+#define _(N,n) \
+ vl_msg_api_set_handlers(VL_API_##N, #n, \
+ vl_api_##n##_t_handler, \
+ vl_noop_handler, \
+ vl_api_##n##_t_endian, \
+ vl_api_##n##_t_print, \
+ sizeof(vl_api_##n##_t), 1);
foreach_vlib_api_msg;
#undef _
diff --git a/src/vnet/lisp-cp/one_api.c b/src/vnet/lisp-cp/one_api.c
index 0def13c6db9..0708bf033f9 100644
--- a/src/vnet/lisp-cp/one_api.c
+++ b/src/vnet/lisp-cp/one_api.c
@@ -1328,16 +1328,9 @@ vl_api_one_eid_table_vni_dump_t_handler (vl_api_one_eid_table_vni_dump_t * mp)
static void
vl_api_show_one_status_t_handler (vl_api_show_one_status_t * mp)
{
- unix_shared_memory_queue_t *q = NULL;
vl_api_show_one_status_reply_t *rmp = NULL;
int rv = 0;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- {
- return;
- }
-
/* *INDENT-OFF* */
REPLY_MACRO2(VL_API_SHOW_ONE_STATUS_REPLY,
({
@@ -1351,19 +1344,12 @@ static void
vl_api_one_get_map_request_itr_rlocs_t_handler
(vl_api_one_get_map_request_itr_rlocs_t * mp)
{
- unix_shared_memory_queue_t *q = NULL;
vl_api_one_get_map_request_itr_rlocs_reply_t *rmp = NULL;
lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
locator_set_t *loc_set = 0;
u8 *tmp_str = 0;
int rv = 0;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- {
- return;
- }
-
if (~0 == lcm->mreq_itr_rlocs)
{
tmp_str = format (0, " ");
diff --git a/src/vppinfra/file.h b/src/vppinfra/file.h
index 6ebf5122567..4231a39b723 100644
--- a/src/vppinfra/file.h
+++ b/src/vppinfra/file.h
@@ -122,6 +122,13 @@ clib_file_set_data_available_to_write (clib_file_main_t * um,
return was_available != 0;
}
+always_inline clib_file_t *
+clib_file_get (clib_file_main_t * fm, u32 file_index)
+{
+ if (pool_is_free_index (fm->file_pool, file_index))
+ return 0;
+ return pool_elt_at_index (fm->file_pool, file_index);
+}
#endif /* included_clib_file_h */