X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlibapi%2Fapi_shared.c;h=5e715d6f8298c73f1ae82d17dbd2d0f20b40eedd;hb=78f487e11;hp=28e9f481650e903a34123d522df0d4ab4f33dfc8;hpb=2dbee9361e74d03727a8b618ba80a5e28c006011;p=vpp.git diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c index 28e9f481650..5e715d6f829 100644 --- a/src/vlibapi/api_shared.c +++ b/src/vlibapi/api_shared.c @@ -30,6 +30,7 @@ #include #include #include +#include /* *INDENT-OFF* */ api_main_t api_global_main = @@ -485,7 +486,23 @@ msg_handler_internal (api_main_t * am, 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 (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); + + 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]) vl_msg_api_barrier_release (); } @@ -533,6 +550,8 @@ msg_handler_internal (api_main_t * am, } } +void (*vl_msg_api_fuzz_hook) (u16, void *); + /* This is only to be called from a vlib/vnet app */ void vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, @@ -600,7 +619,23 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, am->vlib_rp = vlib_rp; am->shmem_hdr = (void *) vlib_rp->user_ctx; } + + if (PREDICT_FALSE (vl_msg_api_fuzz_hook != 0)) + (*vl_msg_api_fuzz_hook) (id, the_msg); + + if (am->is_autoendian[id]) + { + void (*endian_fp) (void *); + endian_fp = am->msg_endian_handlers[id]; + (*endian_fp) (the_msg); + } + if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0)) + clib_call_callbacks (am->perf_counter_cbs, am, id, 0 /* before */ ); + (*handler) (the_msg, vm, node); + + if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0)) + clib_call_callbacks (am->perf_counter_cbs, am, id, 1 /* after */ ); if (is_private) { am->vlib_rp = old_vlib_rp; @@ -618,7 +653,7 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, * Special-case, so we can e.g. bounce messages off the vnet * main thread without copying them... */ - if (!(am->message_bounce[id])) + if (id >= vec_len (am->message_bounce) || !(am->message_bounce[id])) vl_msg_api_free (the_msg); if (PREDICT_FALSE (am->elog_trace_api_messages)) @@ -766,7 +801,8 @@ _(msg_endian_handlers) \ _(msg_print_handlers) \ _(api_trace_cfg) \ _(message_bounce) \ -_(is_mp_safe) +_(is_mp_safe) \ +_(is_autoendian) void vl_msg_api_config (vl_msg_api_msg_config_t * c) @@ -807,6 +843,7 @@ vl_msg_api_config (vl_msg_api_msg_config_t * c) am->msg_print_handlers[c->id] = c->print; 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; @@ -836,6 +873,7 @@ vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup, c->replay = 1; c->message_bounce = 0; c->is_mp_safe = 0; + c->is_autoendian = 0; vl_msg_api_config (c); } @@ -870,6 +908,21 @@ vl_msg_api_queue_handler (svm_queue_t * q) vl_msg_api_handler ((void *) msg); } +u32 +vl_msg_api_max_length (void *mp) +{ + msgbuf_t *mb; + u32 data_len = ~0; + + /* Work out the maximum sane message length, and return it */ + if (PREDICT_TRUE (mp != 0)) + { + mb = (msgbuf_t *) (((u8 *) mp) - offsetof (msgbuf_t, data)); + data_len = clib_net_to_host_u32 (mb->data_len); + } + return data_len; +} + vl_api_trace_t * vl_msg_api_trace_get (api_main_t * am, vl_api_trace_which_t which) { @@ -1132,9 +1185,13 @@ vl_api_format_string (u8 * s, va_list * args) * NOT nul terminated. */ u8 * -vl_api_from_api_to_new_vec (vl_api_string_t * astr) +vl_api_from_api_to_new_vec (void *mp, vl_api_string_t * astr) { u8 *v = 0; + + if (vl_msg_api_max_length (mp) < clib_net_to_host_u32 (astr->length)) + return format (0, "insane astr->length %u%c", + clib_net_to_host_u32 (astr->length), 0); vec_add (v, astr->buf, clib_net_to_host_u32 (astr->length)); return v; }