X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=src%2Fvlibapi%2Fapi_shared.c;h=52e66f41342f50db16a0bb29cfa97dbe38d2f7ff;hp=ce7c4aec712473170795c0744831b3b70203f4df;hb=36217e3ca;hpb=edfe2c0079a756f5fb1108037c39450e3521c8bd diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c index ce7c4aec712..52e66f41342 100644 --- a/src/vlibapi/api_shared.c +++ b/src/vlibapi/api_shared.c @@ -30,9 +30,10 @@ #include #include #include +#include /* *INDENT-OFF* */ -api_main_t api_main = +api_main_t api_global_main = { .region_name = "/unset", .api_uid = -1, @@ -40,10 +41,20 @@ api_main_t api_main = }; /* *INDENT-ON* */ +/* Please use vlibapi_get_main() to access my_api_main */ +__thread api_main_t *my_api_main = &api_global_main; + +void +vl_msg_api_set_global_main (void *am_arg) +{ + ASSERT (am_arg); + my_api_main = (api_main_t *) am_arg; +} + void vl_msg_api_increment_missing_client_counter (void) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); am->missing_clients++; } @@ -212,13 +223,160 @@ vl_api_serialize_message_table (api_main_t * am, u8 * vector) return serialize_close_vector (sm); } +static int +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)); + + void (*endian_fp) (void *); + endian_fp = am->msg_endian_handlers[id]; + (*endian_fp) (tmpmem); + + if (id < vec_len (am->msg_tojson_handlers) && am->msg_tojson_handlers[id]) + { + tojson_fn = am->msg_tojson_handlers[id]; + cJSON *o = tojson_fn (tmpmem); + char *s = cJSON_Print (o); + slen = strlen (s); + tlen = fwrite (s, 1, slen, fp); + cJSON_free (s); + cJSON_Delete (o); + vec_free (tmpmem); + if (tlen != slen) + { + fformat (stderr, "writing to file error\n"); + return -11; + } + } + else + fformat (stderr, " [no registered tojson fn]\n"); + + return 0; +} + +#define vl_msg_fwrite(_s, _f) fwrite (_s, 1, sizeof (_s) - 1, _f) + +typedef struct +{ + FILE *fp; + u32 n_traces; + u32 i; +} vl_msg_write_json_args_t; + +static int +vl_msg_write_json_fn (u8 *msg, void *ctx) +{ + vl_msg_write_json_args_t *arg = ctx; + FILE *fp = arg->fp; + api_main_t *am = vlibapi_get_main (); + int rc = vl_msg_api_trace_write_one (am, msg, fp); + if (rc < 0) + return rc; + + if (arg->i < arg->n_traces - 1) + vl_msg_fwrite (",\n", fp); + arg->i++; + return 0; +} + +static int +vl_msg_api_trace_write_json (api_main_t *am, vl_api_trace_t *tp, FILE *fp) +{ + vl_msg_write_json_args_t args; + clib_memset (&args, 0, sizeof (args)); + args.fp = fp; + args.n_traces = vec_len (tp->traces); + vl_msg_fwrite ("[\n", fp); + + int rv = vl_msg_traverse_trace (tp, vl_msg_write_json_fn, &args); + if (rv < 0) + return rv; + + vl_msg_fwrite ("]", fp); + return 0; +} + int -vl_msg_api_trace_save (api_main_t * am, vl_api_trace_which_t which, FILE * fp) +vl_msg_traverse_trace (vl_api_trace_t *tp, vl_msg_traverse_trace_fn fn, + void *ctx) { - vl_api_trace_t *tp; - vl_api_trace_file_header_t fh; int i; u8 *msg; + int rv = 0; + + /* No-wrap case */ + if (tp->wrapped == 0) + { + for (i = 0; i < vec_len (tp->traces); i++) + { + /*sa_ignore NO_NULL_CHK */ + msg = tp->traces[i]; + if (!msg) + continue; + + rv = fn (msg, ctx); + if (rv < 0) + return rv; + } + } + else + { + /* Wrap case: write oldest -> end of buffer */ + for (i = tp->curindex; i < vec_len (tp->traces); i++) + { + msg = tp->traces[i]; + if (!msg) + continue; + + rv = fn (msg, ctx); + if (rv < 0) + return rv; + } + /* write beginning of buffer -> oldest-1 */ + for (i = 0; i < tp->curindex; i++) + { + /*sa_ignore NO_NULL_CHK */ + msg = tp->traces[i]; + if (!msg) + continue; + + rv = fn (msg, ctx); + if (rv < 0) + return rv; + } + } + return 0; +} + +static int +vl_api_msg_write_fn (u8 *msg, void *ctx) +{ + FILE *fp = ctx; + u32 msg_length = clib_host_to_net_u32 (vec_len (msg)); + if (fwrite (&msg_length, 1, sizeof (msg_length), fp) != sizeof (msg_length)) + { + return (-14); + } + if (fwrite (msg, 1, vec_len (msg), fp) != vec_len (msg)) + { + return (-14); + } + return 0; +} + +int +vl_msg_api_trace_save (api_main_t *am, vl_api_trace_which_t which, FILE *fp, + u8 is_json) +{ + vl_api_trace_t *tp; + vl_api_trace_file_header_t fh; switch (which) { @@ -245,11 +403,14 @@ vl_msg_api_trace_save (api_main_t * am, vl_api_trace_which_t which, FILE * fp) return -2; } + if (is_json) + return vl_msg_api_trace_write_json (am, tp, fp); + /* Write the file header */ fh.wrapped = tp->wrapped; fh.nitems = clib_host_to_net_u32 (vec_len (tp->traces)); + u8 *m = vl_api_serialize_message_table (am, 0); - clib_warning ("Message table length %d", vec_len (m)); fh.msgtbl_size = clib_host_to_net_u32 (vec_len (m)); if (fwrite (&fh, sizeof (fh), 1, fp) != 1) @@ -264,92 +425,7 @@ vl_msg_api_trace_save (api_main_t * am, vl_api_trace_which_t which, FILE * fp) } vec_free (m); - /* No-wrap case */ - if (tp->wrapped == 0) - { - /* - * Note: vec_len return 0 when fed a NULL pointer. - * Unfortunately, the static analysis tool doesn't - * figure it out, hence the suppressed warnings. - * What a great use of my time. - */ - for (i = 0; i < vec_len (tp->traces); i++) - { - u32 msg_length; - /*sa_ignore NO_NULL_CHK */ - msg = tp->traces[i]; - /* - * This retarded check required to pass - * [sic] SA-checking. - */ - if (!msg) - continue; - - msg_length = clib_host_to_net_u32 (vec_len (msg)); - if (fwrite (&msg_length, 1, sizeof (msg_length), fp) - != sizeof (msg_length)) - { - return (-14); - } - if (fwrite (msg, 1, vec_len (msg), fp) != vec_len (msg)) - { - return (-11); - } - } - } - else - { - /* Wrap case: write oldest -> end of buffer */ - for (i = tp->curindex; i < vec_len (tp->traces); i++) - { - u32 msg_length; - msg = tp->traces[i]; - /* - * This retarded check required to pass - * [sic] SA-checking - */ - if (!msg) - continue; - - msg_length = clib_host_to_net_u32 (vec_len (msg)); - if (fwrite (&msg_length, 1, sizeof (msg_length), fp) - != sizeof (msg_length)) - { - return (-14); - } - - if (fwrite (msg, 1, vec_len (msg), fp) != vec_len (msg)) - { - return (-12); - } - } - /* write beginning of buffer -> oldest-1 */ - for (i = 0; i < tp->curindex; i++) - { - u32 msg_length; - /*sa_ignore NO_NULL_CHK */ - msg = tp->traces[i]; - /* - * This retarded check required to pass - * [sic] SA-checking - */ - if (!msg) - continue; - - msg_length = clib_host_to_net_u32 (vec_len (msg)); - if (fwrite (&msg_length, 1, sizeof (msg_length), fp) - != sizeof (msg_length)) - { - return (-14); - } - - if (fwrite (msg, 1, vec_len (msg), fp) != vec_len (msg)) - { - return (-13); - } - } - } - return 0; + return vl_msg_traverse_trace (tp, vl_api_msg_write_fn, fp); } int @@ -444,7 +520,7 @@ msg_handler_internal (api_main_t * am, u32 c; } *ed; ed = ELOG_DATA (am->elog_main, e); - if (id < vec_len (am->msg_names)) + if (id < vec_len (am->msg_names) && am->msg_names[id]) ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); else ed->c = elog_string (am->elog_main, "BOGUS"); @@ -476,7 +552,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 (); } @@ -511,7 +603,7 @@ msg_handler_internal (api_main_t * am, u32 c; } *ed; ed = ELOG_DATA (am->elog_main, e); - if (id < vec_len (am->msg_names)) + if (id < vec_len (am->msg_names) && am->msg_names[id]) { ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); ed->barrier = !am->is_mp_safe[id]; @@ -524,15 +616,19 @@ 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, +vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp, void *the_msg, vlib_main_t * vm, - vlib_node_runtime_t * node) + vlib_node_runtime_t * node, u8 is_private) { u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); u8 *(*handler) (void *, void *, void *); u8 *(*print_fp) (void *, void *); + svm_region_t *old_vlib_rp; + void *save_shmem_hdr; int is_mp_safe = 1; if (PREDICT_FALSE (am->elog_trace_api_messages)) @@ -549,7 +645,7 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, u32 c; } *ed; ed = ELOG_DATA (am->elog_main, e); - if (id < vec_len (am->msg_names)) + if (id < vec_len (am->msg_names) && am->msg_names[id]) ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); else ed->c = elog_string (am->elog_main, "BOGUS"); @@ -582,7 +678,35 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, vl_msg_api_barrier_trace_context (am->msg_names[id]); vl_msg_api_barrier_sync (); } + if (is_private) + { + old_vlib_rp = am->vlib_rp; + save_shmem_hdr = am->shmem_hdr; + 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; + am->shmem_hdr = save_shmem_hdr; + } if (!is_mp_safe) vl_msg_api_barrier_release (); } @@ -595,8 +719,22 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, * Special-case, so we can e.g. bounce messages off the vnet * main thread without copying them... */ - if (!(am->message_bounce[id])) - vl_msg_api_free (the_msg); + if (id >= vec_len (am->message_bounce) || !(am->message_bounce[id])) + { + if (is_private) + { + old_vlib_rp = am->vlib_rp; + save_shmem_hdr = am->shmem_hdr; + am->vlib_rp = vlib_rp; + am->shmem_hdr = (void *) vlib_rp->user_ctx; + } + vl_msg_api_free (the_msg); + if (is_private) + { + am->vlib_rp = old_vlib_rp; + am->shmem_hdr = save_shmem_hdr; + } + } if (PREDICT_FALSE (am->elog_trace_api_messages)) { @@ -620,7 +758,7 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, u32 c; } *ed; ed = ELOG_DATA (am->elog_main, e); - if (id < vec_len (am->msg_names)) + if (id < vec_len (am->msg_names) && am->msg_names[id]) ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]); else ed->c = elog_string (am->elog_main, "BOGUS"); @@ -631,7 +769,7 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, void vl_msg_api_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace @@ -642,7 +780,7 @@ vl_msg_api_handler (void *the_msg) void vl_msg_api_handler_no_free (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace && am->rx_trace->enabled) /* trace_it */ , @@ -652,7 +790,7 @@ vl_msg_api_handler_no_free (void *the_msg) void vl_msg_api_handler_no_trace_no_free (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, 0 /* trace_it */ , 1 /* do_it */ , 0 /* free_it */ ); } @@ -669,7 +807,7 @@ vl_msg_api_handler_no_trace_no_free (void *the_msg) void vl_msg_api_trace_only (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace @@ -680,7 +818,7 @@ vl_msg_api_trace_only (void *the_msg) void vl_msg_api_cleanup_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); if (PREDICT_FALSE (id >= vec_len (am->msg_cleanup_handlers))) @@ -700,7 +838,7 @@ vl_msg_api_cleanup_handler (void *the_msg) void vl_msg_api_replay_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); u16 id = clib_net_to_host_u16 (*((u16 *) the_msg)); @@ -727,7 +865,7 @@ vl_msg_api_get_msg_length (void *msg_arg) void vl_msg_api_socket_handler (void *the_msg) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); msg_handler_internal (am, the_msg, (am->rx_trace @@ -735,20 +873,24 @@ vl_msg_api_socket_handler (void *the_msg) 1 /* do_it */ , 0 /* free_it */ ); } -#define foreach_msg_api_vector \ -_(msg_names) \ -_(msg_handlers) \ -_(msg_cleanup_handlers) \ -_(msg_endian_handlers) \ -_(msg_print_handlers) \ -_(api_trace_cfg) \ -_(message_bounce) \ -_(is_mp_safe) +#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) \ + _ (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 = &api_main; + api_main_t *am = vlibapi_get_main (); /* * This happens during the java core tests if the message @@ -782,12 +924,21 @@ vl_msg_api_config (vl_msg_api_msg_config_t * c) 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->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; + + if (!am->msg_id_by_name) + am->msg_id_by_name = hash_create_string (0, sizeof (uword)); + + hash_set_mem (am->msg_id_by_name, c->name, c->id); } /* @@ -796,7 +947,8 @@ vl_msg_api_config (vl_msg_api_msg_config_t * c) */ void vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup, - void *endian, void *print, int size, int traced) + void *endian, void *print, int size, int traced, + void *print_json, void *tojson, void *fromjson) { vl_msg_api_msg_config_t cfg; vl_msg_api_msg_config_t *c = &cfg; @@ -813,6 +965,10 @@ 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; + c->tojson = tojson; + c->fromjson = fromjson; + c->print_json = print_json; vl_msg_api_config (c); } @@ -831,7 +987,7 @@ vl_msg_api_clean_handlers (int msg_id) void vl_msg_api_set_cleanup_handler (int msg_id, void *fp) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); ASSERT (msg_id > 0); vec_validate (am->msg_cleanup_handlers, msg_id); @@ -847,6 +1003,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) { @@ -878,7 +1049,7 @@ vl_msg_api_post_mortem_dump_enable_disable (int enable) void vl_msg_api_post_mortem_dump (void) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); FILE *fp; char filename[64]; int rv; @@ -897,7 +1068,7 @@ vl_msg_api_post_mortem_dump (void) rv = write (2, "\n", 1); return; } - rv = vl_msg_api_trace_save (am, VL_API_TRACE_RX, fp); + rv = vl_msg_api_trace_save (am, VL_API_TRACE_RX, fp, 0); fclose (fp); if (rv < 0) { @@ -913,7 +1084,7 @@ vl_msg_api_post_mortem_dump (void) void vl_msg_api_register_pd_handler (void *fp, u16 msg_id_host_byte_order) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); /* Mild idiot proofing */ if (msg_id_host_byte_order > 10000) @@ -927,7 +1098,7 @@ vl_msg_api_register_pd_handler (void *fp, u16 msg_id_host_byte_order) int vl_msg_api_pd_handler (void *mp, int rv) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); int (*fp) (void *, int); u16 msg_id; @@ -948,7 +1119,7 @@ vl_msg_api_pd_handler (void *mp, int rv) void vl_msg_api_set_first_available_msg_id (u16 first_avail) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); am->first_available_msg_id = first_avail; } @@ -956,7 +1127,7 @@ vl_msg_api_set_first_available_msg_id (u16 first_avail) u16 vl_msg_api_get_msg_ids (const char *name, int n) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); u8 *name_copy; vl_api_msg_range_t *rp; uword *p; @@ -1028,7 +1199,7 @@ vl_msg_api_add_version (api_main_t * am, const char *string, u32 vl_msg_api_get_msg_index (u8 * name_and_crc) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); uword *p; if (am->msg_index_by_name_and_crc) @@ -1040,30 +1211,47 @@ vl_msg_api_get_msg_index (u8 * name_and_crc) return ~0; } +void * +vl_msg_push_heap_w_region (svm_region_t * vlib_rp) +{ + pthread_mutex_lock (&vlib_rp->mutex); + return svm_push_data_heap (vlib_rp); +} + void * vl_msg_push_heap (void) { - api_main_t *am = &api_main; - pthread_mutex_lock (&am->vlib_rp->mutex); - return svm_push_data_heap (am->vlib_rp); + api_main_t *am = vlibapi_get_main (); + return vl_msg_push_heap_w_region (am->vlib_rp); } void -vl_msg_pop_heap (void *oldheap) +vl_msg_pop_heap_w_region (svm_region_t * vlib_rp, void *oldheap) { - api_main_t *am = &api_main; svm_pop_heap (oldheap); - pthread_mutex_unlock (&am->vlib_rp->mutex); + pthread_mutex_unlock (&vlib_rp->mutex); +} + +void +vl_msg_pop_heap (void *oldheap) +{ + api_main_t *am = vlibapi_get_main (); + vl_msg_pop_heap_w_region (am->vlib_rp, oldheap); } +/* Must be nul terminated */ int -vl_api_to_api_string (u32 len, const char *buf, vl_api_string_t * str) +vl_api_c_string_to_api_string (const char *buf, vl_api_string_t * str) { - clib_memcpy_fast (str->buf, buf, len); + /* copy without nul terminator */ + u32 len = strlen (buf); + if (len > 0) + clib_memcpy_fast (str->buf, buf, len); str->length = htonl (len); return len + sizeof (u32); } +/* Must NOT be nul terminated */ int vl_api_vec_to_api_string (const u8 * vec, vl_api_string_t * str) { @@ -1073,34 +1261,56 @@ vl_api_vec_to_api_string (const u8 * vec, vl_api_string_t * str) return len + sizeof (u32); } -/* Return a pointer to the API string (not nul terminated */ -u8 * -vl_api_from_api_string (vl_api_string_t * astr) -{ - return astr->buf; -} - u32 vl_api_string_len (vl_api_string_t * astr) { return clib_net_to_host_u32 (astr->length); } +u8 * +vl_api_format_string (u8 * s, va_list * args) +{ + vl_api_string_t *a = va_arg (*args, vl_api_string_t *); + vec_add (s, a->buf, clib_net_to_host_u32 (a->length)); + return s; +} + /* * Returns a new vector. Remember to free it after use. + * NOT nul terminated. */ u8 * -vl_api_from_api_to_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; } +/* + * Returns a new vector. Remember to free it after use. + * Nul terminated. + */ +char * +vl_api_from_api_to_new_c_string (vl_api_string_t * astr) +{ + char *v = 0; + if (clib_net_to_host_u32 (astr->length) > 0) + { + vec_add (v, astr->buf, clib_net_to_host_u32 (astr->length)); + vec_add1 (v, 0); + } + return v; +} + void vl_api_set_elog_main (elog_main_t * m) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); am->elog_main = m; } @@ -1108,7 +1318,7 @@ int vl_api_set_elog_trace_api_messages (int enable) { int rv; - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); rv = am->elog_trace_api_messages; am->elog_trace_api_messages = enable; @@ -1118,7 +1328,7 @@ vl_api_set_elog_trace_api_messages (int enable) int vl_api_get_elog_trace_api_messages (void) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); return am->elog_trace_api_messages; }