interface: add api test file
Type: improvement
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
Change-Id: Ib07029204ecf12bf2adb5a39afa54bc98fb81f34
diff --git a/src/plugins/arping/arping_test.c b/src/plugins/arping/arping_test.c
index ac4349d..00b0b98 100644
--- a/src/plugins/arping/arping_test.c
+++ b/src/plugins/arping/arping_test.c
@@ -52,7 +52,6 @@
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 @@
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 373e788..dcfe3d0 100644
--- a/src/plugins/gtpu/gtpu_test.c
+++ b/src/plugins/gtpu/gtpu_test.c
@@ -91,24 +91,6 @@
}
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)
{
return 0;
diff --git a/src/vat/api_format.c b/src/vat/api_format.c
index 61ac92f..a759ba2 100644
--- a/src/vat/api_format.c
+++ b/src/vat/api_format.c
@@ -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 @@
}
#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 @@
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 \
diff --git a/src/vat/main.c b/src/vat/main.c
index c718197..d052493 100644
--- a/src/vat/main.c
+++ b/src/vat/main.c
@@ -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 @@
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 @@
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 @@
vam->json_output = json_output;
- if (!json_output)
- api_sw_interface_dump (vam);
-
vec_validate (vam->inbuf, 4096);
load_features ();
@@ -494,6 +516,11 @@
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 32de90e..10199e3 100644
--- a/src/vat/vat.h
+++ b/src/vat/vat.h
@@ -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 @@
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 @@
.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 beb2a78..7b19760 100644
--- a/src/vat2/vat2_helpers.h
+++ b/src/vat2/vat2_helpers.h
@@ -20,7 +20,7 @@
/* For control ping */
#define vl_endianfun
-#include <vlibmemory/vlib.api.h>
+#include <vlibmemory/memclnt.api.h>
#undef vl_endianfun
static inline void
diff --git a/src/vlibapi/vat_helper_macros.h b/src/vlibapi/vat_helper_macros.h
index 2e1b942..1dd597c 100644
--- a/src/vlibapi/vat_helper_macros.h
+++ b/src/vlibapi/vat_helper_macros.h
@@ -65,13 +65,16 @@
#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 a5194cd..bd999b5 100644
--- a/src/vlibmemory/memclnt.api
+++ b/src/vlibmemory/memclnt.api
@@ -207,3 +207,28 @@
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 e7d689b..2b4a239 100644
--- a/src/vlibmemory/memclnt_api.c
+++ b/src/vlibmemory/memclnt_api.c
@@ -29,6 +29,7 @@
#include <vlib/unix/unix.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
+#include <vlibapi/api_helper_macros.h>
/**
* @file
@@ -131,9 +132,20 @@
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 @@
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 @@
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 c017fc7..ce12368 100644
--- a/src/vlibmemory/vlib.api
+++ b/src/vlibmemory/vlib.api
@@ -243,32 +243,8 @@
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 6962ea0..b598f0b 100644
--- a/src/vlibmemory/vlib_api.c
+++ b/src/vlibmemory/vlib_api.c
@@ -329,16 +329,6 @@
}));
}
-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 <vlibmemory/vlib.api.c>
static clib_error_t *
vlib_apis_hookup (vlib_main_t *vm)
@@ -351,9 +341,6 @@
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 c91cd79..820096a 100644
--- a/src/vlibmemory/vlibapi_test.c
+++ b/src/vlibmemory/vlibapi_test.c
@@ -449,31 +449,6 @@
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 5e1cbc2..3b19108 100644
--- a/src/vnet/CMakeLists.txt
+++ b/src/vnet/CMakeLists.txt
@@ -1522,6 +1522,7 @@
)
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 0000000..4a1681f
--- /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 <vat/vat.h>
+#include <vlibapi/api.h>
+#include <vlibmemory/api.h>
+#include <vppinfra/error.h>
+#include <vpp/api/types.h>
+
+#include <vnet/ip/ip_types_api.h>
+
+#define __plugin_msg_base interface_test_main.msg_id_base
+#include <vlibapi/vat_helper_macros.h>
+
+/* Declare message IDs */
+#include <vnet/format_fns.h>
+#include <vnet/interface.api_enum.h>
+#include <vnet/interface.api_types.h>
+#include <vlibmemory/vlib.api_types.h>
+#include <vlibmemory/memclnt.api_enum.h>
+
+#define vl_endianfun /* define message structures */
+#include <vnet/interface.api.h>
+#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 <vnet/interface.api_test.c>
+
+/*
+ * 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 3ba38d3..c47cd3d 100644
--- a/src/vnet/ip/ip_test.c
+++ b/src/vnet/ip/ip_test.c
@@ -40,7 +40,6 @@
{
/* API message ID base */
u16 msg_id_base;
- u32 ping_id;
vat_main_t *vat_main;
} ip_test_main_t;
@@ -100,7 +99,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 b7e6f01..9855ffa 100644
--- a/src/vpp-api/client/test.c
+++ b/src/vpp-api/client/test.c
@@ -38,6 +38,8 @@
#include <vlibmemory/vlib.api_enum.h>
#include <vlibmemory/vlib.api_types.h>
+#include <vlibmemory/memclnt.api_enum.h>
+#include <vlibmemory/memclnt.api_types.h>
#include <vpp/api/vpe.api_enum.h>
#include <vpp/api/vpe.api_types.h>
diff --git a/src/vpp-api/vapi/vapi.c b/src/vpp-api/vapi/vapi.c
index 1bd8e5b..513ff98 100644
--- a/src/vpp-api/vapi/vapi.c
+++ b/src/vpp-api/vapi/vapi.c
@@ -31,8 +31,8 @@
#include <vlibapi/api_common.h>
#include <vlibmemory/memory_client.h>
-#include <vapi/vlib.api.vapi.h>
#include <vapi/memclnt.api.vapi.h>
+#include <vapi/vlib.api.vapi.h>
/* 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 eacfab4..1a5665e 100755
--- a/src/vpp-api/vapi/vapi_c_gen.py
+++ b/src/vpp-api/vapi/vapi_c_gen.py
@@ -705,7 +705,7 @@
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 52b930d..85fc8b3 100644
--- a/src/vpp-api/vapi/vapi_c_test.c
+++ b/src/vpp-api/vapi/vapi_c_test.c
@@ -24,6 +24,8 @@
#include <check.h>
#include <vppinfra/string.h>
#include <vapi/vapi.h>
+#include <vapi/memclnt.api.vapi.h>
+#include <vapi/vlib.api.vapi.h>
#include <vapi/vpe.api.vapi.h>
#include <vapi/interface.api.vapi.h>
#include <vapi/l2.api.vapi.h>
diff --git a/src/vpp-api/vapi/vapi_cpp_test.cpp b/src/vpp-api/vapi/vapi_cpp_test.cpp
index c574dd7..c0e0cdc 100644
--- a/src/vpp-api/vapi/vapi_cpp_test.cpp
+++ b/src/vpp-api/vapi/vapi_cpp_test.cpp
@@ -21,6 +21,7 @@
#include <assert.h>
#include <setjmp.h>
#include <check.h>
+#include <vapi/memclnt.api.vapi.h>
#include <vapi/vapi.hpp>
#include <vapi/vpe.api.vapi.hpp>
#include <vapi/interface.api.vapi.hpp>
diff --git a/src/vpp/api/api_main.c b/src/vpp/api/api_main.c
index 97dec9e..9b915ee 100644
--- a/src/vpp/api/api_main.c
+++ b/src/vpp/api/api_main.c
@@ -1,4 +1,6 @@
#include "vat.h"
+#include <dlfcn.h>
+#include <vat/plugin.h>
vat_main_t vat_main;
@@ -94,6 +96,30 @@
}
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;
@@ -130,7 +156,8 @@
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 @@
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;