From f0e67d78ae23ff3d5751ea10e9e76cb6e81ba4a5 Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Fri, 23 Jul 2021 22:03:05 +0000 Subject: interface: add api test file Type: improvement Signed-off-by: Filip Tehlar Change-Id: Ib07029204ecf12bf2adb5a39afa54bc98fb81f34 --- src/plugins/arping/arping_test.c | 4 +- src/plugins/gtpu/gtpu_test.c | 18 - src/vat/api_format.c | 212 +++++-- src/vat/main.c | 35 +- src/vat/vat.h | 23 + src/vat2/vat2_helpers.h | 2 +- src/vlibapi/vat_helper_macros.h | 13 +- src/vlibmemory/memclnt.api | 25 + src/vlibmemory/memclnt_api.c | 18 +- src/vlibmemory/vlib.api | 26 +- src/vlibmemory/vlib_api.c | 13 - src/vlibmemory/vlibapi_test.c | 25 - src/vnet/CMakeLists.txt | 1 + src/vnet/interface_test.c | 1170 ++++++++++++++++++++++++++++++++++++ src/vnet/ip/ip_test.c | 23 +- src/vpp-api/client/test.c | 2 + src/vpp-api/vapi/vapi.c | 2 +- src/vpp-api/vapi/vapi_c_gen.py | 2 +- src/vpp-api/vapi/vapi_c_test.c | 2 + src/vpp-api/vapi/vapi_cpp_test.cpp | 1 + src/vpp/api/api_main.c | 31 +- 21 files changed, 1484 insertions(+), 164 deletions(-) create mode 100644 src/vnet/interface_test.c diff --git a/src/plugins/arping/arping_test.c b/src/plugins/arping/arping_test.c index ac4349d20d2..00b0b98ab9a 100644 --- a/src/plugins/arping/arping_test.c +++ b/src/plugins/arping/arping_test.c @@ -52,7 +52,6 @@ api_arping (vat_main_t *vam) arping_args_t args = { 0 }; int ret; unformat_input_t *input = vam->input; - vnet_main_t *vnm = vnet_get_main (); f64 interval = ARPING_DEFAULT_INTERVAL; vl_api_control_ping_t *mp_ping; arping_test_main_t *atm = &arping_test_main; @@ -76,8 +75,7 @@ api_arping (vat_main_t *vam) return -99; } - if (!unformat_user (input, unformat_vnet_sw_interface, vnm, - &args.sw_if_index)) + if (!unformat_user (input, api_unformat_sw_if_index, vam, &args.sw_if_index)) { errmsg ("unknown interface `%U'", format_unformat_error, input); return -99; diff --git a/src/plugins/gtpu/gtpu_test.c b/src/plugins/gtpu/gtpu_test.c index 373e7888341..dcfe3d02666 100644 --- a/src/plugins/gtpu/gtpu_test.c +++ b/src/plugins/gtpu/gtpu_test.c @@ -90,24 +90,6 @@ static void vl_api_gtpu_add_del_tunnel_reply_t_handler } } -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; -} - static uword api_unformat_hw_if_index (unformat_input_t * input, va_list * args) { diff --git a/src/vat/api_format.c b/src/vat/api_format.c index 61ac92fac38..a759ba25b1f 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -57,6 +57,8 @@ #include #include +#include +#include #define vl_endianfun /* define message structures */ #include @@ -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 ") \ _(sock_init_shm, "size ") \ /* List of command functions, CLI names map directly to functions */ -#define foreach_cli_function \ -_(comment, "usage: comment ") \ -_(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 ") \ -_(get_msg_id, "usage: get_msg_id name_and_crc") \ -_(echo, "usage: echo ") \ -_(help, "usage: help") \ -_(q, "usage: quit") \ -_(quit, "usage: quit") \ -_(search_node_table, "usage: search_node_table ...") \ -_(set, "usage: set ") \ -_(script, "usage: script ") \ -_(statseg, "usage: statseg") \ -_(unset, "usage: unset ") +#define foreach_cli_function \ + _ (comment, "usage: comment ") \ + _ (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 ") \ + _ (get_msg_id, "usage: get_msg_id name_and_crc") \ + _ (echo, "usage: echo ") \ + _ (help, "usage: help") \ + _ (q, "usage: quit") \ + _ (quit, "usage: quit") \ + _ (search_node_table, "usage: search_node_table ...") \ + _ (set, "usage: set ") \ + _ (script, "usage: script ") \ + _ (statseg, "usage: statseg") \ + _ (unset, "usage: unset ") #define _(N,n) \ static void vl_api_##n##_t_handler_uni \ diff --git a/src/vat/main.c b/src/vat/main.c index c718197e30d..d052493495d 100644 --- a/src/vat/main.c +++ b/src/vat/main.c @@ -13,6 +13,7 @@ * limitations under the License. */ #include "vat.h" +#include #include "plugin.h" #include #include @@ -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); diff --git a/src/vat/vat.h b/src/vat/vat.h index 32de90e4411..10199e3e9e6 100644 --- a/src/vat/vat.h +++ b/src/vat/vat.h @@ -33,6 +33,8 @@ #include #include #include +#include +#include #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__ */ diff --git a/src/vat2/vat2_helpers.h b/src/vat2/vat2_helpers.h index beb2a787659..7b197608a7b 100644 --- a/src/vat2/vat2_helpers.h +++ b/src/vat2/vat2_helpers.h @@ -20,7 +20,7 @@ /* For control ping */ #define vl_endianfun -#include +#include #undef vl_endianfun static inline void diff --git a/src/vlibapi/vat_helper_macros.h b/src/vlibapi/vat_helper_macros.h index 2e1b9422bf7..1dd597cce96 100644 --- a/src/vlibapi/vat_helper_macros.h +++ b/src/vlibapi/vat_helper_macros.h @@ -65,13 +65,16 @@ do { \ #define PING(_tm, mp_ping) \ do \ { \ - if (!(_tm)->ping_id) \ - (_tm)->ping_id = \ - vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC)); \ - mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping)); \ - mp_ping->_vl_msg_id = htons ((_tm)->ping_id); \ + socket_client_main_t *scm = vam->socket_client_main; \ + if (scm && scm->socket_enable) \ + mp_ping = vl_socket_client_msg_alloc (sizeof (*mp_ping)); \ + else \ + mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping)); \ + mp_ping->_vl_msg_id = htons (VL_API_CONTROL_PING + 1); \ mp_ping->client_index = vam->my_client_index; \ vam->result_ready = 0; \ + if (scm) \ + scm->control_pings_outstanding++; \ } \ while (0); diff --git a/src/vlibmemory/memclnt.api b/src/vlibmemory/memclnt.api index a5194cd58c4..bd999b51dd0 100644 --- a/src/vlibmemory/memclnt.api +++ b/src/vlibmemory/memclnt.api @@ -207,3 +207,28 @@ autoreply define memclnt_keepalive u32 client_index; u32 context; }; + +/** \brief Control ping from client to api server request + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request +*/ +define control_ping +{ + u32 client_index; + u32 context; +}; + +/** \brief Control ping from the client to the server response + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param retval - return code for the request + @param vpe_pid - the pid of the vpe, returned by the server +*/ +define control_ping_reply +{ + u32 context; + i32 retval; + u32 client_index; + u32 vpe_pid; +}; + diff --git a/src/vlibmemory/memclnt_api.c b/src/vlibmemory/memclnt_api.c index e7d689b614a..2b4a2393db3 100644 --- a/src/vlibmemory/memclnt_api.c +++ b/src/vlibmemory/memclnt_api.c @@ -29,6 +29,7 @@ #include #include #include +#include /** * @file @@ -131,9 +132,20 @@ vl_api_api_versions_t_handler (vl_api_api_versions_t *mp) vl_api_send_msg (reg, (u8 *) rmp); } +static void +vl_api_control_ping_t_handler (vl_api_control_ping_t *mp) +{ + vl_api_control_ping_reply_t *rmp; + int rv = 0; + + REPLY_MACRO2 (VL_API_CONTROL_PING_REPLY, + ({ rmp->vpe_pid = ntohl (getpid ()); })); +} + #define foreach_vlib_api_msg \ _ (GET_FIRST_MSG_ID, get_first_msg_id) \ - _ (API_VERSIONS, api_versions) + _ (API_VERSIONS, api_versions) \ + _ (CONTROL_PING, control_ping) /* * vl_api_init @@ -141,6 +153,7 @@ vl_api_api_versions_t_handler (vl_api_api_versions_t *mp) static int vlib_api_init (void) { + api_main_t *am = vlibapi_get_main (); vl_msg_api_msg_config_t cfg; vl_msg_api_msg_config_t *c = &cfg; @@ -175,6 +188,9 @@ vlib_api_init (void) foreach_vlib_api_msg; #undef _ + am->is_mp_safe[VL_API_CONTROL_PING] = 1; + am->is_mp_safe[VL_API_CONTROL_PING_REPLY] = 1; + return 0; } diff --git a/src/vlibmemory/vlib.api b/src/vlibmemory/vlib.api index c017fc7919a..ce1236826aa 100644 --- a/src/vlibmemory/vlib.api +++ b/src/vlibmemory/vlib.api @@ -243,32 +243,8 @@ define get_f64_increment_by_one_reply f64 f64_value; }; -/** \brief Control ping from client to api server request - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request -*/ -define control_ping -{ - u32 client_index; - u32 context; -}; - -/** \brief Control ping from the client to the server response - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param retval - return code for the request - @param vpe_pid - the pid of the vpe, returned by the server -*/ -define control_ping_reply -{ - u32 context; - i32 retval; - u32 client_index; - u32 vpe_pid; -}; - /* * Local Variables: * eval: (c-set-style "gnu") * End: - */ \ No newline at end of file + */ diff --git a/src/vlibmemory/vlib_api.c b/src/vlibmemory/vlib_api.c index 6962ea01f5d..b598f0b9852 100644 --- a/src/vlibmemory/vlib_api.c +++ b/src/vlibmemory/vlib_api.c @@ -329,16 +329,6 @@ vl_api_get_f64_increment_by_one_t_handler ( })); } -static void -vl_api_control_ping_t_handler (vl_api_control_ping_t *mp) -{ - vl_api_control_ping_reply_t *rmp; - int rv = 0; - - REPLY_MACRO2 (VL_API_CONTROL_PING_REPLY, - ({ rmp->vpe_pid = ntohl (getpid ()); })); -} - #include static clib_error_t * vlib_apis_hookup (vlib_main_t *vm) @@ -351,9 +341,6 @@ vlib_apis_hookup (vlib_main_t *vm) msg_id_base = setup_message_id_table (); am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1; - am->is_mp_safe[VL_API_CONTROL_PING] = 1; - am->is_mp_safe[VL_API_CONTROL_PING_REPLY] = 1; - return 0; } diff --git a/src/vlibmemory/vlibapi_test.c b/src/vlibmemory/vlibapi_test.c index c91cd7942f9..820096ab80d 100644 --- a/src/vlibmemory/vlibapi_test.c +++ b/src/vlibmemory/vlibapi_test.c @@ -449,31 +449,6 @@ api_get_node_graph (vat_main_t *vam) return ret; } -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 int -api_control_ping (vat_main_t *vam) -{ - // not yet implemented - return -1; -} - #define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE local_setup_message_id_table static void local_setup_message_id_table (vat_main_t *vam) diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 5e1cbc24fd1..3b19108cb61 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -1522,6 +1522,7 @@ add_vpp_library (vatclient ) add_vat_test_library(vnet + interface_test.c ip/ip_test.c arp/arp_test.c ip6-nd/ip6_nd_test.c diff --git a/src/vnet/interface_test.c b/src/vnet/interface_test.c new file mode 100644 index 00000000000..4a1681f4eac --- /dev/null +++ b/src/vnet/interface_test.c @@ -0,0 +1,1170 @@ +/* + *------------------------------------------------------------------ + * Copyright (c) 2021 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------ + */ + +#include +#include +#include +#include +#include + +#include + +#define __plugin_msg_base interface_test_main.msg_id_base +#include + +/* Declare message IDs */ +#include +#include +#include +#include +#include + +#define vl_endianfun /* define message structures */ +#include +#undef vl_endianfun + +typedef struct +{ + /* API message ID base */ + u16 msg_id_base; + vat_main_t *vat_main; +} interface_test_main_t; + +static interface_test_main_t interface_test_main; + +static int +api_sw_interface_set_flags (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_set_flags_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + u8 admin_up = 0; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "admin-up")) + admin_up = 1; + else if (unformat (i, "admin-down")) + admin_up = 0; + else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else + break; + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + /* Construct the API message */ + M (SW_INTERFACE_SET_FLAGS, mp); + mp->sw_if_index = ntohl (sw_if_index); + mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0); + + /* send it... */ + S (mp); + + /* Wait for a reply, return the good/bad news... */ + W (ret); + return ret; +} + +static int +api_hw_interface_set_mtu (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_hw_interface_set_mtu_t *mp; + u32 sw_if_index = ~0; + u32 mtu = 0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "mtu %d", &mtu)) + ; + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + ; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + ; + else + break; + } + + if (sw_if_index == ~0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + if (mtu == 0) + { + errmsg ("no mtu specified"); + return -99; + } + + /* Construct the API message */ + M (HW_INTERFACE_SET_MTU, mp); + mp->sw_if_index = ntohl (sw_if_index); + mp->mtu = ntohs ((u16) mtu); + + S (mp); + W (ret); + return ret; +} + +static int +api_sw_interface_tag_add_del (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_tag_add_del_t *mp; + u32 sw_if_index = ~0; + u8 *tag = 0; + u8 enable = 1; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "tag %s", &tag)) + ; + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + ; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + ; + else if (unformat (i, "del")) + enable = 0; + else + break; + } + + if (sw_if_index == ~0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + if (enable && (tag == 0)) + { + errmsg ("no tag specified"); + return -99; + } + + /* Construct the API message */ + M (SW_INTERFACE_TAG_ADD_DEL, mp); + mp->sw_if_index = ntohl (sw_if_index); + mp->is_add = enable; + if (enable) + strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1); + vec_free (tag); + + S (mp); + W (ret); + return ret; +} + +static int +api_sw_interface_add_del_mac_address (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_mac_address_t mac = { 0 }; + vl_api_sw_interface_add_del_mac_address_t *mp; + u32 sw_if_index = ~0; + u8 is_add = 1; + u8 mac_set = 0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + ; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + ; + else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac)) + mac_set++; + else if (unformat (i, "del")) + is_add = 0; + else + break; + } + + if (sw_if_index == ~0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + if (!mac_set) + { + errmsg ("missing MAC address"); + return -99; + } + + /* Construct the API message */ + M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp); + mp->sw_if_index = ntohl (sw_if_index); + mp->is_add = is_add; + clib_memcpy (&mp->addr, &mac, sizeof (mac)); + + S (mp); + W (ret); + return ret; +} + +static void +vl_api_sw_interface_details_t_handler (vl_api_sw_interface_details_t *mp) +{ + vat_main_t *vam = &vat_main; + u8 *s = format (0, "%s%c", mp->interface_name, 0); + + hash_set_mem (vam->sw_if_index_by_interface_name, s, + ntohl (mp->sw_if_index)); + + /* In sub interface case, fill the sub interface table entry */ + if (mp->sw_if_index != mp->sup_sw_if_index) + { + sw_interface_subif_t *sub = NULL; + + vec_add2 (vam->sw_if_subif_table, sub, 1); + + vec_validate (sub->interface_name, strlen ((char *) s) + 1); + strncpy ((char *) sub->interface_name, (char *) s, + vec_len (sub->interface_name)); + sub->sw_if_index = ntohl (mp->sw_if_index); + sub->sub_id = ntohl (mp->sub_id); + + sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET); + + sub->sub_number_of_tags = mp->sub_number_of_tags; + sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id); + sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id); + + /* vlan tag rewrite */ + sub->vtr_op = ntohl (mp->vtr_op); + sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q); + sub->vtr_tag1 = ntohl (mp->vtr_tag1); + sub->vtr_tag2 = ntohl (mp->vtr_tag2); + } +} + +static int +api_sw_interface_get_mac_address (vat_main_t *vat) +{ + return -1; +} + +static void +vl_api_sw_interface_get_mac_address_reply_t_handler ( + vl_api_sw_interface_get_mac_address_reply_t *mp) +{ +} + +static int +api_sw_interface_add_del_address (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_add_del_address_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + u8 is_add = 1, del_all = 0; + u32 address_length = 0; + u8 v4_address_set = 0; + u8 v6_address_set = 0; + ip4_address_t v4address; + ip6_address_t v6address; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "del-all")) + del_all = 1; + else if (unformat (i, "del")) + is_add = 0; + else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "%U/%d", unformat_ip4_address, &v4address, + &address_length)) + v4_address_set = 1; + else if (unformat (i, "%U/%d", unformat_ip6_address, &v6address, + &address_length)) + v6_address_set = 1; + else + break; + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + if (v4_address_set && v6_address_set) + { + errmsg ("both v4 and v6 addresses set"); + return -99; + } + if (!v4_address_set && !v6_address_set && !del_all) + { + errmsg ("no addresses set"); + return -99; + } + + /* Construct the API message */ + M (SW_INTERFACE_ADD_DEL_ADDRESS, mp); + + mp->sw_if_index = ntohl (sw_if_index); + mp->is_add = is_add; + mp->del_all = del_all; + if (v6_address_set) + { + mp->prefix.address.af = ADDRESS_IP6; + clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address)); + } + else + { + mp->prefix.address.af = ADDRESS_IP4; + clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address)); + } + mp->prefix.len = address_length; + + /* send it... */ + S (mp); + + /* Wait for a reply, return good/bad news */ + W (ret); + return ret; +} + +static int +api_sw_interface_get_table (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_get_table_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + u8 is_ipv6 = 0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "ipv6")) + is_ipv6 = 1; + else + break; + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + M (SW_INTERFACE_GET_TABLE, mp); + mp->sw_if_index = htonl (sw_if_index); + mp->is_ipv6 = is_ipv6; + + S (mp); + W (ret); + return ret; +} + +static int +api_sw_interface_set_rx_mode (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_set_rx_mode_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + int ret; + u8 queue_id_valid = 0; + u32 queue_id; + vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "queue %d", &queue_id)) + queue_id_valid = 1; + else if (unformat (i, "polling")) + mode = VNET_HW_IF_RX_MODE_POLLING; + else if (unformat (i, "interrupt")) + mode = VNET_HW_IF_RX_MODE_INTERRUPT; + else if (unformat (i, "adaptive")) + mode = VNET_HW_IF_RX_MODE_ADAPTIVE; + else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else + break; + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + if (mode == VNET_HW_IF_RX_MODE_UNKNOWN) + { + errmsg ("missing rx-mode"); + return -99; + } + + /* Construct the API message */ + M (SW_INTERFACE_SET_RX_MODE, mp); + mp->sw_if_index = ntohl (sw_if_index); + mp->mode = (vl_api_rx_mode_t) mode; + mp->queue_id_valid = queue_id_valid; + mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0; + + /* send it... */ + S (mp); + + /* Wait for a reply, return the good/bad news... */ + W (ret); + return ret; +} + +static int +api_sw_interface_set_unnumbered (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_set_unnumbered_t *mp; + u32 sw_if_index; + u32 unnum_sw_index = ~0; + u8 is_add = 1; + u8 sw_if_index_set = 0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "unnum_if_index %d", &unnum_sw_index)) + ; + else if (unformat (i, "del")) + is_add = 0; + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + M (SW_INTERFACE_SET_UNNUMBERED, mp); + + mp->sw_if_index = ntohl (sw_if_index); + mp->unnumbered_sw_if_index = ntohl (unnum_sw_index); + mp->is_add = is_add; + + S (mp); + W (ret); + return ret; +} + +static void +vl_api_sw_interface_get_table_reply_t_handler ( + vl_api_sw_interface_get_table_reply_t *mp) +{ + vat_main_t *vam = interface_test_main.vat_main; + + fformat (vam->ofp, "%d", ntohl (mp->vrf_id)); + + vam->retval = ntohl (mp->retval); + vam->result_ready = 1; +} + +static int +api_sw_interface_address_replace_begin (vat_main_t *vam) +{ + return -1; +} + +static int +api_sw_interface_set_mac_address (vat_main_t *vam) +{ + return -1; +} + +static int +api_sw_interface_set_rx_placement (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_set_rx_placement_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + int ret; + u8 is_main = 0; + u32 queue_id, thread_index; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "queue %d", &queue_id)) + ; + else if (unformat (i, "main")) + is_main = 1; + else if (unformat (i, "worker %d", &thread_index)) + ; + else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else + break; + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + if (is_main) + thread_index = 0; + /* Construct the API message */ + M (SW_INTERFACE_SET_RX_PLACEMENT, mp); + mp->sw_if_index = ntohl (sw_if_index); + mp->worker_id = ntohl (thread_index); + mp->queue_id = ntohl (queue_id); + mp->is_main = is_main; + + /* send it... */ + S (mp); + /* Wait for a reply, return the good/bad news... */ + W (ret); + return ret; +} + +static int +api_interface_name_renumber (vat_main_t *vam) +{ + unformat_input_t *line_input = vam->input; + vl_api_interface_name_renumber_t *mp; + u32 sw_if_index = ~0; + u32 new_show_dev_instance = ~0; + int ret; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%U", api_unformat_sw_if_index, vam, + &sw_if_index)) + ; + else if (unformat (line_input, "sw_if_index %d", &sw_if_index)) + ; + else if (unformat (line_input, "new_show_dev_instance %d", + &new_show_dev_instance)) + ; + else + break; + } + + if (sw_if_index == ~0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + if (new_show_dev_instance == ~0) + { + errmsg ("missing new_show_dev_instance"); + return -99; + } + + M (INTERFACE_NAME_RENUMBER, mp); + + mp->sw_if_index = ntohl (sw_if_index); + mp->new_show_dev_instance = ntohl (new_show_dev_instance); + + S (mp); + W (ret); + return ret; +} + +static int +api_delete_subif (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_delete_subif_t *mp; + u32 sw_if_index = ~0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + ; + if (unformat (i, "sw_if_index %d", &sw_if_index)) + ; + else + break; + } + + if (sw_if_index == ~0) + { + errmsg ("missing sw_if_index"); + return -99; + } + + /* Construct the API message */ + M (DELETE_SUBIF, mp); + mp->sw_if_index = ntohl (sw_if_index); + + S (mp); + W (ret); + return ret; +} + +static int +api_delete_loopback (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_delete_loopback_t *mp; + u32 sw_if_index = ~0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "sw_if_index %d", &sw_if_index)) + ; + else + break; + } + + if (sw_if_index == ~0) + { + errmsg ("missing sw_if_index"); + return -99; + } + + /* Construct the API message */ + M (DELETE_LOOPBACK, mp); + mp->sw_if_index = ntohl (sw_if_index); + + S (mp); + W (ret); + return ret; +} + +static int +api_create_loopback_instance (vat_main_t *vat) +{ + return -1; +} + +static int +api_create_loopback (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_create_loopback_t *mp; + vl_api_create_loopback_instance_t *mp_lbi; + u8 mac_address[6]; + u8 mac_set = 0; + u8 is_specified = 0; + u32 user_instance = 0; + int ret; + + clib_memset (mac_address, 0, sizeof (mac_address)); + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) + mac_set = 1; + if (unformat (i, "instance %d", &user_instance)) + is_specified = 1; + else + break; + } + + if (is_specified) + { + M (CREATE_LOOPBACK_INSTANCE, mp_lbi); + mp_lbi->is_specified = is_specified; + if (is_specified) + mp_lbi->user_instance = htonl (user_instance); + if (mac_set) + clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address)); + S (mp_lbi); + } + else + { + /* Construct the API message */ + M (CREATE_LOOPBACK, mp); + if (mac_set) + clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address)); + S (mp); + } + + W (ret); + return ret; +} + +static void +vl_api_create_subif_reply_t_handler (vl_api_create_subif_reply_t *mp) +{ + vat_main_t *vam = interface_test_main.vat_main; + vam->result_ready = 1; +} + +#define foreach_create_subif_bit \ + _ (no_tags) \ + _ (one_tag) \ + _ (two_tags) \ + _ (dot1ad) \ + _ (exact_match) \ + _ (default_sub) \ + _ (outer_vlan_id_any) \ + _ (inner_vlan_id_any) + +#define foreach_create_subif_flag \ + _ (0, "no_tags") \ + _ (1, "one_tag") \ + _ (2, "two_tags") \ + _ (3, "dot1ad") \ + _ (4, "exact_match") \ + _ (5, "default_sub") \ + _ (6, "outer_vlan_id_any") \ + _ (7, "inner_vlan_id_any") + +static int +api_create_subif (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_create_subif_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + u32 sub_id; + u8 sub_id_set = 0; + u32 __attribute__ ((unused)) no_tags = 0; + u32 __attribute__ ((unused)) one_tag = 0; + u32 __attribute__ ((unused)) two_tags = 0; + u32 __attribute__ ((unused)) dot1ad = 0; + u32 __attribute__ ((unused)) exact_match = 0; + u32 __attribute__ ((unused)) default_sub = 0; + u32 __attribute__ ((unused)) outer_vlan_id_any = 0; + u32 __attribute__ ((unused)) inner_vlan_id_any = 0; + u32 tmp; + u16 outer_vlan_id = 0; + u16 inner_vlan_id = 0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sub_id %d", &sub_id)) + sub_id_set = 1; + else if (unformat (i, "outer_vlan_id %d", &tmp)) + outer_vlan_id = tmp; + else if (unformat (i, "inner_vlan_id %d", &tmp)) + inner_vlan_id = tmp; + +#define _(a) else if (unformat (i, #a)) a = 1; + foreach_create_subif_bit +#undef _ + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + if (sub_id_set == 0) + { + errmsg ("missing sub_id"); + return -99; + } + M (CREATE_SUBIF, mp); + + mp->sw_if_index = ntohl (sw_if_index); + mp->sub_id = ntohl (sub_id); + +#define _(a, b) mp->sub_if_flags |= (1 << a); + foreach_create_subif_flag; +#undef _ + + mp->outer_vlan_id = ntohs (outer_vlan_id); + mp->inner_vlan_id = ntohs (inner_vlan_id); + + S (mp); + W (ret); + return ret; +} + +static void +vl_api_sw_interface_rx_placement_details_t_handler ( + vl_api_sw_interface_rx_placement_details_t *mp) +{ + vat_main_t *vam = interface_test_main.vat_main; + u32 worker_id = ntohl (mp->worker_id); + + print (vam->ofp, "\n%-11d %-11s %-6d %-5d %-9s", ntohl (mp->sw_if_index), + (worker_id == 0) ? "main" : "worker", worker_id, ntohl (mp->queue_id), + (mp->mode == 1) ? "polling" : + ((mp->mode == 2) ? "interrupt" : "adaptive")); +} + +static void +vl_api_create_vlan_subif_reply_t_handler (vl_api_create_vlan_subif_reply_t *mp) +{ + vat_main_t *vam = interface_test_main.vat_main; + vam->result_ready = 1; +} + +static void +vl_api_create_loopback_reply_t_handler (vl_api_create_loopback_reply_t *mp) +{ + vat_main_t *vam = interface_test_main.vat_main; + vam->result_ready = 1; +} + +static void +vl_api_create_loopback_instance_reply_t_handler ( + vl_api_create_loopback_instance_reply_t *mp) +{ + vat_main_t *vam = interface_test_main.vat_main; + vam->result_ready = 1; +} + +static int +api_create_vlan_subif (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_create_vlan_subif_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + u32 vlan_id; + u8 vlan_id_set = 0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "vlan %d", &vlan_id)) + vlan_id_set = 1; + else + { + clib_warning ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + if (vlan_id_set == 0) + { + errmsg ("missing vlan_id"); + return -99; + } + M (CREATE_VLAN_SUBIF, mp); + + mp->sw_if_index = ntohl (sw_if_index); + mp->vlan_id = ntohl (vlan_id); + + S (mp); + W (ret); + return ret; +} + +static int +api_collect_detailed_interface_stats (vat_main_t *vam) +{ + return -1; +} + +static int +api_sw_interface_rx_placement_dump (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_rx_placement_dump_t *mp; + vl_api_control_ping_t *mp_ping; + int ret; + u32 sw_if_index; + u8 sw_if_index_set = 0; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set++; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set++; + else + break; + } + + fformat (vam->ofp, "\n%-11s %-11s %-6s %-5s %-4s", "sw_if_index", + "main/worker", "thread", "queue", "mode"); + + /* Dump Interface rx placement */ + M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp); + + if (sw_if_index_set) + mp->sw_if_index = htonl (sw_if_index); + else + mp->sw_if_index = ~0; + + S (mp); + + /* Use a control ping for synchronization */ + PING (&interface_test_main, mp_ping); + S (mp_ping); + + W (ret); + return ret; +} + +static int +api_sw_interface_clear_stats (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_clear_stats_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else + break; + } + + /* Construct the API message */ + M (SW_INTERFACE_CLEAR_STATS, mp); + + if (sw_if_index_set == 1) + mp->sw_if_index = ntohl (sw_if_index); + else + mp->sw_if_index = ~0; + + /* send it... */ + S (mp); + + /* Wait for a reply, return the good/bad news... */ + W (ret); + return ret; +} + +static int +api_sw_interface_set_table (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_set_table_t *mp; + u32 sw_if_index, vrf_id = 0; + u8 sw_if_index_set = 0; + u8 is_ipv6 = 0; + int ret; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "vrf %d", &vrf_id)) + ; + else if (unformat (i, "ipv6")) + is_ipv6 = 1; + else + break; + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + + /* Construct the API message */ + M (SW_INTERFACE_SET_TABLE, mp); + + mp->sw_if_index = ntohl (sw_if_index); + mp->is_ipv6 = is_ipv6; + mp->vrf_id = ntohl (vrf_id); + + /* send it... */ + S (mp); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static int +api_sw_interface_address_replace_end (vat_main_t *vam) +{ + return -1; +} + +static int +api_sw_interface_set_ip_directed_broadcast (vat_main_t *vam) +{ + return -1; +} + +static int +api_sw_interface_set_mtu (vat_main_t *vam) +{ + return -1; +} + +static int +api_sw_interface_set_promisc (vat_main_t *vam) +{ + return -1; +} + +static int +api_want_interface_events (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + vl_api_want_interface_events_t *mp; + int enable = -1; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "enable")) + enable = 1; + else if (unformat (i, "disable")) + enable = 0; + else + break; + } + + if (enable == -1) + { + errmsg ("missing enable|disable"); + return -99; + } + + M (WANT_INTERFACE_EVENTS, mp); + mp->enable_disable = enable; + + vam->interface_event_display = enable; + + S (mp); + W (ret); + return ret; +} + +typedef struct +{ + u8 *name; + u32 value; +} name_sort_t; + +int +api_sw_interface_dump (vat_main_t *vam) +{ + vl_api_sw_interface_dump_t *mp; + vl_api_control_ping_t *mp_ping; + hash_pair_t *p; + name_sort_t *nses = 0, *ns; + sw_interface_subif_t *sub = NULL; + int ret; + + /* Toss the old name table */ + 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]; + })); + + hash_free (vam->sw_if_index_by_interface_name); + + vec_foreach (ns, nses) + vec_free (ns->name); + + vec_free (nses); + + vec_foreach (sub, vam->sw_if_subif_table) + { + vec_free (sub->interface_name); + } + vec_free (vam->sw_if_subif_table); + + /* recreate the interface name hash table */ + vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword)); + + /* + * Ask for all interface names. Otherwise, the epic catalog of + * name filters becomes ridiculously long, and vat ends up needing + * to be taught about new interface types. + */ + M (SW_INTERFACE_DUMP, mp); + S (mp); + + /* Use a control ping for synchronization */ + PING (&interface_test_main, mp_ping); + S (mp_ping); + + W (ret); + return ret; +} + +static int +api_sw_interface_set_interface_name (vat_main_t *vam) +{ + return -1; +} + +#include + +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vnet/ip/ip_test.c b/src/vnet/ip/ip_test.c index 3ba38d3470e..c47cd3d208e 100644 --- a/src/vnet/ip/ip_test.c +++ b/src/vnet/ip/ip_test.c @@ -40,7 +40,6 @@ typedef struct { /* API message ID base */ u16 msg_id_base; - u32 ping_id; vat_main_t *vat_main; } ip_test_main_t; @@ -100,7 +99,7 @@ increment_address (vl_api_address_t *a) static uword unformat_fib_path (unformat_input_t *input, va_list *args) { - vnet_main_t *vnm = va_arg (*args, vnet_main_t *); + vat_main_t *vam = va_arg (*args, vat_main_t *); vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *); u32 weight, preference; mpls_label_t out_label; @@ -114,14 +113,14 @@ unformat_fib_path (unformat_input_t *input, va_list *args) while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "%U %U", unformat_vl_api_ip4_address, - &path->nh.address.ip4, unformat_vnet_sw_interface, vnm, + &path->nh.address.ip4, api_unformat_sw_if_index, vam, &path->sw_if_index)) { path->proto = FIB_API_PATH_NH_PROTO_IP4; } else if (unformat (input, "%U %U", unformat_vl_api_ip6_address, - &path->nh.address.ip6, unformat_vnet_sw_interface, - vnm, &path->sw_if_index)) + &path->nh.address.ip6, api_unformat_sw_if_index, vam, + &path->sw_if_index)) { path->proto = FIB_API_PATH_NH_PROTO_IP6; } @@ -238,7 +237,6 @@ unformat_fib_path (unformat_input_t *input, va_list *args) static int api_ip_route_add_del (vat_main_t *vam) { - vnet_main_t *vnm = vnet_get_main (); unformat_input_t *i = vam->input; vl_api_ip_route_add_del_t *mp; u32 vrf_id = 0; @@ -274,7 +272,7 @@ api_ip_route_add_del (vat_main_t *vam) is_multipath = 1; else if (unformat (i, "seed %d", &random_seed)) ; - else if (unformat (i, "via %U", unformat_fib_path, vnm, + else if (unformat (i, "via %U", unformat_fib_path, vam, &paths[path_count])) { path_count++; @@ -704,7 +702,6 @@ vl_api_ip_punt_redirect_v2_details_t_handler ( static int api_ip_address_dump (vat_main_t *vam) { - vnet_main_t *vnm = vnet_get_main (); unformat_input_t *i = vam->input; vl_api_ip_address_dump_t *mp; vl_api_control_ping_t *mp_ping; @@ -718,8 +715,7 @@ api_ip_address_dump (vat_main_t *vam) { if (unformat (i, "sw_if_index %d", &sw_if_index)) sw_if_index_set = 1; - else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, - &sw_if_index)) + else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) sw_if_index_set = 1; else if (unformat (i, "ipv4")) ipv4_set = 1; @@ -1022,7 +1018,6 @@ vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp) int api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam) { - vnet_main_t *vnm = vnet_get_main (); unformat_input_t *input = vam->input; vl_api_ip_source_and_port_range_check_interface_add_del_t *mp; u32 sw_if_index = ~0; @@ -1034,8 +1029,7 @@ api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam) while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, - &sw_if_index)) + if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) ; else if (unformat (input, "sw_if_index %d", &sw_if_index)) ; @@ -1214,7 +1208,6 @@ api_ip_mroute_dump (vat_main_t *vam) static int api_sw_interface_ip6_enable_disable (vat_main_t *vam) { - vnet_main_t *vnm = vnet_get_main (); unformat_input_t *i = vam->input; vl_api_sw_interface_ip6_enable_disable_t *mp; u32 sw_if_index; @@ -1224,7 +1217,7 @@ api_sw_interface_ip6_enable_disable (vat_main_t *vam) while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { - if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index)) + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) sw_if_index_set = 1; else if (unformat (i, "sw_if_index %d", &sw_if_index)) sw_if_index_set = 1; diff --git a/src/vpp-api/client/test.c b/src/vpp-api/client/test.c index b7e6f017445..9855ffa1880 100644 --- a/src/vpp-api/client/test.c +++ b/src/vpp-api/client/test.c @@ -38,6 +38,8 @@ #include #include +#include +#include #include #include diff --git a/src/vpp-api/vapi/vapi.c b/src/vpp-api/vapi/vapi.c index 1bd8e5bdd9f..513ff98b30c 100644 --- a/src/vpp-api/vapi/vapi.c +++ b/src/vpp-api/vapi/vapi.c @@ -31,8 +31,8 @@ #include #include -#include #include +#include /* we need to use control pings for some stuff and because we're forced to put * the code in headers, we need a way to be able to grab the ids of these diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index eacfab41555..1a5665e5500 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -705,7 +705,7 @@ def gen_json_unified_header(parser, logger, j, io, name): print("#ifdef __cplusplus") print("extern \"C\" {") print("#endif") - if name == "vlib.api.vapi.h": + if name == "memclnt.api.vapi.h": print("") print("static inline vapi_error_e vapi_send_with_control_ping " "(vapi_ctx_t ctx, void * msg, u32 context);") diff --git a/src/vpp-api/vapi/vapi_c_test.c b/src/vpp-api/vapi/vapi_c_test.c index 52b930d422f..85fc8b3504c 100644 --- a/src/vpp-api/vapi/vapi_c_test.c +++ b/src/vpp-api/vapi/vapi_c_test.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/src/vpp-api/vapi/vapi_cpp_test.cpp b/src/vpp-api/vapi/vapi_cpp_test.cpp index c574dd70b96..c0e0cdc3ab8 100644 --- a/src/vpp-api/vapi/vapi_cpp_test.cpp +++ b/src/vpp-api/vapi/vapi_cpp_test.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/src/vpp/api/api_main.c b/src/vpp/api/api_main.c index 97dec9e1542..9b915eeffcf 100644 --- a/src/vpp/api/api_main.c +++ b/src/vpp/api/api_main.c @@ -1,4 +1,6 @@ #include "vat.h" +#include +#include vat_main_t vat_main; @@ -93,6 +95,30 @@ 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) { @@ -130,7 +156,8 @@ maybe_register_api_client (vat_main_t * vam) am->shmem_hdr->application_restarts); vam->vl_input_queue = am->shmem_hdr->vl_input_queue; - api_sw_interface_dump (vam); + vat_register_interface_dump (vam); + vam->api_sw_interface_dump (vam); } static clib_error_t * @@ -234,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; -- cgit 1.2.3-korg