aboutsummaryrefslogtreecommitdiffstats
path: root/src/vlibapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/vlibapi')
-rw-r--r--src/vlibapi/api.h24
-rw-r--r--src/vlibapi/api_common.h84
-rw-r--r--src/vlibapi/api_helper_macros.h2
-rw-r--r--src/vlibapi/api_shared.c156
4 files changed, 132 insertions, 134 deletions
diff --git a/src/vlibapi/api.h b/src/vlibapi/api.h
index d290301f8d4..f838a80cf71 100644
--- a/src/vlibapi/api.h
+++ b/src/vlibapi/api.h
@@ -124,6 +124,30 @@ typedef int (*vl_msg_traverse_trace_fn) (u8 *, void *);
int vl_msg_traverse_trace (vl_api_trace_t *tp, vl_msg_traverse_trace_fn fn,
void *ctx);
+always_inline void
+vl_api_increase_msg_trace_size (api_main_t *am, u32 msg_id, u32 inc)
+{
+ am->msg_data[msg_id].trace_size += inc;
+}
+
+always_inline void
+vl_api_set_msg_thread_safe (api_main_t *am, u32 msg_id, int v)
+{
+ am->msg_data[msg_id].is_mp_safe = v != 0;
+}
+
+always_inline void
+vl_api_set_msg_autoendian (api_main_t *am, u32 msg_id, int v)
+{
+ am->msg_data[msg_id].is_autoendian = v != 0;
+}
+
+always_inline void
+vl_api_allow_msg_replay (api_main_t *am, u32 msg_id, int v)
+{
+ am->msg_data[msg_id].replay_allowed = v != 0;
+}
+
#endif /* included_api_h */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vlibapi/api_common.h b/src/vlibapi/api_common.h
index 491ecb8eaef..66a547fb93d 100644
--- a/src/vlibapi/api_common.h
+++ b/src/vlibapi/api_common.h
@@ -81,14 +81,6 @@ typedef struct vl_api_registration_
#define VL_API_INVALID_FI ((u32)~0)
-/** Trace configuration for a single message */
-typedef struct
-{
- int size; /**< for sanity checking */
- int trace_enable; /**< trace this message */
- int replay_enable; /**< This message can be replayed */
-} trace_cfg_t;
-
/**
* API trace state
*/
@@ -136,11 +128,11 @@ typedef struct
void *fromjson; /**< JSON to binary convert function */
void *calc_size; /**< message size calculation */
int size; /**< message size */
- int traced; /**< is this message to be traced? */
- int replay; /**< is this message to be replayed? */
- int message_bounce; /**< do not free message after processing */
- int is_mp_safe; /**< worker thread barrier required? */
- int is_autoendian; /**< endian conversion required? */
+ int traced : 1; /**< is this message to be traced? */
+ int replay : 1; /**< is this message to be replayed? */
+ int message_bounce : 1; /**< do not free message after processing */
+ int is_mp_safe : 1; /**< worker thread barrier required? */
+ int is_autoendian : 1; /**< endian conversion required? */
} vl_msg_api_msg_config_t;
/** Message header structure */
@@ -231,47 +223,54 @@ typedef struct
char name[64];
} api_version_t;
-/** API main structure, used by both vpp and binary API clients */
-typedef struct api_main_t
+typedef struct
{
/** Message handler vector */
- void (**msg_handlers) (void *);
+ void (*handler) (void *);
/** non-default message cleanup handler vector */
- void (**msg_cleanup_handlers) (void *);
+ void (*cleanup_handler) (void *);
+
+ /** Message name vector */
+ const char *name;
+
+ /** Message convert function vector */
+ cJSON *(*tojson_handler) (void *);
+
+ /** Message convert function vector */
+ void *(*fromjson_handler) (cJSON *, int *);
/** Message endian handler vector */
- void (**msg_endian_handlers) (void *);
+ void (*endian_handler) (void *);
/** Message print function vector */
- void (**msg_print_handlers) (void *, void *);
+ void (*print_handler) (void *, void *);
/** Message print function vector in JSON */
- void (**msg_print_json_handlers) (void *, void *);
-
- /** Message convert function vector */
- cJSON *(**msg_tojson_handlers) (void *);
-
- /** Message convert function vector */
- void *(**msg_fromjson_handlers) (cJSON *, int *);
+ void (*print_json_handler) (void *, void *);
/** Message calc size function vector */
- uword (**msg_calc_size_funcs) (void *);
+ uword (*calc_size_func) (void *);
- /** Message name vector */
- const char **msg_names;
+ /** trace size for sanity checking */
+ int trace_size;
- /** API message ID by name hash table */
- uword *msg_id_by_name;
+ /** Flags */
+ u8 bounce : 1; /**> Don't automatically free message buffer vetor */
+ u8 is_mp_safe : 1; /**< Message is mp safe vector */
+ u8 is_autoendian : 1; /**< Message requires us to do endian conversion */
+ u8 trace_enable : 1; /**< trace this message */
+ u8 replay_allowed : 1; /**< This message can be replayed */
- /** Don't automatically free message buffer vetor */
- u8 *message_bounce;
+} vl_api_msg_data_t;
- /** Message is mp safe vector */
- u8 *is_mp_safe;
+/** API main structure, used by both vpp and binary API clients */
+typedef struct api_main_t
+{
+ vl_api_msg_data_t *msg_data;
- /** Message requires us to do endian conversion */
- u8 *is_autoendian;
+ /** API message ID by name hash table */
+ uword *msg_id_by_name;
/** Allocator ring vectors (in shared memory) */
struct ring_alloc_ *arings;
@@ -294,9 +293,6 @@ typedef struct api_main_t
/** Print every received message */
int msg_print_flag;
- /** Current trace configuration */
- trace_cfg_t *api_trace_cfg;
-
/** Current process PID */
int our_pid;
@@ -411,6 +407,14 @@ vlibapi_get_main (void)
return my_api_main;
}
+always_inline vl_api_msg_data_t *
+vl_api_get_msg_data (api_main_t *am, u32 msg_id)
+{
+ if (msg_id >= vec_len (am->msg_data))
+ return 0;
+ return am->msg_data + msg_id;
+}
+
always_inline void
vlibapi_set_main (api_main_t * am)
{
diff --git a/src/vlibapi/api_helper_macros.h b/src/vlibapi/api_helper_macros.h
index 6b5b37ae746..9c93d33934b 100644
--- a/src/vlibapi/api_helper_macros.h
+++ b/src/vlibapi/api_helper_macros.h
@@ -30,7 +30,7 @@
#define _NATIVE_TO_NETWORK(t, rmp) \
api_main_t *am = vlibapi_get_main (); \
void (*endian_fp) (void *); \
- endian_fp = am->msg_endian_handlers[t + (REPLY_MSG_ID_BASE)]; \
+ endian_fp = am->msg_data[t + (REPLY_MSG_ID_BASE)].endian_handler; \
(*endian_fp) (rmp);
#define REPLY_MACRO(msg) \
diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c
index 17560e5de23..98da604a456 100644
--- a/src/vlibapi/api_shared.c
+++ b/src/vlibapi/api_shared.c
@@ -79,13 +79,11 @@ vl_msg_api_trace (api_main_t * am, vl_api_trace_t * tp, void *msg)
u8 **old_trace;
u8 *msg_copy;
u32 length;
- trace_cfg_t *cfgp;
u16 msg_id = clib_net_to_host_u16 (*((u16 *) msg));
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, msg_id);
msgbuf_t *header = (msgbuf_t *) (((u8 *) msg) - offsetof (msgbuf_t, data));
- cfgp = am->api_trace_cfg + msg_id;
-
- if (!cfgp || !cfgp->trace_enable)
+ if (!m || !m->trace_enable)
return;
msg_copy = 0;
@@ -227,21 +225,18 @@ vl_msg_api_trace_write_one (api_main_t *am, u8 *msg, FILE *fp)
{
u8 *tmpmem = 0;
int tlen, slen;
- cJSON *(*tojson_fn) (void *);
u32 msg_length = vec_len (msg);
vec_validate (tmpmem, msg_length - 1);
clib_memcpy_fast (tmpmem, msg, msg_length);
u16 id = clib_net_to_host_u16 (*((u16 *) msg));
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, id);
- void (*endian_fp) (void *);
- endian_fp = am->msg_endian_handlers[id];
- (*endian_fp) (tmpmem);
+ m->endian_handler (tmpmem);
- if (id < vec_len (am->msg_tojson_handlers) && am->msg_tojson_handlers[id])
+ if (m && m->tojson_handler)
{
- tojson_fn = am->msg_tojson_handlers[id];
- cJSON *o = tojson_fn (tmpmem);
+ cJSON *o = m->tojson_handler (tmpmem);
char *s = cJSON_Print (o);
slen = strlen (s);
tlen = fwrite (s, 1, slen, fp);
@@ -503,7 +498,7 @@ msg_handler_internal (api_main_t *am, void *the_msg, uword msg_len,
int trace_it, int do_it, int free_it)
{
u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
- u8 *(*print_fp) (void *, void *);
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, id);
if (PREDICT_FALSE (am->elog_trace_api_messages))
{
@@ -519,51 +514,44 @@ msg_handler_internal (api_main_t *am, void *the_msg, uword msg_len,
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)
{
if (trace_it)
vl_msg_api_trace (am, am->rx_trace, the_msg);
if (am->msg_print_flag)
{
- fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]);
- print_fp = (void *) am->msg_print_handlers[id];
- if (print_fp == 0)
- {
- fformat (stdout, " [no registered print fn]\n");
- }
+ fformat (stdout, "[%d]: %s\n", id, m->name);
+ if (m->print_handler)
+ m->print_handler (the_msg, stdout);
else
- {
- (*print_fp) (the_msg, stdout);
- }
+ fformat (stdout, " [no registered print fn]\n");
}
uword calc_size = 0;
- uword (*calc_size_fp) (void *);
- calc_size_fp = am->msg_calc_size_funcs[id];
- ASSERT (NULL != calc_size_fp);
- if (calc_size_fp)
+ ASSERT (NULL != m->calc_size_func);
+ if (m->calc_size_func)
{
- calc_size = (*calc_size_fp) (the_msg);
+ calc_size = m->calc_size_func (the_msg);
if (calc_size > msg_len)
{
clib_warning (
"Truncated message '%s' (id %u) received, calculated size "
"%lu is bigger than actual size %llu, message dropped.",
- am->msg_names[id], id, calc_size, msg_len);
+ m->name, id, calc_size, msg_len);
}
}
else
{
clib_warning ("Message '%s' (id %u) has NULL calc_size_func, cannot "
"verify message size is correct",
- am->msg_names[id], id);
+ m->name, id);
}
/* don't process message if it's truncated, otherwise byte swaps
@@ -572,30 +560,26 @@ msg_handler_internal (api_main_t *am, void *the_msg, uword msg_len,
if (do_it && calc_size <= msg_len)
{
- if (!am->is_mp_safe[id])
+ if (!m->is_mp_safe)
{
vl_msg_api_barrier_trace_context (am->msg_names[id]);
vl_msg_api_barrier_sync ();
}
- if (am->is_autoendian[id])
- {
- void (*endian_fp) (void *);
- endian_fp = am->msg_endian_handlers[id];
- (*endian_fp) (the_msg);
- }
+ if (m->is_autoendian)
+ m->endian_handler (the_msg);
if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0))
clib_call_callbacks (am->perf_counter_cbs, am, id,
0 /* before */ );
- (*am->msg_handlers[id]) (the_msg);
+ m->handler (the_msg);
if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0))
clib_call_callbacks (am->perf_counter_cbs, am, id,
1 /* after */ );
- if (!am->is_mp_safe[id])
+ if (!m->is_mp_safe)
vl_msg_api_barrier_release ();
}
}
@@ -629,10 +613,10 @@ msg_handler_internal (api_main_t *am, void *the_msg, uword msg_len,
u32 c;
} *ed;
ed = ELOG_DATA (am->elog_main, e);
- if (id < vec_len (am->msg_names) && am->msg_names[id])
+ if (m && m->name)
{
- ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
- ed->barrier = !am->is_mp_safe[id];
+ ed->c = elog_string (am->elog_main, (char *) m->name);
+ ed->barrier = !m->is_mp_safe;
}
else
{
@@ -693,14 +677,16 @@ vl_msg_api_cleanup_handler (void *the_msg)
{
api_main_t *am = vlibapi_get_main ();
u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, id);
- if (PREDICT_FALSE (id >= vec_len (am->msg_cleanup_handlers)))
+ if (PREDICT_FALSE (!m))
{
clib_warning ("_vl_msg_id too large: %d\n", id);
return;
}
- if (am->msg_cleanup_handlers[id])
- (*am->msg_cleanup_handlers[id]) (the_msg);
+
+ if (m->cleanup_handler)
+ m->cleanup_handler (the_msg);
vl_msg_api_free (the_msg);
}
@@ -712,17 +698,17 @@ void
vl_msg_api_replay_handler (void *the_msg)
{
api_main_t *am = vlibapi_get_main ();
-
u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, id);
- if (PREDICT_FALSE (id >= vec_len (am->msg_handlers)))
+ if (PREDICT_FALSE (!m))
{
clib_warning ("_vl_msg_id too large: %d\n", id);
return;
}
/* do NOT trace the message... */
- if (am->msg_handlers[id])
- (*am->msg_handlers[id]) (the_msg);
+ if (m->handler)
+ m->handler (the_msg);
/* do NOT free the message buffer... */
}
@@ -745,25 +731,11 @@ vl_msg_api_socket_handler (void *the_msg, uword msg_len)
1 /* do_it */, 0 /* free_it */);
}
-#define foreach_msg_api_vector \
- _ (msg_names) \
- _ (msg_handlers) \
- _ (msg_cleanup_handlers) \
- _ (msg_endian_handlers) \
- _ (msg_print_handlers) \
- _ (msg_print_json_handlers) \
- _ (msg_tojson_handlers) \
- _ (msg_fromjson_handlers) \
- _ (msg_calc_size_funcs) \
- _ (api_trace_cfg) \
- _ (message_bounce) \
- _ (is_mp_safe) \
- _ (is_autoendian)
-
void
vl_msg_api_config (vl_msg_api_msg_config_t * c)
{
api_main_t *am = vlibapi_get_main ();
+ vl_api_msg_data_t *m;
/*
* This happens during the java core tests if the message
@@ -782,32 +754,30 @@ vl_msg_api_config (vl_msg_api_msg_config_t * c)
return;
}
-#define _(a) vec_validate (am->a, c->id);
- foreach_msg_api_vector;
-#undef _
-
- if (am->msg_handlers[c->id] && am->msg_handlers[c->id] != c->handler)
- clib_warning
- ("BUG: re-registering 'vl_api_%s_t_handler'."
- "Handler was %llx, replaced by %llx",
- c->name, am->msg_handlers[c->id], c->handler);
-
- am->msg_names[c->id] = c->name;
- am->msg_handlers[c->id] = c->handler;
- am->msg_cleanup_handlers[c->id] = c->cleanup;
- am->msg_endian_handlers[c->id] = c->endian;
- am->msg_print_handlers[c->id] = c->print;
- am->msg_print_json_handlers[c->id] = c->print_json;
- am->msg_tojson_handlers[c->id] = c->tojson;
- am->msg_fromjson_handlers[c->id] = c->fromjson;
- am->msg_calc_size_funcs[c->id] = c->calc_size;
- am->message_bounce[c->id] = c->message_bounce;
- am->is_mp_safe[c->id] = c->is_mp_safe;
- am->is_autoendian[c->id] = c->is_autoendian;
-
- am->api_trace_cfg[c->id].size = c->size;
- am->api_trace_cfg[c->id].trace_enable = c->traced;
- am->api_trace_cfg[c->id].replay_enable = c->replay;
+ vec_validate (am->msg_data, c->id);
+ m = vl_api_get_msg_data (am, c->id);
+
+ if (m->handler && m->handler != c->handler)
+ clib_warning ("BUG: re-registering 'vl_api_%s_t_handler'."
+ "Handler was %llx, replaced by %llx",
+ c->name, m->handler, c->handler);
+
+ m->name = c->name;
+ m->handler = c->handler;
+ m->cleanup_handler = c->cleanup;
+ m->endian_handler = c->endian;
+ m->print_handler = c->print;
+ m->print_json_handler = c->print_json;
+ m->tojson_handler = c->tojson;
+ m->fromjson_handler = c->fromjson;
+ m->calc_size_func = c->calc_size;
+ m->bounce = c->message_bounce;
+ m->is_mp_safe = c->is_mp_safe;
+ m->is_autoendian = c->is_autoendian;
+
+ m->trace_size = c->size;
+ m->trace_enable = c->traced;
+ m->replay_allowed = c->replay;
if (!am->msg_id_by_name)
am->msg_id_by_name = hash_create_string (0, sizeof (uword));
@@ -864,10 +834,10 @@ void
vl_msg_api_set_cleanup_handler (int msg_id, void *fp)
{
api_main_t *am = vlibapi_get_main ();
+ vl_api_msg_data_t *m = vl_api_get_msg_data (am, msg_id);
ASSERT (msg_id > 0);
- vec_validate (am->msg_cleanup_handlers, msg_id);
- am->msg_cleanup_handlers[msg_id] = fp;
+ m->cleanup_handler = fp;
}
void