api: refactor api data storage
single struct to hold all api handler, flags, etc.
Provide functions to toggle flags instead of writing directly to
internal data.
Type: refactor
Change-Id: I4730d7290e57489de8eda34a72211527e015b721
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vlibmemory/memclnt_api.c b/src/vlibmemory/memclnt_api.c
index 289a4c5..9e2971a 100644
--- a/src/vlibmemory/memclnt_api.c
+++ b/src/vlibmemory/memclnt_api.c
@@ -193,8 +193,8 @@
foreach_vlib_api_msg;
#undef _
- am->is_mp_safe[VL_API_CONTROL_PING] = 1;
- am->is_mp_safe[VL_API_CONTROL_PING_REPLY] = 1;
+ vl_api_set_msg_thread_safe (am, VL_API_CONTROL_PING, 1);
+ vl_api_set_msg_thread_safe (am, VL_API_CONTROL_PING_REPLY, 1);
return 0;
}
@@ -727,10 +727,10 @@
foreach_plugin_trace_msg;
#undef _
- am->api_trace_cfg[VL_API_TRACE_PLUGIN_MSG_IDS].replay_enable = 0;
+ vl_api_allow_msg_replay (am, VL_API_TRACE_PLUGIN_MSG_IDS, 0);
/* No reason to halt the parade to create a trace record... */
- am->is_mp_safe[VL_API_TRACE_PLUGIN_MSG_IDS] = 1;
+ vl_api_set_msg_thread_safe (am, VL_API_TRACE_PLUGIN_MSG_IDS, 1);
rpc_call_main_thread_cb_fn = vl_api_rpc_call_main_thread;
return 0;
}
diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c
index ecdcc72..80d8628 100644
--- a/src/vlibmemory/memory_api.c
+++ b/src/vlibmemory/memory_api.c
@@ -532,9 +532,9 @@
* special-case freeing of memclnt_delete messages, so we can
* simply munmap pairwise / private API segments...
*/
- am->message_bounce[VL_API_MEMCLNT_DELETE] = 1;
- am->is_mp_safe[VL_API_MEMCLNT_KEEPALIVE_REPLY] = 1;
- am->is_mp_safe[VL_API_MEMCLNT_KEEPALIVE] = 1;
+ am->msg_data[VL_API_MEMCLNT_DELETE].bounce = 1;
+ vl_api_set_msg_thread_safe (am, VL_API_MEMCLNT_KEEPALIVE_REPLY, 1);
+ vl_api_set_msg_thread_safe (am, VL_API_MEMCLNT_KEEPALIVE, 1);
vlib_set_queue_signal_callback (vm, memclnt_queue_callback);
@@ -768,6 +768,7 @@
vlib_node_runtime_t *node, u8 is_private)
{
u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, id);
u8 *(*handler) (void *, void *, void *);
u8 *(*print_fp) (void *, void *);
svm_region_t *old_vlib_rp;
@@ -785,23 +786,23 @@
u32 c;
} * ed;
ed = ELOG_DATA (am->elog_main, e);
- if (id < vec_len (am->msg_names) && am->msg_names[id])
- ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
+ if (m && m->name)
+ ed->c = elog_string (am->elog_main, (char *) m->name);
else
ed->c = elog_string (am->elog_main, "BOGUS");
}
- if (id < vec_len (am->msg_handlers) && am->msg_handlers[id])
+ if (m && m->handler)
{
- handler = (void *) am->msg_handlers[id];
+ handler = (void *) m->handler;
if (PREDICT_FALSE (am->rx_trace && am->rx_trace->enabled))
vl_msg_api_trace (am, am->rx_trace, the_msg);
if (PREDICT_FALSE (am->msg_print_flag))
{
- fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]);
- print_fp = (void *) am->msg_print_handlers[id];
+ fformat (stdout, "[%d]: %s\n", id, m->name);
+ print_fp = (void *) am->msg_data[id].print_handler;
if (print_fp == 0)
{
fformat (stdout, " [no registered print fn for msg %d]\n", id);
@@ -811,11 +812,11 @@
(*print_fp) (the_msg, vm);
}
}
- is_mp_safe = am->is_mp_safe[id];
+ is_mp_safe = am->msg_data[id].is_mp_safe;
if (!is_mp_safe)
{
- vl_msg_api_barrier_trace_context (am->msg_names[id]);
+ vl_msg_api_barrier_trace_context (am->msg_data[id].name);
vl_msg_api_barrier_sync ();
}
if (is_private)
@@ -829,10 +830,10 @@
if (PREDICT_FALSE (vl_mem_api_fuzz_hook != 0))
(*vl_mem_api_fuzz_hook) (id, the_msg);
- if (am->is_autoendian[id])
+ if (m->is_autoendian)
{
void (*endian_fp) (void *);
- endian_fp = am->msg_endian_handlers[id];
+ endian_fp = am->msg_data[id].endian_handler;
(*endian_fp) (the_msg);
}
if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0))
@@ -859,7 +860,7 @@
* Special-case, so we can e.g. bounce messages off the vnet
* main thread without copying them...
*/
- if (id >= vec_len (am->message_bounce) || !(am->message_bounce[id]))
+ if (!m || !m->bounce)
{
if (is_private)
{
@@ -892,8 +893,8 @@
u32 c;
} * ed;
ed = ELOG_DATA (am->elog_main, e);
- if (id < vec_len (am->msg_names) && am->msg_names[id])
- ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
+ if (m && m->name)
+ ed->c = elog_string (am->elog_main, (char *) m->name);
else
ed->c = elog_string (am->elog_main, "BOGUS");
ed->barrier = is_mp_safe;
diff --git a/src/vlibmemory/memory_client.c b/src/vlibmemory/memory_client.c
index 585fca6..330390e 100644
--- a/src/vlibmemory/memory_client.c
+++ b/src/vlibmemory/memory_client.c
@@ -377,7 +377,7 @@
vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); \
- am->api_trace_cfg[VL_API_##N].replay_enable = 0;
+ am->msg_data[VL_API_##N].replay_allowed = 0;
foreach_api_msg;
#undef _
}
@@ -562,6 +562,8 @@
vl_api_get_first_msg_id_t *mp;
api_main_t *am = vlibapi_get_main ();
memory_client_main_t *mm = vlibapi_get_memory_client_main ();
+ vl_api_msg_data_t *m =
+ vl_api_get_msg_data (am, VL_API_GET_FIRST_MSG_ID_REPLY);
f64 timeout;
void *old_handler;
clib_time_t clib_time;
@@ -574,12 +576,11 @@
clib_time_init (&clib_time);
/* Push this plugin's first_msg_id_reply handler */
- old_handler = am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY];
- am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = (void *)
- vl_api_get_first_msg_id_reply_t_handler;
- if (!am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY])
+ old_handler = m->handler;
+ m->handler = (void *) vl_api_get_first_msg_id_reply_t_handler;
+ if (!m->calc_size_func)
{
- am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY] =
+ m->calc_size_func =
(uword (*) (void *)) vl_api_get_first_msg_id_reply_t_calc_size;
}
@@ -608,7 +609,7 @@
sock_err:
/* Restore old handler */
- am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;
+ m->handler = old_handler;
return -1;
}
@@ -633,7 +634,7 @@
}
}
/* Restore old handler */
- am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;
+ m->handler = old_handler;
return rv;
}
@@ -641,7 +642,7 @@
result:
/* Restore the old handler */
- am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;
+ m->handler = old_handler;
if (rv == (u16) ~ 0)
clib_warning ("plugin '%s' not registered", plugin_name);
diff --git a/src/vlibmemory/memory_shared.c b/src/vlibmemory/memory_shared.c
index b70f45f..77a610b 100644
--- a/src/vlibmemory/memory_shared.c
+++ b/src/vlibmemory/memory_shared.c
@@ -117,14 +117,16 @@
if (CLIB_DEBUG > 0)
{
u16 *msg_idp, msg_id;
+ vl_api_msg_data_t *m;
clib_warning
("garbage collect pool %d ring %d index %d", pool, i,
q->head);
msg_idp = (u16 *) (rv->data);
msg_id = clib_net_to_host_u16 (*msg_idp);
- if (msg_id < vec_len (vlibapi_get_main ()->msg_names))
+ m = vl_api_get_msg_data (am, msg_id);
+ if (m)
clib_warning ("msg id %d name %s", (u32) msg_id,
- vlibapi_get_main ()->msg_names[msg_id]);
+ m->name);
}
shmem_hdr->garbage_collects++;
goto collected;
@@ -731,10 +733,7 @@
is_client ? svm_region_exit_client () : svm_region_exit ();
- /* $$$ more careful cleanup, valgrind run... */
- vec_free (am->msg_handlers);
- vec_free (am->msg_endian_handlers);
- vec_free (am->msg_print_handlers);
+ vec_free (am->msg_data);
}
void
diff --git a/src/vlibmemory/socket_api.c b/src/vlibmemory/socket_api.c
index 3df182b..e451d62 100644
--- a/src/vlibmemory/socket_api.c
+++ b/src/vlibmemory/socket_api.c
@@ -132,7 +132,7 @@
cf = vl_api_registration_file (rp);
ASSERT (rp->registration_type > REGISTRATION_TYPE_SHMEM);
- if (msg_id >= vec_len (am->api_trace_cfg))
+ if (msg_id >= vec_len (am->msg_data))
{
clib_warning ("id out of range: %d", msg_id);
vl_msg_api_free ((void *) elem);
@@ -802,7 +802,7 @@
vl_api_##n##_t_endian, vl_api_##n##_t_print, sizeof (vl_api_##n##_t), t, \
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size); \
- am->api_trace_cfg[VL_API_##N].replay_enable = 0;
+ am->msg_data[VL_API_##N].replay_allowed = 0;
foreach_vlib_api_msg;
#undef _
diff --git a/src/vlibmemory/vlib_api.c b/src/vlibmemory/vlib_api.c
index b598f0b..3d4f882 100644
--- a/src/vlibmemory/vlib_api.c
+++ b/src/vlibmemory/vlib_api.c
@@ -340,7 +340,7 @@
*/
msg_id_base = setup_message_id_table ();
- am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1;
+ vl_api_set_msg_thread_safe (am, VL_API_GET_NODE_GRAPH, 1);
return 0;
}
diff --git a/src/vlibmemory/vlib_api_cli.c b/src/vlibmemory/vlib_api_cli.c
index 39e2250..084080f 100644
--- a/src/vlibmemory/vlib_api_cli.c
+++ b/src/vlibmemory/vlib_api_cli.c
@@ -242,20 +242,19 @@
vlib_cli_output (vm, "%-4s %-40s %6s %7s", "ID", "Name", "Bounce",
"MP-safe");
- for (i = 1; i < vec_len (am->msg_names); i++)
+ for (i = 1; i < vec_len (am->msg_data); i++)
{
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, i);
if (verbose == 0)
{
vlib_cli_output (vm, "%-4d %s", i,
- am->msg_names[i] ? am->msg_names[i] :
- " [no handler]");
+ m->name ? m->name : " [no handler]");
}
else
{
vlib_cli_output (vm, "%-4d %-40s %6d %7d", i,
- am->msg_names[i] ? am->msg_names[i] :
- " [no handler]", am->message_bounce[i],
- am->is_mp_safe[i]);
+ m->name ? m->name : " [no handler]", m->bounce,
+ m->is_mp_safe);
}
}
@@ -510,7 +509,7 @@
assert_size (file_size_left, clib_max (size, sizeof (u16)));
msg_id = ntohs (*((u16 *) msg));
if (msg_id >= vec_len (msgid_vec) ||
- msgid_vec[msg_id] >= vec_len (am->api_trace_cfg))
+ msgid_vec[msg_id] >= vec_len (am->msg_data))
vlib_cli_output (vm, "warning: unknown msg id %d for msg number %d\n",
msg_id, i);
@@ -522,7 +521,7 @@
for (; i <= last_index; i++)
{
- trace_cfg_t *cfgp;
+ vl_api_msg_data_t *m;
u16 msg_id;
int size;
@@ -537,7 +536,7 @@
msg_id = ntohs (*((u16 *) msg));
if (msg_id >= vec_len (msgid_vec) ||
- msgid_vec[msg_id] >= vec_len (am->api_trace_cfg))
+ msgid_vec[msg_id] >= vec_len (am->msg_data))
{
vlib_cli_output (
vm, "warning: unknown msg id %d for msg number %d, skipping\n",
@@ -547,7 +546,7 @@
}
msg_id = msgid_vec[msg_id];
- cfgp = am->api_trace_cfg + msg_id;
+ m = vl_api_get_msg_data (am, msg_id);
/* Copy the buffer (from the read-only mmap'ed file) */
vec_validate (tmpbuf, size - 1 + sizeof (uword));
@@ -561,9 +560,7 @@
if (((which == DUMP || which == DUMP_JSON) &&
clib_arch_is_little_endian))
{
- void (*endian_fp) (void *);
- if (msg_id >= vec_len (am->msg_endian_handlers)
- || (am->msg_endian_handlers[msg_id] == 0))
+ if (m && m->endian_handler == 0)
{
vlib_cli_output (vm, "Ugh: msg id %d no endian swap\n", msg_id);
munmap (hp, file_size);
@@ -571,8 +568,7 @@
am->replay_in_progress = 0;
return;
}
- endian_fp = am->msg_endian_handlers[msg_id];
- (*endian_fp) (tmpbuf + sizeof (uword));
+ m->endian_handler (tmpbuf + sizeof (uword));
}
/* msg_id always in network byte order */
@@ -585,13 +581,9 @@
switch (which)
{
case DUMP_JSON:
- if (msg_id < vec_len (am->msg_print_json_handlers) &&
- am->msg_print_json_handlers[msg_id])
+ if (m && m->print_json_handler)
{
- u8 *(*print_fp) (void *, void *);
-
- print_fp = (void *) am->msg_print_json_handlers[msg_id];
- (*print_fp) (tmpbuf + sizeof (uword), vm);
+ m->print_json_handler (tmpbuf + sizeof (uword), vm);
}
else
{
@@ -602,13 +594,9 @@
break;
case DUMP:
- if (msg_id < vec_len (am->msg_print_handlers) &&
- am->msg_print_handlers[msg_id])
+ if (m && m->print_handler)
{
- u8 *(*print_fp) (void *, void *);
-
- print_fp = (void *) am->msg_print_handlers[msg_id];
- (*print_fp) (tmpbuf + sizeof (uword), vm);
+ m->print_handler (tmpbuf + sizeof (uword), vm);
}
else
{
@@ -619,25 +607,20 @@
break;
case INITIALIZERS:
- if (msg_id < vec_len (am->msg_print_handlers) &&
- am->msg_print_handlers[msg_id])
+ if (m && m->print_handler)
{
u8 *s;
int j;
- u8 *(*print_fp) (void *, void *);
-
- print_fp = (void *) am->msg_print_handlers[msg_id];
vlib_cli_output (vm, "/*");
- (*print_fp) (tmpbuf + sizeof (uword), vm);
+ m->print_handler (tmpbuf + sizeof (uword), vm);
vlib_cli_output (vm, "*/\n");
- s = format (0, "static u8 * vl_api_%s_%d[%d] = {",
- am->msg_names[msg_id], i,
- am->api_trace_cfg[msg_id].size);
+ s = format (0, "static u8 * vl_api_%s_%d[%d] = {", m->name, i,
+ m->trace_size);
- for (j = 0; j < am->api_trace_cfg[msg_id].size; j++)
+ for (j = 0; j < m->trace_size; j++)
{
if ((j & 7) == 0)
s = format (s, "\n ");
@@ -650,22 +633,17 @@
break;
case REPLAY:
- if (msg_id < vec_len (am->msg_print_handlers) &&
- am->msg_print_handlers[msg_id] && cfgp->replay_enable)
+ if (m && m->print_handler && m->replay_allowed)
{
- void (*handler) (void *, vlib_main_t *);
-
- handler = (void *) am->msg_handlers[msg_id];
-
- if (!am->is_mp_safe[msg_id])
+ if (!m->is_mp_safe)
vl_msg_api_barrier_sync ();
- (*handler) (tmpbuf + sizeof (uword), vm);
- if (!am->is_mp_safe[msg_id])
+ m->handler (tmpbuf + sizeof (uword));
+ if (!m->is_mp_safe)
vl_msg_api_barrier_release ();
}
else
{
- if (cfgp->replay_enable)
+ if (m->replay_allowed)
vlib_cli_output (vm, "Skipping msg id %d: no handler\n",
msg_id);
break;
@@ -708,11 +686,17 @@
vl_msg_print_args *a = ctx;
api_main_t *am = vlibapi_get_main ();
u16 msg_id = ntohs (*((u16 *) msg));
- void (*print_fp) (void *, void *);
- void (**handlers) (void *, void *);
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, msg_id);
+ void (*handler) (void *, void *) = 0;
u8 is_json = a->is_json;
u8 *tmpbuf = 0;
+ if (!m)
+ {
+ vlib_cli_output (a->vm, "Unknown msg id %d\n", msg_id);
+ return 0;
+ }
+
if (clib_arch_is_little_endian)
{
u32 msg_length = vec_len (msg);
@@ -720,25 +704,15 @@
clib_memcpy_fast (tmpbuf, msg, msg_length);
msg = tmpbuf;
- void (*endian_fp) (void *);
- endian_fp = am->msg_endian_handlers[msg_id];
- (*endian_fp) (tmpbuf);
+ m->endian_handler (tmpbuf);
}
- if (is_json)
- handlers = am->msg_print_json_handlers;
- else
- handlers = am->msg_print_handlers;
+ handler = is_json ? m->print_json_handler : m->print_handler;
- if (msg_id < vec_len (handlers) && handlers[msg_id])
- {
- print_fp = (void *) handlers[msg_id];
- (*print_fp) (msg, a->vm);
- }
+ if (handler)
+ handler (msg, a->vm);
else
- {
- vlib_cli_output (a->vm, "Skipping msg id %d: no print fcn\n", msg_id);
- }
+ vlib_cli_output (a->vm, "Skipping msg id %d: no print fcn\n", msg_id);
vec_free (tmpbuf);
return 0;
@@ -825,9 +799,8 @@
{
api_main_t *am = vlibapi_get_main ();
u16 msg_id;
- void *(*fromjson) (cJSON *, int *);
int len = 0, rv = -1;
- trace_cfg_t *cfgp;
+ vl_api_msg_data_t *m;
u8 *msg = 0;
cJSON *msg_id_obj = cJSON_GetObjectItem (o, "_msgname");
@@ -849,6 +822,7 @@
u8 *name_crc = format (0, "%s_%s%c", name, crc, 0);
msg_id = vl_msg_find_id_by_name_and_crc (vm, am, (char *) name_crc);
+ m = vl_api_get_msg_data (am, msg_id);
if (msg_id == (u16) ~0)
{
msg_id = vl_msg_find_id_by_name (vm, am, name);
@@ -862,28 +836,19 @@
}
vec_free (name_crc);
- cfgp = am->api_trace_cfg + msg_id;
- if (!am->api_trace_cfg)
+ if (m->replay_allowed)
{
- vlib_cli_output (vm, "msg id %d no trace config\n", msg_id);
- return rv;
- }
-
- if (cfgp->replay_enable)
- {
-
if (proc_warning)
vlib_cli_output (vm, "warning: msg %d has different signature\n");
- fromjson = am->msg_fromjson_handlers[msg_id];
- if (!fromjson)
+ if (!m->fromjson_handler)
{
vlib_cli_output (vm, "missing fromjson convert function! id %d\n",
msg_id);
return rv;
}
- msg = (u8 *) fromjson (o, &len);
+ msg = (u8 *) m->fromjson_handler (o, &len);
if (!msg)
{
vlib_cli_output (vm, "failed to convert JSON (msg id %d)!\n",
@@ -892,24 +857,18 @@
}
if (clib_arch_is_little_endian)
- {
- void (*endian_fp) (void *);
- endian_fp = am->msg_endian_handlers[msg_id];
- (*endian_fp) (msg);
- }
+ m->endian_handler (msg);
- void (*handler) (void *, vlib_main_t *);
- handler = (void *) am->msg_handlers[msg_id];
- if (!handler)
+ if (!m->handler)
{
vlib_cli_output (vm, "no handler for msg id %d!\n", msg_id);
goto end;
}
- if (!am->is_mp_safe[msg_id])
+ if (!m->is_mp_safe)
vl_msg_api_barrier_sync ();
- (*handler) (msg, vm);
- if (!am->is_mp_safe[msg_id])
+ m->handler (msg);
+ if (!m->is_mp_safe)
vl_msg_api_barrier_release ();
}