interface: add api test file

Type: improvement

Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
Change-Id: Ib07029204ecf12bf2adb5a39afa54bc98fb81f34
This commit is contained in:
Filip Tehlar
2021-07-23 22:03:05 +00:00
committed by Ole Tr�an
parent 2e55823af6
commit f0e67d78ae
21 changed files with 1484 additions and 164 deletions

View File

@ -57,6 +57,8 @@
#include <vlibmemory/memclnt.api_enum.h>
#include <vlibmemory/memclnt.api_types.h>
#include <vlibmemory/memclnt.api_tojson.h>
#include <vlibmemory/memclnt.api_fromjson.h>
#define vl_endianfun /* define message structures */
#include <vlibmemory/memclnt.api.h>
@ -170,23 +172,6 @@ errmsg (char *fmt, ...)
}
#if VPP_API_TEST_BUILTIN == 0
static uword
api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
{
vat_main_t *vam = va_arg (*args, vat_main_t *);
u32 *result = va_arg (*args, u32 *);
u8 *if_name;
uword *p;
if (!unformat (input, "%s", &if_name))
return 0;
p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
if (p == 0)
return 0;
*result = p[0];
return 1;
}
/* Parse an IP4 address %d.%d.%d.%d. */
uword
@ -644,6 +629,48 @@ format_hex_bytes (u8 * s, va_list * va)
return s;
}
static void
vl_api_control_ping_reply_t_handler (vl_api_control_ping_reply_t *mp)
{
vat_main_t *vam = &vat_main;
i32 retval = ntohl (mp->retval);
if (vam->async_mode)
{
vam->async_errors += (retval < 0);
}
else
{
vam->retval = retval;
vam->result_ready = 1;
}
if (vam->socket_client_main)
vam->socket_client_main->control_pings_outstanding--;
}
static void
vl_api_control_ping_reply_t_handler_json (vl_api_control_ping_reply_t *mp)
{
vat_main_t *vam = &vat_main;
i32 retval = ntohl (mp->retval);
if (VAT_JSON_NONE != vam->json_tree.type)
{
vat_json_print (vam->ofp, &vam->json_tree);
vat_json_free (&vam->json_tree);
vam->json_tree.type = VAT_JSON_NONE;
}
else
{
/* just print [] */
vat_json_init_array (&vam->json_tree);
vat_json_print (vam->ofp, &vam->json_tree);
vam->json_tree.type = VAT_JSON_NONE;
}
vam->retval = retval;
vam->result_ready = 1;
}
/*
* Generate boilerplate reply handlers, which
* dig the return value out of the xxx_reply_t API message,
@ -693,6 +720,7 @@ foreach_standard_reply_retval_handler;
#define foreach_vpe_api_reply_msg \
_ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
_ (CONTROL_PING_REPLY, control_ping_reply)
#define foreach_standalone_reply_msg \
@ -706,10 +734,23 @@ typedef struct
case L2_VTR_ ## op: \
return "" # op;
int
api_sw_interface_dump (vat_main_t *vam)
static const char *
str_vtr_op (u32 vtr_op)
{
return 0;
switch (vtr_op)
{
STR_VTR_OP_CASE (DISABLED);
STR_VTR_OP_CASE (PUSH_1);
STR_VTR_OP_CASE (PUSH_2);
STR_VTR_OP_CASE (POP_1);
STR_VTR_OP_CASE (POP_2);
STR_VTR_OP_CASE (TRANSLATE_1_1);
STR_VTR_OP_CASE (TRANSLATE_1_2);
STR_VTR_OP_CASE (TRANSLATE_2_1);
STR_VTR_OP_CASE (TRANSLATE_2_2);
}
return "UNKNOWN";
}
uword
@ -2299,12 +2340,10 @@ help (vat_main_t * vam)
print (vam->ofp, "Help is available for the following:");
/* *INDENT-OFF* */
hash_foreach_pair (p, vam->function_by_name,
({
vec_add1 (cmds, (u8 *)(p->key));
}));
/* *INDENT-ON* */
vec_sort_with_function (cmds, cmd_cmp);
@ -2377,14 +2416,11 @@ dump_macro_table (vat_main_t * vam)
int i;
hash_pair_t *p;
/* *INDENT-OFF* */
hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
({
vec_add2 (sort_me, sm, 1);
sm->name = (u8 *)(p->key);
sm->value = (u8 *) (p->value[0]);
}));
/* *INDENT-ON* */
hash_foreach_pair (p, vam->macro_main.the_value_table_hash, ({
vec_add2 (sort_me, sm, 1);
sm->name = (u8 *) (p->key);
sm->value = (u8 *) (p->value[0]);
}));
vec_sort_with_function (sort_me, macro_sort_cmp);
@ -2420,14 +2456,12 @@ dump_msg_api_table (vat_main_t * vam)
hash_pair_t *hp;
int i;
/* *INDENT-OFF* */
hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
({
vec_add2 (nses, ns, 1);
ns->name = (u8 *)(hp->key);
ns->value = (u32) hp->value[0];
}));
/* *INDENT-ON* */
vec_sort_with_function (nses, value_sort_cmp);
@ -2580,29 +2614,107 @@ exec (vat_main_t *vam)
return -1;
}
static int
name_sort_cmp (void *a1, void *a2)
{
name_sort_t *n1 = a1;
name_sort_t *n2 = a2;
return strcmp ((char *) n1->name, (char *) n2->name);
}
static int
dump_interface_table (vat_main_t *vam)
{
hash_pair_t *p;
name_sort_t *nses = 0, *ns;
if (vam->json_output)
{
clib_warning (
"JSON output supported only for VPE API calls and dump_stats_table");
return -99;
}
hash_foreach_pair (p, vam->sw_if_index_by_interface_name, ({
vec_add2 (nses, ns, 1);
ns->name = (u8 *) (p->key);
ns->value = (u32) p->value[0];
}));
vec_sort_with_function (nses, name_sort_cmp);
print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
vec_foreach (ns, nses)
{
print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
}
vec_free (nses);
return 0;
}
static int
dump_sub_interface_table (vat_main_t *vam)
{
const sw_interface_subif_t *sub = NULL;
if (vam->json_output)
{
clib_warning (
"JSON output supported only for VPE API calls and dump_stats_table");
return -99;
}
print (vam->ofp, "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
"Interface", "sw_if_index", "sub id", "dot1ad", "tags", "outer id",
"inner id", "exact", "default", "outer any", "inner any");
vec_foreach (sub, vam->sw_if_subif_table)
{
print (vam->ofp, "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
sub->interface_name, sub->sw_if_index, sub->sub_id,
sub->sub_dot1ad ? "dot1ad" : "dot1q", sub->sub_number_of_tags,
sub->sub_outer_vlan_id, sub->sub_inner_vlan_id,
sub->sub_exact_match, sub->sub_default,
sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
if (sub->vtr_op != L2_VTR_DISABLED)
{
print (vam->ofp,
" vlan-tag-rewrite - op: %-14s [ dot1q: %d "
"tag1: %d tag2: %d ]",
str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q, sub->vtr_tag1,
sub->vtr_tag2);
}
}
return 0;
}
/* List of API message constructors, CLI names map to api_xxx */
#define foreach_vpe_api_msg \
_(get_first_msg_id, "client <name>") \
_(sock_init_shm, "size <nnn>") \
/* List of command functions, CLI names map directly to functions */
#define foreach_cli_function \
_(comment, "usage: comment <ignore-rest-of-line>") \
_(dump_macro_table, "usage: dump_macro_table ") \
_(dump_msg_api_table, "usage: dump_msg_api_table") \
_(elog_setup, "usage: elog_setup [nevents, default 128K]") \
_(elog_disable, "usage: elog_disable") \
_(elog_enable, "usage: elog_enable") \
_(elog_save, "usage: elog_save <filename>") \
_(get_msg_id, "usage: get_msg_id name_and_crc") \
_(echo, "usage: echo <message>") \
_(help, "usage: help") \
_(q, "usage: quit") \
_(quit, "usage: quit") \
_(search_node_table, "usage: search_node_table <name>...") \
_(set, "usage: set <variable-name> <value>") \
_(script, "usage: script <file-name>") \
_(statseg, "usage: statseg") \
_(unset, "usage: unset <variable-name>")
#define foreach_cli_function \
_ (comment, "usage: comment <ignore-rest-of-line>") \
_ (dump_interface_table, "usage: dump_interface_table") \
_ (dump_sub_interface_table, "usage: dump_sub_interface_table") \
_ (dump_macro_table, "usage: dump_macro_table ") \
_ (dump_msg_api_table, "usage: dump_msg_api_table") \
_ (elog_setup, "usage: elog_setup [nevents, default 128K]") \
_ (elog_disable, "usage: elog_disable") \
_ (elog_enable, "usage: elog_enable") \
_ (elog_save, "usage: elog_save <filename>") \
_ (get_msg_id, "usage: get_msg_id name_and_crc") \
_ (echo, "usage: echo <message>") \
_ (help, "usage: help") \
_ (q, "usage: quit") \
_ (quit, "usage: quit") \
_ (search_node_table, "usage: search_node_table <name>...") \
_ (set, "usage: set <variable-name> <value>") \
_ (script, "usage: script <file-name>") \
_ (statseg, "usage: statseg") \
_ (unset, "usage: unset <variable-name>")
#define _(N,n) \
static void vl_api_##n##_t_handler_uni \

View File

@ -13,6 +13,7 @@
* limitations under the License.
*/
#include "vat.h"
#include <dlfcn.h>
#include "plugin.h"
#include <signal.h>
#include <limits.h>
@ -181,7 +182,7 @@ do_one_file (vat_main_t * vam)
if (vam->regenerate_interface_table)
{
vam->regenerate_interface_table = 0;
api_sw_interface_dump (vam);
vam->api_sw_interface_dump (vam);
}
/* Hack to pick up new client index after memfd_segment_create pivot */
@ -380,6 +381,30 @@ vlib_call_init_exit_functions (vlib_main_t *vm,
1 /* do_sort */, is_global);
}
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);
}
}
int
main (int argc, char **argv)
{
@ -484,9 +509,6 @@ main (int argc, char **argv)
vam->json_output = json_output;
if (!json_output)
api_sw_interface_dump (vam);
vec_validate (vam->inbuf, 4096);
load_features ();
@ -494,6 +516,11 @@ main (int argc, char **argv)
vam->current_file = (u8 *) "plugin-init";
vat_plugin_init (vam);
vat_register_interface_dump (vam);
if (!json_output)
vam->api_sw_interface_dump (vam);
/* Set up the init function hash table */
vgm->init_functions_called = hash_create (0, 0);

View File

@ -33,6 +33,8 @@
#include <vlib/unix/unix.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vlibmemory/memclnt.api_enum.h>
#include <vlibmemory/memclnt.api_types.h>
#include "vat/json_format.h"
@ -232,6 +234,8 @@ typedef struct
struct vat_registered_features_t *feature_function_registrations;
int (*api_sw_interface_dump) ();
/* Convenience */
vlib_main_t *vlib_main;
} vat_main_t;
@ -295,6 +299,25 @@ static void __vlib_add_config_function_##x (void) \
.function = x, \
}
#if VPP_API_TEST_BUILTIN == 0
static_always_inline uword
api_unformat_sw_if_index (unformat_input_t *input, va_list *args)
{
vat_main_t *vam = va_arg (*args, vat_main_t *);
u32 *result = va_arg (*args, u32 *);
u8 *if_name;
uword *p;
if (!unformat (input, "%s", &if_name))
return 0;
p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
if (p == 0)
return 0;
*result = p[0];
return 1;
}
#endif /* VPP_API_TEST_BUILTIN */
#endif /* __included_vat_h__ */