+_(cop_whitelist_enable_disable_reply) \
+_(sw_interface_clear_stats_reply) \
+_(trace_profile_add_reply) \
+_(trace_profile_apply_reply) \
+_(trace_profile_del_reply) \
+_(lisp_add_del_locator_set_reply) \
+_(lisp_add_del_locator_reply) \
+_(lisp_add_del_local_eid_reply) \
+_(lisp_add_del_remote_mapping_reply) \
+_(lisp_add_del_adjacency_reply) \
+_(lisp_gpe_add_del_fwd_entry_reply) \
+_(lisp_add_del_map_resolver_reply) \
+_(lisp_gpe_enable_disable_reply) \
+_(lisp_gpe_add_del_iface_reply) \
+_(lisp_enable_disable_reply) \
+_(lisp_pitr_set_locator_set_reply) \
+_(lisp_add_del_map_request_itr_rlocs_reply) \
+_(lisp_eid_table_add_del_map_reply) \
+_(vxlan_gpe_add_del_tunnel_reply) \
+_(af_packet_delete_reply) \
+_(policer_add_del_reply) \
+_(netmap_create_reply) \
+_(netmap_delete_reply) \
+_(ipfix_enable_reply) \
+_(pg_capture_reply) \
+_(pg_enable_disable_reply)
+
+#define _(n) \
+ static void vl_api_##n##_t_handler \
+ (vl_api_##n##_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; \
+ } \
+ }
+foreach_standard_reply_retval_handler;
+#undef _
+
+#define _(n) \
+ static void vl_api_##n##_t_handler_json \
+ (vl_api_##n##_t * mp) \
+ { \
+ vat_main_t * vam = &vat_main; \
+ vat_json_node_t node; \
+ vat_json_init_object(&node); \
+ vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
+ vat_json_print(vam->ofp, &node); \
+ vam->retval = ntohl(mp->retval); \
+ vam->result_ready = 1; \
+ }
+foreach_standard_reply_retval_handler;
+#undef _
+
+/*
+ * Table of message reply handlers, must include boilerplate handlers
+ * we just generated
+ */
+
+#define foreach_vpe_api_reply_msg \
+_(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
+_(SW_INTERFACE_DETAILS, sw_interface_details) \
+_(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \
+_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
+_(CONTROL_PING_REPLY, control_ping_reply) \
+_(CLI_REPLY, cli_reply) \
+_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
+ sw_interface_add_del_address_reply) \
+_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
+_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \
+_(SW_INTERFACE_SET_L2_XCONNECT_REPLY, \
+ sw_interface_set_l2_xconnect_reply) \
+_(SW_INTERFACE_SET_L2_BRIDGE_REPLY, \
+ sw_interface_set_l2_bridge_reply) \
+_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply) \
+_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details) \
+_(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details) \
+_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply) \
+_(L2_FLAGS_REPLY, l2_flags_reply) \
+_(BRIDGE_FLAGS_REPLY, bridge_flags_reply) \
+_(TAP_CONNECT_REPLY, tap_connect_reply) \
+_(TAP_MODIFY_REPLY, tap_modify_reply) \
+_(TAP_DELETE_REPLY, tap_delete_reply) \
+_(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details) \
+_(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply) \
+_(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply) \
+_(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY, \
+ proxy_arp_intfc_enable_disable_reply) \
+_(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply) \
+_(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply) \
+_(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply) \
+_(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY, \
+ mpls_ethernet_add_del_tunnel_reply) \
+_(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY, \
+ mpls_ethernet_add_del_tunnel_2_reply) \
+_(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
+ sw_interface_set_unnumbered_reply) \
+_(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply) \
+_(RESET_VRF_REPLY, reset_vrf_reply) \
+_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
+_(CREATE_SUBIF_REPLY, create_subif_reply) \
+_(OAM_ADD_DEL_REPLY, oam_add_del_reply) \
+_(RESET_FIB_REPLY, reset_fib_reply) \
+_(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply) \
+_(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply) \
+_(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply) \
+_(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply) \
+_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
+_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
+ sw_interface_ip6_enable_disable_reply) \
+_(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY, \
+ sw_interface_ip6_set_link_local_address_reply) \
+_(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY, \
+ sw_interface_ip6nd_ra_prefix_reply) \
+_(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY, \
+ sw_interface_ip6nd_ra_config_reply) \
+_(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply) \
+_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply) \
+_(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply) \
+_(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply) \
+_(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply) \
+_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply) \
+_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply) \
+_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY, \
+classify_set_interface_ip_table_reply) \
+_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY, \
+ classify_set_interface_l2_tables_reply) \
+_(GET_NODE_INDEX_REPLY, get_node_index_reply) \
+_(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
+_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply) \
+_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply) \
+_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY, \
+ l2tpv3_interface_enable_disable_reply) \
+_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
+_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
+_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
+_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
+_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
+_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
+_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
+_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
+_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
+_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details) \
+_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply) \
+_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply) \
+_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply) \
+_(SHOW_VERSION_REPLY, show_version_reply) \
+_(L2_FIB_TABLE_ENTRY, l2_fib_table_entry) \
+_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply) \
+_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details) \
+_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
+_(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply) \
+_(IP4_ARP_EVENT, ip4_arp_event) \
+_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply) \
+_(IP_ADDRESS_DETAILS, ip_address_details) \
+_(IP_DETAILS, ip_details) \
+_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply) \
+_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
+_(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply) \
+_(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply) \
+_(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply) \
+_(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply) \
+_(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply) \
+_(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply) \
+_(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply) \
+_(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply) \
+_(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
+_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply) \
+_(DHCP_COMPL_EVENT, dhcp_compl_event) \
+_(VNET_INTERFACE_COUNTERS, vnet_interface_counters) \
+_(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters) \
+_(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters) \
+_(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply) \
+_(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply) \
+_(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply) \
+_(MAP_DOMAIN_DETAILS, map_domain_details) \
+_(MAP_RULE_DETAILS, map_rule_details) \
+_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
+_(WANT_STATS_REPLY, want_stats_reply) \
+_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
+_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
+_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
+_(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
+_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
+_(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply) \
+_(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply) \
+_(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply) \
+_(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply) \
+_(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply) \
+_(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply) \
+_(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
+_(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply) \
+_(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply) \
+_(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply) \
+_(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply) \
+_(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply) \
+_(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply) \
+_(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply) \
+_(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply) \
+_(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details) \
+_(LISP_LOCAL_EID_TABLE_DETAILS, lisp_local_eid_table_details) \
+_(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details) \
+_(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details) \
+_(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details) \
+_(LISP_ENABLE_DISABLE_STATUS_DETAILS, \
+ lisp_enable_disable_status_details) \
+_(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY, \
+ lisp_add_del_map_request_itr_rlocs_reply) \
+_(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY, \
+ lisp_get_map_request_itr_rlocs_reply) \
+_(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply) \
+_(AF_PACKET_CREATE_REPLY, af_packet_create_reply) \
+_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply) \
+_(POLICER_ADD_DEL_REPLY, policer_add_del_reply) \
+_(POLICER_DETAILS, policer_details) \
+_(NETMAP_CREATE_REPLY, netmap_create_reply) \
+_(NETMAP_DELETE_REPLY, netmap_delete_reply) \
+_(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details) \
+_(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details) \
+_(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details) \
+_(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details) \
+_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply) \
+_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
+_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply) \
+_(CLASSIFY_SESSION_DETAILS, classify_session_details) \
+_(IPFIX_ENABLE_REPLY, ipfix_enable_reply) \
+_(IPFIX_DETAILS, ipfix_details) \
+_(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
+_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply) \
+_(PG_CAPTURE_REPLY, pg_capture_reply) \
+_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)
+
+/* M: construct, but don't yet send a message */
+
+#define M(T,t) \
+do { \
+ vam->result_ready = 0; \
+ mp = vl_msg_api_alloc(sizeof(*mp)); \
+ memset (mp, 0, sizeof (*mp)); \
+ mp->_vl_msg_id = ntohs (VL_API_##T); \
+ mp->client_index = vam->my_client_index; \
+} while(0);
+
+#define M2(T,t,n) \
+do { \
+ vam->result_ready = 0; \
+ mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
+ memset (mp, 0, sizeof (*mp)); \
+ mp->_vl_msg_id = ntohs (VL_API_##T); \
+ mp->client_index = vam->my_client_index; \
+} while(0);
+
+
+/* S: send a message */
+#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
+
+/* W: wait for results, with timeout */
+#define W \
+do { \
+ timeout = vat_time_now (vam) + 1.0; \
+ \
+ while (vat_time_now (vam) < timeout) { \
+ if (vam->result_ready == 1) { \
+ return (vam->retval); \
+ } \
+ } \
+ return -99; \
+} while(0);
+
+/* W2: wait for results, with timeout */
+#define W2(body) \
+do { \
+ timeout = vat_time_now (vam) + 1.0; \
+ \
+ while (vat_time_now (vam) < timeout) { \
+ if (vam->result_ready == 1) { \
+ (body); \
+ return (vam->retval); \
+ } \
+ } \
+ return -99; \
+} while(0);
+
+typedef struct {
+ u8 * name;
+ u32 value;
+} name_sort_t;
+
+
+#define STR_VTR_OP_CASE(op) \
+ case L2_VTR_ ## op: \
+ return "" # op;
+
+static const char *str_vtr_op(u32 vtr_op)
+{
+ 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";
+}
+
+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;
+ }
+
+ fformat (vam->ofp,
+ "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
+ "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) {
+ fformat (vam->ofp,
+ "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
+ 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) {
+ fformat (vam->ofp,
+ " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
+ "tag1: %d tag2: %d ]\n",
+ str_vtr_op(sub->vtr_op), sub->vtr_push_dot1q,
+ sub->vtr_tag1, sub->vtr_tag2);
+ }
+ }
+
+ return 0;
+}
+
+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);
+
+ fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
+ vec_foreach (ns, nses) {
+ fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
+ }
+ vec_free (nses);
+ return 0;
+}
+
+static int dump_ip_table (vat_main_t * vam, int is_ipv6)
+{
+ const ip_details_t * det = NULL;
+ const ip_address_details_t * address = NULL;
+ u32 i = ~0;
+
+ fformat (vam->ofp,
+ "%-12s\n",
+ "sw_if_index");
+
+ if (0 == vam) {
+ return 0;
+ }
+
+ vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6]) {
+ i++;
+ if (!det->present) {
+ continue;
+ }
+ fformat (vam->ofp,
+ "%-12d\n",
+ i);
+ fformat (vam->ofp,
+ " %-30s%-13s\n",
+ "Address", "Prefix length");
+ if (!det->addr) {
+ continue;
+ }
+ vec_foreach (address, det->addr) {
+ fformat (vam->ofp,
+ " %-30U%-13d\n",
+ is_ipv6 ? format_ip6_address : format_ip4_address,
+ address->ip,
+ address->prefix_length);
+ }
+ }
+
+ return 0;
+}
+
+static int dump_ipv4_table (vat_main_t * vam)
+{
+ if (vam->json_output) {
+ clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
+ return -99;
+ }
+
+ return dump_ip_table (vam, 0);
+}
+
+static int dump_ipv6_table (vat_main_t * vam)
+{
+ if (vam->json_output) {
+ clib_warning ("JSON output supported only for VPE API calls and dump_stats_table");
+ return -99;
+ }
+
+ return dump_ip_table (vam, 1);
+}
+
+static char* counter_type_to_str (u8 counter_type, u8 is_combined)
+{
+ if (!is_combined) {
+ switch(counter_type) {
+ case VNET_INTERFACE_COUNTER_DROP:
+ return "drop";
+ case VNET_INTERFACE_COUNTER_PUNT:
+ return "punt";
+ case VNET_INTERFACE_COUNTER_IP4:
+ return "ip4";
+ case VNET_INTERFACE_COUNTER_IP6:
+ return "ip6";
+ case VNET_INTERFACE_COUNTER_RX_NO_BUF:
+ return "rx-no-buf";
+ case VNET_INTERFACE_COUNTER_RX_MISS:
+ return "rx-miss";
+ case VNET_INTERFACE_COUNTER_RX_ERROR:
+ return "rx-error";
+ case VNET_INTERFACE_COUNTER_TX_ERROR:
+ return "tx-error";
+ default:
+ return "INVALID-COUNTER-TYPE";
+ }
+ } else {
+ switch(counter_type) {
+ case VNET_INTERFACE_COUNTER_RX:
+ return "rx";
+ case VNET_INTERFACE_COUNTER_TX:
+ return "tx";
+ default:
+ return "INVALID-COUNTER-TYPE";
+ }
+ }
+}
+
+static int dump_stats_table (vat_main_t * vam)
+{
+ vat_json_node_t node;
+ vat_json_node_t *msg_array;
+ vat_json_node_t *msg;
+ vat_json_node_t *counter_array;
+ vat_json_node_t *counter;
+ interface_counter_t c;
+ u64 packets;
+ ip4_fib_counter_t *c4;
+ ip6_fib_counter_t *c6;
+ int i, j;
+
+ if (!vam->json_output) {
+ clib_warning ("dump_stats_table supported only in JSON format");
+ return -99;
+ }
+
+ vat_json_init_object(&node);
+
+ /* interface counters */
+ msg_array = vat_json_object_add(&node, "interface_counters");
+ vat_json_init_array(msg_array);
+ for (i = 0; i < vec_len(vam->simple_interface_counters); i++) {
+ msg = vat_json_array_add(msg_array);
+ vat_json_init_object(msg);
+ vat_json_object_add_string_copy(msg, "vnet_counter_type",
+ (u8*)counter_type_to_str(i, 0));
+ vat_json_object_add_int(msg, "is_combined", 0);
+ counter_array = vat_json_object_add(msg, "data");
+ vat_json_init_array(counter_array);
+ for (j = 0; j < vec_len(vam->simple_interface_counters[i]); j++) {
+ packets = vam->simple_interface_counters[i][j];
+ vat_json_array_add_uint(counter_array, packets);
+ }
+ }
+ for (i = 0; i < vec_len(vam->combined_interface_counters); i++) {
+ msg = vat_json_array_add(msg_array);
+ vat_json_init_object(msg);
+ vat_json_object_add_string_copy(msg, "vnet_counter_type",
+ (u8*)counter_type_to_str(i, 1));
+ vat_json_object_add_int(msg, "is_combined", 1);
+ counter_array = vat_json_object_add(msg, "data");
+ vat_json_init_array(counter_array);
+ for (j = 0; j < vec_len(vam->combined_interface_counters[i]); j++) {
+ c = vam->combined_interface_counters[i][j];
+ counter = vat_json_array_add(counter_array);
+ vat_json_init_object(counter);
+ vat_json_object_add_uint(counter, "packets", c.packets);
+ vat_json_object_add_uint(counter, "bytes", c.bytes);
+ }
+ }
+
+ /* ip4 fib counters */
+ msg_array = vat_json_object_add(&node, "ip4_fib_counters");
+ vat_json_init_array(msg_array);
+ for (i = 0; i < vec_len(vam->ip4_fib_counters); i++) {
+ msg = vat_json_array_add(msg_array);
+ vat_json_init_object(msg);
+ vat_json_object_add_uint(msg, "vrf_id", vam->ip4_fib_counters_vrf_id_by_index[i]);
+ counter_array = vat_json_object_add(msg, "c");
+ vat_json_init_array(counter_array);
+ for (j = 0; j < vec_len(vam->ip4_fib_counters[i]); j++) {
+ counter = vat_json_array_add(counter_array);
+ vat_json_init_object(counter);
+ c4 = &vam->ip4_fib_counters[i][j];
+ vat_json_object_add_ip4(counter, "address", c4->address);
+ vat_json_object_add_uint(counter, "address_length", c4->address_length);
+ vat_json_object_add_uint(counter, "packets", c4->packets);
+ vat_json_object_add_uint(counter, "bytes", c4->bytes);
+ }
+ }
+
+ /* ip6 fib counters */
+ msg_array = vat_json_object_add(&node, "ip6_fib_counters");
+ vat_json_init_array(msg_array);
+ for (i = 0; i < vec_len(vam->ip6_fib_counters); i++) {
+ msg = vat_json_array_add(msg_array);
+ vat_json_init_object(msg);
+ vat_json_object_add_uint(msg, "vrf_id", vam->ip6_fib_counters_vrf_id_by_index[i]);
+ counter_array = vat_json_object_add(msg, "c");
+ vat_json_init_array(counter_array);
+ for (j = 0; j < vec_len(vam->ip6_fib_counters[i]); j++) {
+ counter = vat_json_array_add(counter_array);
+ vat_json_init_object(counter);
+ c6 = &vam->ip6_fib_counters[i][j];
+ vat_json_object_add_ip6(counter, "address", c6->address);
+ vat_json_object_add_uint(counter, "address_length", c6->address_length);
+ vat_json_object_add_uint(counter, "packets", c6->packets);
+ vat_json_object_add_uint(counter, "bytes", c6->bytes);
+ }
+ }
+
+ vat_json_print(vam->ofp, &node);
+ vat_json_free(&node);
+
+ return 0;
+}
+
+int exec (vat_main_t * vam)
+{
+ api_main_t * am = &api_main;
+ vl_api_cli_request_t *mp;
+ f64 timeout;
+ void * oldheap;
+ u8 * cmd = 0;
+ unformat_input_t * i = vam->input;
+
+ if (vec_len(i->buffer) == 0)
+ return -1;
+
+ if (vam->exec_mode == 0 && unformat (i, "mode")) {
+ vam->exec_mode = 1;
+ return 0;
+ }
+ if (vam->exec_mode == 1 &&
+ (unformat (i, "exit") || unformat (i, "quit"))) {
+ vam->exec_mode = 0;
+ return 0;
+ }
+
+
+ M(CLI_REQUEST, cli_request);
+
+ /*
+ * Copy cmd into shared memory.
+ * In order for the CLI command to work, it
+ * must be a vector ending in \n, not a C-string ending
+ * in \n\0.
+ */
+ pthread_mutex_lock (&am->vlib_rp->mutex);
+ oldheap = svm_push_data_heap (am->vlib_rp);
+
+ vec_validate (cmd, vec_len(vam->input->buffer)-1);
+ clib_memcpy (cmd, vam->input->buffer, vec_len(vam->input->buffer));
+
+ svm_pop_heap (oldheap);
+ pthread_mutex_unlock (&am->vlib_rp->mutex);
+
+ mp->cmd_in_shmem = (u64) cmd;
+ S;
+ timeout = vat_time_now (vam) + 10.0;
+
+ while (vat_time_now (vam) < timeout) {
+ if (vam->result_ready == 1) {
+ u8 * free_me;
+ if (vam->shmem_result != NULL)
+ fformat (vam->ofp, "%s", vam->shmem_result);
+ pthread_mutex_lock (&am->vlib_rp->mutex);
+ oldheap = svm_push_data_heap (am->vlib_rp);
+
+ free_me = (u8 *)vam->shmem_result;
+ vec_free (free_me);
+
+ svm_pop_heap (oldheap);
+ pthread_mutex_unlock (&am->vlib_rp->mutex);
+ return 0;
+ }
+ }
+ return -99;
+}
+
+static int api_create_loopback (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_create_loopback_t *mp;
+ f64 timeout;
+ u8 mac_address[6];
+ u8 mac_set = 0;
+
+ 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;
+ else
+ break;
+ }
+
+ /* Construct the API message */
+ M(CREATE_LOOPBACK, create_loopback);
+ if (mac_set)
+ clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
+
+ S; W;
+}
+
+static int api_delete_loopback (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_delete_loopback_t *mp;
+ f64 timeout;
+ u32 sw_if_index = ~0;
+
+ 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\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(DELETE_LOOPBACK, delete_loopback);
+ mp->sw_if_index = ntohl (sw_if_index);
+
+ S; W;
+}
+
+static int api_want_stats (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_want_stats_t * mp;
+ f64 timeout;
+ int enable = -1;
+
+ 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\n");
+ return -99;
+ }
+
+ M(WANT_STATS, want_stats);
+ mp->enable_disable = enable;
+
+ S; W;
+}
+
+static int api_want_interface_events (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_want_interface_events_t * mp;
+ f64 timeout;
+ int enable = -1;
+
+ 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\n");
+ return -99;
+ }
+
+ M(WANT_INTERFACE_EVENTS, want_interface_events);
+ mp->enable_disable = enable;
+
+ vam->interface_event_display = enable;
+
+ S; W;
+}
+
+
+/* Note: non-static, called once to set up the initial intfc table */
+int api_sw_interface_dump (vat_main_t * vam)
+{
+ vl_api_sw_interface_dump_t *mp;
+ f64 timeout;
+ hash_pair_t * p;
+ name_sort_t * nses = 0, * ns;
+ sw_interface_subif_t * sub = NULL;
+
+ /* 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));
+
+ /* Get list of ethernets */
+ M(SW_INTERFACE_DUMP, sw_interface_dump);
+ mp->name_filter_valid = 1;
+ strncpy ((char *) mp->name_filter, "Ether", sizeof(mp->name_filter)-1);
+ S;
+
+ /* and local / loopback interfaces */
+ M(SW_INTERFACE_DUMP, sw_interface_dump);
+ mp->name_filter_valid = 1;
+ strncpy ((char *) mp->name_filter, "lo", sizeof(mp->name_filter)-1);
+ S;
+
+
+ /* and vxlan-gpe tunnel interfaces */
+ M(SW_INTERFACE_DUMP, sw_interface_dump);
+ mp->name_filter_valid = 1;
+ strncpy ((char *) mp->name_filter, "vxlan_gpe", sizeof(mp->name_filter)-1);
+ S;
+
+ /* and vxlan tunnel interfaces */
+ M(SW_INTERFACE_DUMP, sw_interface_dump);
+ mp->name_filter_valid = 1;
+ strncpy ((char *) mp->name_filter, "vxlan", sizeof(mp->name_filter)-1);
+ S;
+
+ /* and host (af_packet) interfaces */
+ M(SW_INTERFACE_DUMP, sw_interface_dump);
+ mp->name_filter_valid = 1;
+ strncpy ((char *) mp->name_filter, "host", sizeof(mp->name_filter)-1);
+ S;
+
+ /* and l2tpv3 tunnel interfaces */
+ M(SW_INTERFACE_DUMP, sw_interface_dump);
+ mp->name_filter_valid = 1;
+ strncpy ((char *) mp->name_filter, "l2tpv3_tunnel", sizeof(mp->name_filter)-1);
+ S;
+
+ /* and GRE tunnel interfaces */
+ M(SW_INTERFACE_DUMP, sw_interface_dump);
+ mp->name_filter_valid = 1;
+ strncpy ((char *) mp->name_filter, "gre", sizeof(mp->name_filter)-1);
+ S;
+
+ /* Use a control ping for synchronization */
+ {
+ vl_api_control_ping_t * mp;
+ M(CONTROL_PING, control_ping);
+ S;
+ }
+ W;
+}
+
+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;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u8 admin_up = 0, link_up = 0;
+
+ /* 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, "link-up"))
+ link_up = 1;
+ else if (unformat (i, "link-down"))
+ link_up = 0;
+ else if (unformat (i, "%U", 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\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->admin_up_down = admin_up;
+ mp->link_up_down = link_up;
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply, return the good/bad news... */
+ W;
+}
+
+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;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", 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, sw_interface_clear_stats);
+
+ if (sw_if_index_set == 1)
+ mp->sw_if_index = ntohl (sw_if_index);
+ else
+ mp->sw_if_index = ~0;
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply, return the good/bad news... */
+ W;
+}
+
+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;
+ f64 timeout;
+ 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;
+
+ /* 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", 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\n");
+ return -99;
+ }
+ if (v4_address_set && v6_address_set) {
+ errmsg ("both v4 and v6 addresses set\n");
+ return -99;
+ }
+ if (!v4_address_set && !v6_address_set && !del_all) {
+ errmsg ("no addresses set\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->is_add = is_add;
+ mp->del_all = del_all;
+ if (v6_address_set) {
+ mp->is_ipv6 = 1;
+ clib_memcpy (mp->address, &v6address, sizeof (v6address));
+ } else {
+ clib_memcpy (mp->address, &v4address, sizeof (v4address));
+ }
+ mp->address_length = address_length;
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply, return good/bad news */
+ W;
+}
+
+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;
+ f64 timeout;
+ u32 sw_if_index, vrf_id = 0;
+ u8 sw_if_index_set = 0;
+ u8 is_ipv6 = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", 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\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(SW_INTERFACE_SET_TABLE, sw_interface_set_table);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->is_ipv6 = is_ipv6;
+ mp->vrf_id = ntohl (vrf_id);
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply... */
+ W;
+}
+
+static int api_sw_interface_set_vpath (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_sw_interface_set_vpath_t *mp;
+ f64 timeout;
+ u32 sw_if_index = 0;
+ u8 sw_if_index_set = 0;
+ u8 is_enable = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", 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, "enable"))
+ is_enable = 1;
+ else if (unformat (i, "disable"))
+ is_enable = 0;
+ else
+ break;
+ }
+
+ if (sw_if_index_set == 0) {
+ errmsg ("missing interface name or sw_if_index\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->enable = is_enable;
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply... */
+ W;
+}
+
+static int api_sw_interface_set_l2_xconnect (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_sw_interface_set_l2_xconnect_t *mp;
+ f64 timeout;
+ u32 rx_sw_if_index;
+ u8 rx_sw_if_index_set = 0;
+ u32 tx_sw_if_index;
+ u8 tx_sw_if_index_set = 0;
+ u8 enable = 1;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
+ tx_sw_if_index_set = 1;
+ else if (unformat (i, "rx")) {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", unformat_sw_if_index, vam,
+ &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ } else
+ break;
+ } else if (unformat (i, "tx")) {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", unformat_sw_if_index, vam,
+ &tx_sw_if_index))
+ tx_sw_if_index_set = 1;
+ } else
+ break;
+ } else if (unformat (i, "enable"))
+ enable = 1;
+ else if (unformat (i, "disable"))
+ enable = 0;
+ else
+ break;
+ }
+
+ if (rx_sw_if_index_set == 0) {
+ errmsg ("missing rx interface name or rx_sw_if_index\n");
+ return -99;
+ }
+
+ if (enable && (tx_sw_if_index_set == 0)) {
+ errmsg ("missing tx interface name or tx_sw_if_index\n");
+ return -99;
+ }
+
+ M(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
+
+ mp->rx_sw_if_index = ntohl(rx_sw_if_index);
+ mp->tx_sw_if_index = ntohl(tx_sw_if_index);
+ mp->enable = enable;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_sw_interface_set_l2_bridge (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_sw_interface_set_l2_bridge_t *mp;
+ f64 timeout;
+ u32 rx_sw_if_index;
+ u8 rx_sw_if_index_set = 0;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ u8 bvi = 0;
+ u32 shg = 0;
+ u8 enable = 1;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ else if (unformat (i, "bd_id %d", &bd_id))
+ bd_id_set = 1;
+ else if (unformat (i, "%U", unformat_sw_if_index, vam,
+ &rx_sw_if_index))
+ rx_sw_if_index_set = 1;
+ else if (unformat (i, "shg %d", &shg))
+ ;
+ else if (unformat (i, "bvi"))
+ bvi = 1;
+ else if (unformat (i, "enable"))
+ enable = 1;
+ else if (unformat (i, "disable"))
+ enable = 0;
+ else
+ break;
+ }
+
+ if (rx_sw_if_index_set == 0) {
+ errmsg ("missing rx interface name or sw_if_index\n");
+ return -99;
+ }
+
+ if (enable && (bd_id_set == 0)) {
+ errmsg ("missing bridge domain\n");
+ return -99;
+ }
+
+ M(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
+
+ mp->rx_sw_if_index = ntohl(rx_sw_if_index);
+ mp->bd_id = ntohl(bd_id);
+ mp->shg = (u8)shg;
+ mp->bvi = bvi;
+ mp->enable = enable;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_bridge_domain_dump (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_bridge_domain_dump_t *mp;
+ f64 timeout;
+ u32 bd_id = ~0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "bd_id %d", &bd_id))
+ ;
+ else
+ break;
+ }
+
+ M(BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
+ mp->bd_id = ntohl(bd_id);
+ S;
+
+ /* Use a control ping for synchronization */
+ {
+ vl_api_control_ping_t * mp;
+ M(CONTROL_PING, control_ping);
+ S;
+ }
+
+ W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_bridge_domain_add_del (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_bridge_domain_add_del_t *mp;
+ f64 timeout;
+ u32 bd_id = ~0;
+ u8 is_add = 1;
+ u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "bd_id %d", &bd_id))
+ ;
+ else if (unformat (i, "flood %d", &flood))
+ ;
+ else if (unformat (i, "uu-flood %d", &uu_flood))
+ ;
+ else if (unformat (i, "forward %d", &forward))
+ ;
+ else if (unformat (i, "learn %d", &learn))
+ ;
+ else if (unformat (i, "arp-term %d", &arp_term))
+ ;
+ else if (unformat (i, "del")) {
+ is_add = 0;
+ flood = uu_flood = forward = learn = 0;
+ }
+ else
+ break;
+ }
+
+ if (bd_id == ~0) {
+ errmsg ("missing bridge domain\n");
+ return -99;
+ }
+
+ M(BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
+
+ mp->bd_id = ntohl(bd_id);
+ mp->flood = flood;
+ mp->uu_flood = uu_flood;
+ mp->forward = forward;
+ mp->learn = learn;
+ mp->arp_term = arp_term;
+ mp->is_add = is_add;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_l2fib_add_del (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_l2fib_add_del_t *mp;
+ f64 timeout;
+ u64 mac = 0;
+ u8 mac_set = 0;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u8 is_add = 1;
+ u8 static_mac = 0;
+ u8 filter_mac = 0;
+ u8 bvi_mac = 0;
+ int count = 1;
+ f64 before = 0;
+ int j;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
+ mac_set = 1;
+ else if (unformat (i, "bd_id %d", &bd_id))
+ bd_id_set = 1;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else if (unformat (i, "sw_if")) {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
+ sw_if_index_set = 1;
+ } else
+ break;
+ } else if (unformat (i, "static"))
+ static_mac = 1;
+ else if (unformat (i, "filter")) {
+ filter_mac = 1;
+ static_mac = 1;
+ } else if (unformat (i, "bvi")) {
+ bvi_mac = 1;
+ static_mac = 1;
+ } else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "count %d", &count))
+ ;
+ else
+ break;
+ }
+
+ if (mac_set == 0) {
+ errmsg ("missing mac address\n");
+ return -99;
+ }
+
+ if (bd_id_set == 0) {
+ errmsg ("missing bridge domain\n");
+ return -99;
+ }
+
+ if (is_add && (sw_if_index_set == 0)) {
+ errmsg ("missing interface name or sw_if_index\n");
+ return -99;
+ }
+
+ if (count > 1) {
+ /* Turn on async mode */
+ vam->async_mode = 1;
+ vam->async_errors = 0;
+ before = vat_time_now(vam);
+ }
+
+ for (j = 0; j < count; j++) {
+ M(L2FIB_ADD_DEL, l2fib_add_del);
+
+ mp->mac = mac;
+ mp->bd_id = ntohl(bd_id);
+ mp->is_add = is_add;
+
+ if (is_add) {
+ mp->sw_if_index = ntohl(sw_if_index);
+ mp->static_mac = static_mac;
+ mp->filter_mac = filter_mac;
+ mp->bvi_mac = bvi_mac;
+ }
+ increment_mac_address (&mac);
+ /* send it... */
+ S;
+ }
+
+ if (count > 1) {
+ vl_api_control_ping_t * mp;
+ f64 after;
+
+ /* Shut off async mode */
+ vam->async_mode = 0;
+
+ M(CONTROL_PING, control_ping);
+ S;
+
+ timeout = vat_time_now(vam) + 1.0;
+ while (vat_time_now (vam) < timeout)
+ if (vam->result_ready == 1)
+ goto out;
+ vam->retval = -99;
+
+ out:
+ if (vam->retval == -99)
+ errmsg ("timeout\n");
+
+ if (vam->async_errors > 0) {
+ errmsg ("%d asynchronous errors\n", vam->async_errors);
+ vam->retval = -98;
+ }
+ vam->async_errors = 0;
+ after = vat_time_now(vam);
+
+ fformat(vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
+ count, after - before, count / (after - before));
+ } else {
+ /* Wait for a reply... */
+ W;
+ }
+ /* Return the good/bad news */
+ return (vam->retval);
+}
+
+static int api_l2_flags (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_l2_flags_t *mp;
+ f64 timeout;
+ u32 sw_if_index;
+ u32 feature_bitmap = 0;
+ u8 sw_if_index_set = 0;
+
+ /* Parse args required to build the message */
+ 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, "sw_if")) {
+ if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
+ sw_if_index_set = 1;
+ } else
+ break;
+ } else if (unformat (i, "learn"))
+ feature_bitmap |= L2INPUT_FEAT_LEARN;
+ else if (unformat (i, "forward"))
+ feature_bitmap |= L2INPUT_FEAT_FWD;
+ else if (unformat (i, "flood"))
+ feature_bitmap |= L2INPUT_FEAT_FLOOD;
+ else if (unformat (i, "uu-flood"))
+ feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
+ else
+ break;
+ }
+
+ if (sw_if_index_set == 0) {
+ errmsg ("missing interface name or sw_if_index\n");
+ return -99;
+ }
+
+ M(L2_FLAGS, l2_flags);
+
+ mp->sw_if_index = ntohl(sw_if_index);
+ mp->feature_bitmap = ntohl(feature_bitmap);
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_bridge_flags (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_bridge_flags_t *mp;
+ f64 timeout;
+ u32 bd_id;
+ u8 bd_id_set = 0;
+ u8 is_set = 1;
+ u32 flags = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "bd_id %d", &bd_id))
+ bd_id_set = 1;
+ else if (unformat (i, "learn"))
+ flags |= L2_LEARN;
+ else if (unformat (i, "forward"))
+ flags |= L2_FWD;
+ else if (unformat (i, "flood"))
+ flags |= L2_FLOOD;
+ else if (unformat (i, "uu-flood"))
+ flags |= L2_UU_FLOOD;
+ else if (unformat (i, "arp-term"))
+ flags |= L2_ARP_TERM;
+ else if (unformat (i, "off"))
+ is_set = 0;
+ else if (unformat (i, "disable"))
+ is_set = 0;
+ else
+ break;
+ }
+
+ if (bd_id_set == 0) {
+ errmsg ("missing bridge domain\n");
+ return -99;
+ }
+
+ M(BRIDGE_FLAGS, bridge_flags);
+
+ mp->bd_id = ntohl(bd_id);
+ mp->feature_bitmap = ntohl(flags);
+ mp->is_set = is_set;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_bd_ip_mac_add_del (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_bd_ip_mac_add_del_t *mp;
+ f64 timeout;
+ u32 bd_id;
+ u8 is_ipv6 = 0;
+ u8 is_add = 1;
+ u8 bd_id_set = 0;
+ u8 ip_set = 0;
+ u8 mac_set = 0;
+ ip4_address_t v4addr;
+ ip6_address_t v6addr;
+ u8 macaddr[6];
+
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "bd_id %d", &bd_id)) {
+ bd_id_set++;
+ } else if (unformat (i, "%U", unformat_ip4_address, &v4addr)) {
+ ip_set++;
+ } else if (unformat (i, "%U", unformat_ip6_address, &v6addr)) {
+ ip_set++;
+ is_ipv6++;
+ } else if (unformat (i, "%U", unformat_ethernet_address, macaddr)) {
+ mac_set++;
+ } else if (unformat (i, "del"))
+ is_add = 0;
+ else
+ break;
+ }
+
+ if (bd_id_set == 0) {
+ errmsg ("missing bridge domain\n");
+ return -99;
+ } else if (ip_set == 0) {
+ errmsg ("missing IP address\n");
+ return -99;
+ } else if (mac_set == 0) {
+ errmsg ("missing MAC address\n");
+ return -99;
+ }
+
+ M(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
+
+ mp->bd_id = ntohl(bd_id);
+ mp->is_ipv6 = is_ipv6;
+ mp->is_add = is_add;
+ if (is_ipv6)
+ clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
+ else clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
+ clib_memcpy (mp->mac_address, macaddr, 6);
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_tap_connect (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_tap_connect_t *mp;
+ f64 timeout;
+ u8 mac_address[6];
+ u8 random_mac = 1;
+ u8 name_set = 0;
+ u8 * tap_name;
+
+ memset (mac_address, 0, sizeof (mac_address));
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "mac %U", unformat_ethernet_address, mac_address)) {
+ random_mac = 0;
+ }
+ else if (unformat (i, "random-mac"))
+ random_mac = 1;
+ else if (unformat (i, "tapname %s", &tap_name))
+ name_set = 1;
+ else
+ break;
+ }
+
+ if (name_set == 0) {
+ errmsg ("missing tap name\n");
+ return -99;
+ }
+ if (vec_len (tap_name) > 63) {
+ errmsg ("tap name too long\n");
+ }
+ vec_add1 (tap_name, 0);
+
+ /* Construct the API message */
+ M(TAP_CONNECT, tap_connect);
+
+ mp->use_random_mac = random_mac;
+ clib_memcpy (mp->mac_address, mac_address, 6);
+ clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
+ vec_free (tap_name);
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply... */
+ W;
+}
+
+static int api_tap_modify (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_tap_modify_t *mp;
+ f64 timeout;
+ u8 mac_address[6];
+ u8 random_mac = 1;
+ u8 name_set = 0;
+ u8 * tap_name;
+ u32 sw_if_index = ~0;
+ u8 sw_if_index_set = 0;
+
+ memset (mac_address, 0, sizeof (mac_address));
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", 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, "mac %U", unformat_ethernet_address, mac_address)) {
+ random_mac = 0;
+ }
+ else if (unformat (i, "random-mac"))
+ random_mac = 1;
+ else if (unformat (i, "tapname %s", &tap_name))
+ name_set = 1;
+ else
+ break;
+ }
+
+ if (sw_if_index_set == 0) {
+ errmsg ("missing vpp interface name");
+ return -99;
+ }
+ if (name_set == 0) {
+ errmsg ("missing tap name\n");
+ return -99;
+ }
+ if (vec_len (tap_name) > 63) {
+ errmsg ("tap name too long\n");
+ }
+ vec_add1 (tap_name, 0);
+
+ /* Construct the API message */
+ M(TAP_MODIFY, tap_modify);
+
+ mp->use_random_mac = random_mac;
+ mp->sw_if_index = ntohl(sw_if_index);
+ clib_memcpy (mp->mac_address, mac_address, 6);
+ clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
+ vec_free (tap_name);
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply... */
+ W;
+}
+
+static int api_tap_delete (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_tap_delete_t *mp;
+ f64 timeout;
+ u32 sw_if_index = ~0;
+ u8 sw_if_index_set = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", 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 vpp interface name");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(TAP_DELETE, tap_delete);
+
+ mp->sw_if_index = ntohl(sw_if_index);
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply... */
+ W;
+}
+
+static int api_ip_add_del_route (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_ip_add_del_route_t *mp;
+ f64 timeout;
+ u32 sw_if_index = ~0, vrf_id = 0;
+ u8 sw_if_index_set = 0;
+ u8 is_ipv6 = 0;
+ u8 is_local = 0, is_drop = 0;
+ u8 create_vrf_if_needed = 0;
+ u8 is_add = 1;
+ u8 next_hop_weight = 1;
+ u8 not_last = 0;
+ u8 is_multipath = 0;
+ u8 address_set = 0;
+ u8 address_length_set = 0;
+ u32 lookup_in_vrf = 0;
+ u32 resolve_attempts = 0;
+ u32 dst_address_length = 0;
+ u8 next_hop_set = 0;
+ ip4_address_t v4_dst_address, v4_next_hop_address;
+ ip6_address_t v6_dst_address, v6_next_hop_address;
+ int count = 1;
+ int j;
+ f64 before = 0;
+ u32 random_add_del = 0;
+ u32 * random_vector = 0;
+ uword * random_hash;
+ u32 random_seed = 0xdeaddabe;
+ u32 classify_table_index = ~0;
+ u8 is_classify = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "%U", 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", unformat_ip4_address,
+ &v4_dst_address)) {
+ address_set = 1;
+ is_ipv6 = 0;
+ }
+ else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address)) {
+ address_set = 1;
+ is_ipv6 = 1;
+ }
+ else if (unformat (i, "/%d", &dst_address_length)) {
+ address_length_set = 1;
+ }
+
+ else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
+ &v4_next_hop_address)) {
+ next_hop_set = 1;
+ }
+ else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
+ &v6_next_hop_address)) {
+ next_hop_set = 1;
+ }
+ else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
+ ;
+ else if (unformat (i, "weight %d", &next_hop_weight))
+ ;
+ else if (unformat (i, "drop")) {
+ is_drop = 1;
+ } else if (unformat (i, "local")) {
+ is_local = 1;
+ } else if (unformat (i, "classify %d", &classify_table_index)) {
+ is_classify = 1;
+ } else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "add"))
+ is_add = 1;
+ else if (unformat (i, "not-last"))
+ not_last = 1;
+ else if (unformat (i, "multipath"))
+ is_multipath = 1;
+ else if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "create-vrf"))
+ create_vrf_if_needed = 1;
+ else if (unformat (i, "count %d", &count))
+ ;
+ else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
+ ;
+ else if (unformat (i, "random"))
+ random_add_del = 1;
+ else if (unformat (i, "seed %d", &random_seed))
+ ;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }