+ /* Construct the API message */
+ M (TAP_DELETE_V2, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+static int
+api_bond_create (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bond_create_t *mp;
+ u8 mac_address[6];
+ u8 custom_mac = 0;
+ int ret;
+ u8 mode;
+ u8 lb;
+ u8 mode_is_set = 0;
+
+ memset (mac_address, 0, sizeof (mac_address));
+ lb = BOND_LB_L2;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "mode %U", unformat_bond_mode, &mode))
+ mode_is_set = 1;
+ else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
+ && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
+ ;
+ else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
+ mac_address))
+ custom_mac = 1;
+ else
+ break;
+ }
+
+ if (mode_is_set == 0)
+ {
+ errmsg ("Missing bond mode. ");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (BOND_CREATE, mp);
+
+ mp->use_custom_mac = custom_mac;
+
+ mp->mode = mode;
+ mp->lb = lb;
+
+ if (custom_mac)
+ clib_memcpy (mp->mac_address, mac_address, 6);
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+static int
+api_bond_delete (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bond_delete_t *mp;
+ u32 sw_if_index = ~0;
+ 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;
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing vpp interface name. ");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (BOND_DELETE, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+static int
+api_bond_enslave (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bond_enslave_t *mp;
+ u32 bond_sw_if_index;
+ int ret;
+ u8 is_passive;
+ u8 is_long_timeout;
+ u32 bond_sw_if_index_is_set = 0;
+ u32 sw_if_index;
+ u8 sw_if_index_is_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_is_set = 1;
+ else if (unformat (i, "bond %u", &bond_sw_if_index))
+ bond_sw_if_index_is_set = 1;
+ else if (unformat (i, "passive %d", &is_passive))
+ ;
+ else if (unformat (i, "long-timeout %d", &is_long_timeout))
+ ;
+ else
+ break;
+ }
+
+ if (bond_sw_if_index_is_set == 0)
+ {
+ errmsg ("Missing bond sw_if_index. ");
+ return -99;
+ }
+ if (sw_if_index_is_set == 0)
+ {
+ errmsg ("Missing slave sw_if_index. ");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (BOND_ENSLAVE, mp);
+
+ mp->bond_sw_if_index = ntohl (bond_sw_if_index);
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->is_long_timeout = is_long_timeout;
+ mp->is_passive = is_passive;
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+static int
+api_bond_detach_slave (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_bond_detach_slave_t *mp;
+ u32 sw_if_index = ~0;
+ 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;
+ }
+
+ if (sw_if_index_set == 0)
+ {
+ errmsg ("missing vpp interface name. ");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (BOND_DETACH_SLAVE, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+static int
+api_ip_table_add_del (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ip_table_add_del_t *mp;
+ u32 table_id = ~0;
+ u8 is_ipv6 = 0;
+ u8 is_add = 1;
+ int ret = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "ipv6"))
+ is_ipv6 = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "add"))
+ is_add = 1;
+ else if (unformat (i, "table %d", &table_id))
+ ;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (~0 == table_id)
+ {
+ errmsg ("missing table-ID");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (IP_TABLE_ADD_DEL, mp);
+
+ mp->table_id = ntohl (table_id);
+ mp->is_ipv6 = is_ipv6;
+ mp->is_add = is_add;
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+
+ return ret;
+}
+
+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;
+ u32 sw_if_index = ~0, vrf_id = 0;
+ u8 is_ipv6 = 0;
+ u8 is_local = 0, is_drop = 0;
+ u8 is_unreach = 0, is_prohibit = 0;
+ u8 is_add = 1;
+ u32 next_hop_weight = 1;
+ u8 is_multipath = 0;
+ u8 address_set = 0;
+ u8 address_length_set = 0;
+ u32 next_hop_table_id = 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;
+ u8 resolve_host = 0, resolve_attached = 0;
+ mpls_label_t *next_hop_out_label_stack = NULL;
+ mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
+ mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
+
+ /* 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))
+ ;
+ else if (unformat (i, "sw_if_index %d", &sw_if_index))
+ ;
+ 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, "null-send-unreach"))
+ {
+ is_unreach = 1;
+ }
+ else if (unformat (i, "null-send-prohibit"))
+ {
+ is_prohibit = 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, "resolve-via-host"))
+ resolve_host = 1;
+ else if (unformat (i, "resolve-via-attached"))
+ resolve_attached = 1;
+ else if (unformat (i, "multipath"))
+ is_multipath = 1;
+ else if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "count %d", &count))
+ ;
+ else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
+ ;
+ else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
+ ;
+ else if (unformat (i, "out-label %d", &next_hop_out_label))
+ vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
+ else if (unformat (i, "via-label %d", &next_hop_via_label))
+ ;
+ 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;
+ }
+ }
+
+ if (!next_hop_set && !is_drop && !is_local &&
+ !is_classify && !is_unreach && !is_prohibit &&
+ MPLS_LABEL_INVALID == next_hop_via_label)
+ {
+ errmsg
+ ("next hop / local / drop / unreach / prohibit / classify not set");
+ return -99;
+ }
+
+ if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
+ {
+ errmsg ("next hop and next-hop via label set");