X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvpp%2Fapi%2Fapi_main.c;h=47d974877e1cf5dd7e09afcc79a5991a57f6fcad;hb=f284c14c7bd8731367ba3527cdfffa610a8c6de4;hp=d3764337b1104031fde4c062a119d6917288f62f;hpb=a331e6fc45e175aa2a0544150ddae16f82fae833;p=vpp.git diff --git a/src/vpp/api/api_main.c b/src/vpp/api/api_main.c index d3764337b11..47d974877e1 100644 --- a/src/vpp/api/api_main.c +++ b/src/vpp/api/api_main.c @@ -1,9 +1,11 @@ #include "vat.h" +#include +#include vat_main_t vat_main; -void -vat_suspend (vlib_main_t * vm, f64 interval) +void __clib_no_tail_calls +vat_suspend (vlib_main_t *vm, f64 interval) { vlib_process_suspend (vm, interval); } @@ -38,8 +40,29 @@ init_error_string_table (vat_main_t * vam) hash_set (vam->error_string_by_error_number, 99, "Misc"); } -static clib_error_t * -api_main_init (vlib_main_t * vm) +#if VPP_API_TEST_BUILTIN > 0 +static void +load_features (void) +{ + vat_registered_features_t *f; + vat_main_t *vam = &vat_main; + clib_error_t *error; + + f = vam->feature_function_registrations; + + while (f) + { + error = f->function (vam); + if (error) + { + clib_warning ("INIT FAILED"); + } + f = f->next; + } +} + +clib_error_t * +vat_builtin_main_init (vlib_main_t * vm) { vat_main_t *vam = &vat_main; int rv; @@ -49,14 +72,18 @@ api_main_init (vlib_main_t * vm) vam->my_client_index = (u32) ~ 0; /* Ensure that vam->inbuf is never NULL */ vec_validate (vam->inbuf, 0); + vec_validate (vam->cmd_reply, 0); + vec_reset_length (vam->cmd_reply); init_error_string_table (vam); rv = vat_plugin_init (vam); if (rv) clib_warning ("vat_plugin_init returned %d", rv); + + load_features (); + return 0; } - -VLIB_INIT_FUNCTION (api_main_init); +#endif void vat_plugin_hash_create (void) @@ -68,6 +95,71 @@ vat_plugin_hash_create (void) vam->help_by_name = hash_create_string (0, sizeof (uword)); } +static void +vat_register_interface_dump (vat_main_t *vam) +{ + void *handle; + plugin_info_t *pi; + + vec_foreach (pi, vat_plugin_main.plugin_info) + { + handle = dlsym (pi->handle, "api_sw_interface_dump"); + if (handle) + { + vam->api_sw_interface_dump = handle; + break; + } + } + + if (!vam->api_sw_interface_dump) + { + fformat (stderr, + "sw_interface_dump not found in interface_test plugin!\n"); + exit (1); + } +} + +static void +maybe_register_api_client (vat_main_t * vam) +{ + vl_api_registration_t **regpp; + vl_api_registration_t *regp; + void *oldheap; + api_main_t *am = vlibapi_get_main (); + + if (vam->my_client_index != ~0) + return; + + pool_get (am->vl_clients, regpp); + + oldheap = vl_msg_push_heap (); + + *regpp = clib_mem_alloc (sizeof (vl_api_registration_t)); + + regp = *regpp; + clib_memset (regp, 0, sizeof (*regp)); + regp->registration_type = REGISTRATION_TYPE_SHMEM; + regp->vl_api_registration_pool_index = regpp - am->vl_clients; + regp->vlib_rp = am->vlib_rp; + regp->shmem_hdr = am->shmem_hdr; + + /* Loopback connection */ + regp->vl_input_queue = am->shmem_hdr->vl_input_queue; + + regp->name = format (0, "%s", "vpp-internal"); + vec_add1 (regp->name, 0); + + vl_msg_pop_heap (oldheap); + + vam->my_client_index = vl_msg_api_handle_from_index_and_epoch + (regp->vl_api_registration_pool_index, + am->shmem_hdr->application_restarts); + + vam->vl_input_queue = am->shmem_hdr->vl_input_queue; + vat_register_interface_dump (vam); + vam->api_sw_interface_dump (vam); +} + static clib_error_t * api_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -80,29 +172,23 @@ api_command_fn (vlib_main_t * vm, u32 arg_len; int rv; int (*fp) (vat_main_t *); - api_main_t *am = &api_main; - vam->vl_input_queue = am->shmem_hdr->vl_input_queue; + maybe_register_api_client (vam); -#ifdef __COVERITY - /* - * Convince Coverity that it's not a NULL pointer... - * Done once for real below, since we never vec_free(vam->inbuf); - */ - vec_validate (vam->inbuf, 0); -#endif + /* vec_validated in the init routine */ + vec_set_len (vam->inbuf, 0); - vec_reset_length (vam->inbuf); vam->input = &_input; while (((c = unformat_get_input (input)) != '\n') && (c != UNFORMAT_END_OF_INPUT)) vec_add1 (vam->inbuf, c); - /* Add 1 octet's worth of extra space in case there are no args... */ + /* Null-terminate the command */ vec_add1 (vam->inbuf, 0); - /*$$$$ reinstall macro evaluator */ + /* In case no args given */ + vec_add1 (vam->inbuf, 0); /* Split input into cmd + args */ this_cmd = cmdp = vam->inbuf; @@ -123,7 +209,7 @@ api_command_fn (vlib_main_t * vm, /* Advance past the command */ while (argsp < (this_cmd + vec_len (this_cmd))) { - if (*argsp != ' ' && *argsp != '\t' && *argsp != '\n' && argsp != 0) + if (*argsp != ' ' && *argsp != '\t' && *argsp != '\n' && *argsp != 0) { argsp++; } @@ -133,15 +219,19 @@ api_command_fn (vlib_main_t * vm, /* NULL terminate the command */ *argsp++ = 0; - while (argsp < (this_cmd + vec_len (this_cmd))) - { - if (*argsp == ' ' || *argsp == '\t' || *argsp == '\n') - { - argsp++; - } - else - break; - } + /* No arguments? Ensure that argsp points to a proper (empty) string */ + if (argsp == (this_cmd + vec_len (this_cmd) - 1)) + argsp[0] = 0; + else + while (argsp < (this_cmd + vec_len (this_cmd))) + { + if (*argsp == ' ' || *argsp == '\t' || *argsp == '\n') + { + argsp++; + } + else + break; + } /* Blank input line? */ if (*cmdp == 0) @@ -171,7 +261,7 @@ api_command_fn (vlib_main_t * vm, if (vam->regenerate_interface_table) { vam->regenerate_interface_table = 0; - api_sw_interface_dump (vam); + vam->api_sw_interface_dump (vam); } unformat_free (vam->input); return 0; @@ -183,6 +273,7 @@ VLIB_CLI_COMMAND (api_command, static) = .path = "binary-api", .short_help = "binary-api [help] []", .function = api_command_fn, + .is_mp_safe = 1, }; /* *INDENT-ON* */ @@ -212,9 +303,9 @@ api_cli_output (void *notused, const char *fmt, ...) } u16 -vl_client_get_first_plugin_msg_id (char *plugin_name) +vl_client_get_first_plugin_msg_id (const char *plugin_name) { - api_main_t *am = &api_main; + api_main_t *am = vlibapi_get_main (); vl_api_msg_range_t *rp; uword *p; @@ -230,11 +321,11 @@ vl_client_get_first_plugin_msg_id (char *plugin_name) uword unformat_sw_if_index (unformat_input_t * input, va_list * args) { + void *vam_unused = va_arg (*args, void *); + (void) (vam_unused); u32 *result = va_arg (*args, u32 *); vnet_main_t *vnm = vnet_get_main (); u32 sw_if_index = ~0; - u8 *if_name; - uword *p; if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) {