+ 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;
+
+ /* 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, "del"))
+ is_add = 0;
+ 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;
+ }
+
+ 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;
+ }
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+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;
+ }
+ }
+
+ if (resolve_attempts > 0 && sw_if_index_set == 0) {
+ errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
+ return -99;
+ }
+
+ if (!next_hop_set && !is_drop && !is_local && !is_classify) {
+ errmsg ("next hop / local / drop / classify not set\n");
+ return -99;
+ }
+
+ if (address_set == 0) {
+ errmsg ("missing addresses\n");
+ return -99;
+ }
+
+ if (address_length_set == 0) {
+ errmsg ("missing address length\n");
+ return -99;
+ }
+
+ /* Generate a pile of unique, random routes */
+ if (random_add_del) {
+ u32 this_random_address;
+ random_hash = hash_create (count, sizeof(uword));
+
+ hash_set (random_hash, v4_next_hop_address.as_u32, 1);
+ for (j = 0; j <= count; j++) {
+ do {
+ this_random_address = random_u32 (&random_seed);
+ this_random_address =
+ clib_host_to_net_u32 (this_random_address);
+ } while (hash_get (random_hash, this_random_address));
+ vec_add1 (random_vector, this_random_address);
+ hash_set (random_hash, this_random_address, 1);
+ }
+ hash_free (random_hash);
+ v4_dst_address.as_u32 = random_vector[0];
+ }
+
+ 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++) {
+ /* Construct the API message */
+ M(IP_ADD_DEL_ROUTE, ip_add_del_route);
+
+ mp->next_hop_sw_if_index = ntohl (sw_if_index);
+ mp->vrf_id = ntohl (vrf_id);
+ if (resolve_attempts > 0) {
+ mp->resolve_attempts = ntohl (resolve_attempts);
+ mp->resolve_if_needed = 1;
+ }
+ mp->create_vrf_if_needed = create_vrf_if_needed;
+
+ mp->is_add = is_add;
+ mp->is_drop = is_drop;
+ mp->is_ipv6 = is_ipv6;
+ mp->is_local = is_local;
+ mp->is_classify = is_classify;
+ mp->is_multipath = is_multipath;
+ mp->not_last = not_last;
+ mp->next_hop_weight = next_hop_weight;
+ mp->dst_address_length = dst_address_length;
+ mp->lookup_in_vrf = ntohl(lookup_in_vrf);
+ mp->classify_table_index = ntohl(classify_table_index);
+
+ if (is_ipv6){
+ clib_memcpy (mp->dst_address, &v6_dst_address, sizeof (v6_dst_address));
+ if (next_hop_set)
+ clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
+ sizeof (v6_next_hop_address));
+ increment_v6_address (&v6_dst_address);
+ } else {
+ clib_memcpy (mp->dst_address, &v4_dst_address, sizeof (v4_dst_address));
+ if (next_hop_set)
+ clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
+ sizeof (v4_next_hop_address));
+ if (random_add_del)
+ v4_dst_address.as_u32 = random_vector[j+1];
+ else
+ increment_v4_address (&v4_dst_address);
+ }
+ /* send it... */
+ S;
+ }
+
+ /* When testing multiple add/del ops, use a control-ping to sync */
+ 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_proxy_arp_add_del (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_proxy_arp_add_del_t *mp;
+ f64 timeout;
+ u32 vrf_id = 0;
+ u8 is_add = 1;
+ ip4_address_t lo, hi;
+ u8 range_set = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
+ unformat_ip4_address, &hi))
+ range_set = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (range_set == 0) {
+ errmsg ("address range not set\n");
+ return -99;
+ }
+
+ M(PROXY_ARP_ADD_DEL, proxy_arp_add_del);
+
+ mp->vrf_id = ntohl(vrf_id);
+ mp->is_add = is_add;
+ clib_memcpy(mp->low_address, &lo, sizeof (mp->low_address));
+ clib_memcpy(mp->hi_address, &hi, sizeof (mp->hi_address));
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_proxy_arp_intfc_enable_disable_t *mp;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 enable = 1;
+ u8 sw_if_index_set = 0;
+
+ 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"))
+ enable = 1;
+ else if (unformat (i, "disable"))
+ enable = 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\n");
+ return -99;
+ }
+
+ M(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
+
+ mp->sw_if_index = ntohl(sw_if_index);
+ mp->enable_disable = enable;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_mpls_add_del_decap (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_mpls_add_del_decap_t *mp;
+ f64 timeout;
+ u32 rx_vrf_id = 0;
+ u32 tx_vrf_id = 0;
+ u32 label = 0;
+ u8 is_add = 1;
+ u8 s_bit = 1;
+ u32 next_index = 1;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
+ ;
+ else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
+ ;
+ else if (unformat (i, "label %d", &label))
+ ;
+ else if (unformat (i, "next-index %d", &next_index))
+ ;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "s-bit-clear"))
+ s_bit = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ M(MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
+
+ mp->rx_vrf_id = ntohl(rx_vrf_id);
+ mp->tx_vrf_id = ntohl(tx_vrf_id);
+ mp->label = ntohl(label);
+ mp->next_index = ntohl(next_index);
+ mp->s_bit = s_bit;
+ mp->is_add = is_add;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_mpls_add_del_encap (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_mpls_add_del_encap_t *mp;
+ f64 timeout;
+ u32 vrf_id = 0;
+ u32 *labels = 0;
+ u32 label;
+ ip4_address_t dst_address;
+ u8 is_add = 1;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "label %d", &label))
+ vec_add1 (labels, ntohl(label));
+ else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
+ ;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (vec_len (labels) == 0) {
+ errmsg ("missing encap label stack\n");
+ return -99;
+ }
+
+ M2(MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
+ sizeof (u32) * vec_len (labels));
+
+ mp->vrf_id = ntohl(vrf_id);
+ clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
+ mp->is_add = is_add;
+ mp->nlabels = vec_len (labels);
+ clib_memcpy(mp->labels, labels, sizeof(u32)*mp->nlabels);
+
+ vec_free(labels);
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_mpls_gre_add_del_tunnel (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_mpls_gre_add_del_tunnel_t *mp;
+ f64 timeout;
+ u32 inner_vrf_id = 0;
+ u32 outer_vrf_id = 0;
+ ip4_address_t src_address;
+ ip4_address_t dst_address;
+ ip4_address_t intfc_address;
+ u32 tmp;
+ u8 intfc_address_length = 0;
+ u8 is_add = 1;
+ u8 l2_only = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
+ ;
+ else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
+ ;
+ else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
+ ;
+ else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
+ ;
+ else if (unformat (i, "adj %U/%d", unformat_ip4_address,
+ &intfc_address, &tmp))
+ intfc_address_length = tmp;
+ else if (unformat (i, "l2-only"))
+ l2_only = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ M(MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
+
+ mp->inner_vrf_id = ntohl(inner_vrf_id);
+ mp->outer_vrf_id = ntohl(outer_vrf_id);
+ clib_memcpy(mp->src_address, &src_address, sizeof (src_address));
+ clib_memcpy(mp->dst_address, &dst_address, sizeof (dst_address));
+ clib_memcpy(mp->intfc_address, &intfc_address, sizeof (intfc_address));
+ mp->intfc_address_length = intfc_address_length;
+ mp->l2_only = l2_only;
+ mp->is_add = is_add;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_mpls_ethernet_add_del_tunnel_t *mp;
+ f64 timeout;
+ u32 inner_vrf_id = 0;
+ ip4_address_t intfc_address;
+ u8 dst_mac_address[6];
+ int dst_set = 1;
+ u32 tmp;
+ u8 intfc_address_length = 0;
+ u8 is_add = 1;
+ u8 l2_only = 0;
+ u32 tx_sw_if_index;
+ int tx_sw_if_index_set = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "vrf %d", &inner_vrf_id))
+ ;
+ else if (unformat (i, "adj %U/%d", unformat_ip4_address,
+ &intfc_address, &tmp))
+ intfc_address_length = tmp;
+ else if (unformat (i, "%U",
+ unformat_sw_if_index, vam, &tx_sw_if_index))
+ tx_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, "dst %U", unformat_ethernet_address,
+ dst_mac_address))
+ dst_set = 1;
+ else if (unformat (i, "l2-only"))
+ l2_only = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (!dst_set) {
+ errmsg ("dst (mac address) not set\n");
+ return -99;
+ }
+ if (!tx_sw_if_index_set) {
+ errmsg ("tx-intfc not set\n");
+ return -99;
+ }
+
+ M(MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
+
+ mp->vrf_id = ntohl(inner_vrf_id);
+ clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
+ mp->adj_address_length = intfc_address_length;
+ clib_memcpy (mp->dst_mac_address, dst_mac_address, sizeof (dst_mac_address));
+ mp->tx_sw_if_index = ntohl(tx_sw_if_index);
+ mp->l2_only = l2_only;
+ mp->is_add = is_add;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
+ f64 timeout;
+ u32 inner_vrf_id = 0;
+ u32 outer_vrf_id = 0;
+ ip4_address_t adj_address;
+ int adj_address_set = 0;
+ ip4_address_t next_hop_address;
+ int next_hop_address_set = 0;
+ u32 tmp;
+ u8 adj_address_length = 0;
+ u8 l2_only = 0;
+ u8 is_add = 1;
+ u32 resolve_attempts = 5;
+ u8 resolve_if_needed = 1;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
+ ;
+ else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
+ ;
+ else if (unformat (i, "adj %U/%d", unformat_ip4_address,
+ &adj_address, &tmp)) {
+ adj_address_length = tmp;
+ adj_address_set = 1;
+ }
+ else if (unformat (i, "next-hop %U", unformat_ip4_address,
+ &next_hop_address))
+ next_hop_address_set = 1;
+ else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
+ ;
+ else if (unformat (i, "resolve-if-needed %d", &tmp))
+ resolve_if_needed = tmp;
+ else if (unformat (i, "l2-only"))
+ l2_only = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (!adj_address_set) {
+ errmsg ("adjacency address/mask not set\n");
+ return -99;
+ }
+ if (!next_hop_address_set) {
+ errmsg ("ip4 next hop address (in outer fib) not set\n");
+ return -99;
+ }
+
+ M(MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
+
+ mp->inner_vrf_id = ntohl(inner_vrf_id);
+ mp->outer_vrf_id = ntohl(outer_vrf_id);
+ mp->resolve_attempts = ntohl(resolve_attempts);
+ mp->resolve_if_needed = resolve_if_needed;
+ mp->is_add = is_add;
+ mp->l2_only = l2_only;
+ clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
+ mp->adj_address_length = adj_address_length;
+ clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
+ sizeof (next_hop_address));
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+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;
+ f64 timeout;
+ u32 sw_if_index;
+ u32 unnum_sw_index;
+ u8 is_add = 1;
+ u8 sw_if_index_set = 0;
+
+ 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, "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\n");
+ return -99;
+ }
+
+ M(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
+
+ mp->sw_if_index = ntohl(sw_if_index);
+ mp->unnumbered_sw_if_index = ntohl(unnum_sw_index);
+ mp->is_add = is_add;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_ip_neighbor_add_del (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_ip_neighbor_add_del_t *mp;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u32 vrf_id = 0;
+ u8 is_add = 1;
+ u8 is_static = 0;
+ u8 mac_address[6];
+ u8 mac_set = 0;
+ u8 v4_address_set = 0;
+ u8 v6_address_set = 0;
+ ip4_address_t v4address;
+ ip6_address_t v6address;
+
+ 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)) {
+ mac_set = 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, "is_static"))
+ is_static = 1;
+ else if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "dst %U",
+ unformat_ip4_address, &v4address))
+ v4_address_set = 1;
+ else if (unformat (i, "dst %U",
+ unformat_ip6_address, &v6address))
+ v6_address_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\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) {
+ errmsg ("no addresses set\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->is_add = is_add;
+ mp->vrf_id = ntohl (vrf_id);
+ mp->is_static = is_static;
+ if (mac_set)
+ clib_memcpy (mp->mac_address, mac_address, 6);
+ if (v6_address_set) {
+ mp->is_ipv6 = 1;
+ clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
+ } else {
+ /* mp->is_ipv6 = 0; via memset in M macro above */
+ clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
+ }
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply, return good/bad news */
+ W;
+
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_reset_vrf (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_reset_vrf_t *mp;
+ f64 timeout;
+ u32 vrf_id = 0;
+ u8 is_ipv6 = 0;
+ u8 vrf_id_set = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "vrf %d", &vrf_id))
+ vrf_id_set = 1;
+ else if (unformat (i, "ipv6"))
+ is_ipv6 = 1;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (vrf_id_set == 0) {
+ errmsg ("missing vrf id\n");
+ return -99;
+ }
+
+ M(RESET_VRF, reset_vrf);
+
+ mp->vrf_id = ntohl(vrf_id);
+ mp->is_ipv6 = is_ipv6;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_create_vlan_subif (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_create_vlan_subif_t *mp;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u32 vlan_id;
+ u8 vlan_id_set = 0;
+
+ 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", 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\n");
+ return -99;
+ }
+
+ if (vlan_id_set == 0) {
+ errmsg ("missing vlan_id\n");
+ return -99;
+ }
+ M(CREATE_VLAN_SUBIF, create_vlan_subif);
+
+ mp->sw_if_index = ntohl(sw_if_index);
+ mp->vlan_id = ntohl(vlan_id);
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+#define foreach_create_subif_bit \
+_(no_tags) \
+_(one_tag) \
+_(two_tags) \
+_(dot1ad) \
+_(exact_match) \
+_(default_sub) \
+_(outer_vlan_id_any) \
+_(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;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u32 sub_id;
+ u8 sub_id_set = 0;
+ u32 no_tags = 0;
+ u32 one_tag = 0;
+ u32 two_tags = 0;
+ u32 dot1ad = 0;
+ u32 exact_match = 0;
+ u32 default_sub = 0;
+ u32 outer_vlan_id_any = 0;
+ u32 inner_vlan_id_any = 0;
+ u32 tmp;
+ u16 outer_vlan_id = 0;
+ u16 inner_vlan_id = 0;
+
+ 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", 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\n");
+ return -99;
+ }
+
+ if (sub_id_set == 0) {
+ errmsg ("missing sub_id\n");
+ return -99;
+ }
+ M(CREATE_SUBIF, create_subif);
+
+ mp->sw_if_index = ntohl(sw_if_index);
+ mp->sub_id = ntohl(sub_id);
+
+#define _(a) mp->a = a;
+ foreach_create_subif_bit;
+#undef _
+
+ mp->outer_vlan_id = ntohs (outer_vlan_id);
+ mp->inner_vlan_id = ntohs (inner_vlan_id);
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_oam_add_del (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_oam_add_del_t *mp;
+ f64 timeout;
+ u32 vrf_id = 0;
+ u8 is_add = 1;
+ ip4_address_t src, dst;
+ u8 src_set = 0;
+ u8 dst_set = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "src %U", unformat_ip4_address, &src))
+ src_set = 1;
+ else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
+ dst_set = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (src_set == 0) {
+ errmsg ("missing src addr\n");
+ return -99;
+ }
+
+ if (dst_set == 0) {
+ errmsg ("missing dst addr\n");
+ return -99;
+ }
+
+ M(OAM_ADD_DEL, oam_add_del);
+
+ mp->vrf_id = ntohl(vrf_id);
+ mp->is_add = is_add;
+ clib_memcpy(mp->src_address, &src, sizeof (mp->src_address));
+ clib_memcpy(mp->dst_address, &dst, sizeof (mp->dst_address));
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_reset_fib (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_reset_fib_t *mp;
+ f64 timeout;
+ u32 vrf_id = 0;
+ u8 is_ipv6 = 0;
+ u8 vrf_id_set = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "vrf %d", &vrf_id))
+ vrf_id_set = 1;
+ else if (unformat (i, "ipv6"))
+ is_ipv6 = 1;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (vrf_id_set == 0) {
+ errmsg ("missing vrf id\n");
+ return -99;
+ }
+
+ M(RESET_FIB, reset_fib);
+
+ mp->vrf_id = ntohl(vrf_id);
+ mp->is_ipv6 = is_ipv6;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_dhcp_proxy_config (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_dhcp_proxy_config_t *mp;
+ f64 timeout;
+ u32 vrf_id = 0;
+ u8 is_add = 1;
+ u8 insert_cid = 1;
+ u8 v4_address_set = 0;
+ u8 v6_address_set = 0;
+ ip4_address_t v4address;
+ ip6_address_t v6address;
+ u8 v4_src_address_set = 0;
+ u8 v6_src_address_set = 0;
+ ip4_address_t v4srcaddress;
+ ip6_address_t v6srcaddress;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (i, "insert-cid %d", &insert_cid))
+ ;
+ else if (unformat (i, "svr %U",
+ unformat_ip4_address, &v4address))
+ v4_address_set = 1;
+ else if (unformat (i, "svr %U",
+ unformat_ip6_address, &v6address))
+ v6_address_set = 1;
+ else if (unformat (i, "src %U",
+ unformat_ip4_address, &v4srcaddress))
+ v4_src_address_set = 1;
+ else if (unformat (i, "src %U",
+ unformat_ip6_address, &v6srcaddress))
+ v6_src_address_set = 1;
+ else
+ break;
+ }
+
+ if (v4_address_set && v6_address_set) {
+ errmsg ("both v4 and v6 server addresses set\n");
+ return -99;
+ }
+ if (!v4_address_set && !v6_address_set) {
+ errmsg ("no server addresses set\n");
+ return -99;
+ }
+
+ if (v4_src_address_set && v6_src_address_set) {
+ errmsg ("both v4 and v6 src addresses set\n");
+ return -99;
+ }
+ if (!v4_src_address_set && !v6_src_address_set) {
+ errmsg ("no src addresses set\n");
+ return -99;
+ }
+
+ if (!(v4_src_address_set && v4_address_set) &&
+ !(v6_src_address_set && v6_address_set)) {
+ errmsg ("no matching server and src addresses set\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(DHCP_PROXY_CONFIG, dhcp_proxy_config);
+
+ mp->insert_circuit_id = insert_cid;
+ mp->is_add = is_add;
+ mp->vrf_id = ntohl (vrf_id);
+ if (v6_address_set) {
+ mp->is_ipv6 = 1;
+ clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
+ clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
+ } else {
+ clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
+ clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
+ }
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply, return good/bad news */
+ W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_dhcp_proxy_config_2 (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_dhcp_proxy_config_2_t *mp;
+ f64 timeout;
+ u32 rx_vrf_id = 0;
+ u32 server_vrf_id = 0;
+ u8 is_add = 1;
+ u8 insert_cid = 1;
+ u8 v4_address_set = 0;
+ u8 v6_address_set = 0;
+ ip4_address_t v4address;
+ ip6_address_t v6address;
+ u8 v4_src_address_set = 0;
+ u8 v6_src_address_set = 0;
+ ip4_address_t v4srcaddress;
+ ip6_address_t v6srcaddress;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "del"))
+ is_add = 0;
+ else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
+ ;
+ else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
+ ;
+ else if (unformat (i, "insert-cid %d", &insert_cid))
+ ;
+ else if (unformat (i, "svr %U",
+ unformat_ip4_address, &v4address))
+ v4_address_set = 1;
+ else if (unformat (i, "svr %U",
+ unformat_ip6_address, &v6address))
+ v6_address_set = 1;
+ else if (unformat (i, "src %U",
+ unformat_ip4_address, &v4srcaddress))
+ v4_src_address_set = 1;
+ else if (unformat (i, "src %U",
+ unformat_ip6_address, &v6srcaddress))
+ v6_src_address_set = 1;
+ else
+ break;
+ }
+
+ if (v4_address_set && v6_address_set) {
+ errmsg ("both v4 and v6 server addresses set\n");
+ return -99;
+ }
+ if (!v4_address_set && !v6_address_set) {
+ errmsg ("no server addresses set\n");
+ return -99;
+ }
+
+ if (v4_src_address_set && v6_src_address_set) {
+ errmsg ("both v4 and v6 src addresses set\n");
+ return -99;
+ }
+ if (!v4_src_address_set && !v6_src_address_set) {
+ errmsg ("no src addresses set\n");
+ return -99;
+ }
+
+ if (!(v4_src_address_set && v4_address_set) &&
+ !(v6_src_address_set && v6_address_set)) {
+ errmsg ("no matching server and src addresses set\n");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M(DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
+
+ mp->insert_circuit_id = insert_cid;
+ mp->is_add = is_add;
+ mp->rx_vrf_id = ntohl (rx_vrf_id);
+ mp->server_vrf_id = ntohl (server_vrf_id);
+ if (v6_address_set) {
+ mp->is_ipv6 = 1;
+ clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
+ clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
+ } else {
+ clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
+ clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
+ }
+
+ /* send it... */
+ S;
+
+ /* Wait for a reply, return good/bad news */
+ W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_dhcp_proxy_set_vss (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_dhcp_proxy_set_vss_t *mp;
+ f64 timeout;
+ u8 is_ipv6 = 0;
+ u8 is_add = 1;
+ u32 tbl_id;
+ u8 tbl_id_set = 0;
+ u32 oui;
+ u8 oui_set = 0;
+ u32 fib_id;
+ u8 fib_id_set = 0;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "tbl_id %d", &tbl_id))
+ tbl_id_set = 1;
+ if (unformat (i, "fib_id %d", &fib_id))
+ fib_id_set = 1;
+ if (unformat (i, "oui %d", &oui))
+ oui_set = 1;
+ else if (unformat (i, "ipv6"))
+ is_ipv6 = 1;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (tbl_id_set == 0) {
+ errmsg ("missing tbl id\n");
+ return -99;
+ }
+
+ if (fib_id_set == 0) {
+ errmsg ("missing fib id\n");
+ return -99;
+ }
+ if (oui_set == 0) {
+ errmsg ("missing oui\n");
+ return -99;
+ }
+
+ M(DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
+ mp->tbl_id = ntohl(tbl_id);
+ mp->fib_id = ntohl(fib_id);
+ mp->oui = ntohl(oui);
+ mp->is_ipv6 = is_ipv6;
+ mp->is_add = is_add;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static int api_dhcp_client_config (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_dhcp_client_config_t *mp;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+ u8 is_add = 1;
+ u8 * hostname = 0;
+ u8 disable_event = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ 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, "hostname %s", &hostname))
+ ;
+ else if (unformat (i, "disable_event"))
+ disable_event = 1;
+ else
+ break;
+ }
+
+ if (sw_if_index_set == 0) {
+ errmsg ("missing interface name or sw_if_index\n");
+ return -99;
+ }
+
+ if (vec_len (hostname) > 63) {
+ errmsg ("hostname too long\n");
+ }
+ vec_add1 (hostname, 0);
+
+ /* Construct the API message */
+ M(DHCP_CLIENT_CONFIG, dhcp_client_config);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ clib_memcpy (mp->hostname, hostname, vec_len (hostname));
+ vec_free (hostname);
+ mp->is_add = is_add;
+ mp->want_dhcp_event = disable_event ? 0 : 1;
+ mp->pid = getpid();
+
+ /* send it... */