+ if (VAT_JSON_ARRAY != vam->json_tree.type)
+ {
+ ASSERT (VAT_JSON_NONE == vam->json_tree.type);
+ vat_json_init_array (&vam->json_tree);
+ }
+ node = vat_json_array_add (&vam->json_tree);
+
+ vat_json_init_object (node);
+ vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
+ vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
+ vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
+ if (0 != sw_if_to_name)
+ {
+ vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
+ }
+ vat_json_object_add_uint (node, "state", mp->state);
+ vat_json_object_add_uint (node, "is-l2", mp->is_l2);
+}
+
+static int
+api_sw_interface_span_dump (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_sw_interface_span_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ u8 is_l2 = 0;
+ int ret;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "l2"))
+ is_l2 = 1;
+ else
+ break;
+ }
+
+ M (SW_INTERFACE_SPAN_DUMP, mp);
+ mp->is_l2 = is_l2;
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ MPING (CONTROL_PING, mp_ping);
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+int
+api_pg_create_interface (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_pg_create_interface_t *mp;
+
+ u32 if_id = ~0, gso_size = 0;
+ u8 gso_enabled = 0;
+ int ret;
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "if_id %d", &if_id))
+ ;
+ else if (unformat (input, "gso-enabled"))
+ {
+ gso_enabled = 1;
+ if (unformat (input, "gso-size %u", &gso_size))
+ ;
+ else
+ {
+ errmsg ("missing gso-size");
+ return -99;
+ }
+ }
+ else
+ break;
+ }
+ if (if_id == ~0)
+ {
+ errmsg ("missing pg interface index");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (PG_CREATE_INTERFACE, mp);
+ mp->context = 0;
+ mp->interface_id = ntohl (if_id);
+ mp->gso_enabled = gso_enabled;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+int
+api_pg_capture (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_pg_capture_t *mp;
+
+ u32 if_id = ~0;
+ u8 enable = 1;
+ u32 count = 1;
+ u8 pcap_file_set = 0;
+ u8 *pcap_file = 0;
+ int ret;
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "if_id %d", &if_id))
+ ;
+ else if (unformat (input, "pcap %s", &pcap_file))
+ pcap_file_set = 1;
+ else if (unformat (input, "count %d", &count))
+ ;
+ else if (unformat (input, "disable"))
+ enable = 0;
+ else
+ break;
+ }
+ if (if_id == ~0)
+ {
+ errmsg ("missing pg interface index");
+ return -99;
+ }
+ if (pcap_file_set > 0)
+ {
+ if (vec_len (pcap_file) > 255)
+ {
+ errmsg ("pcap file name is too long");
+ return -99;
+ }
+ }
+
+ /* Construct the API message */
+ M (PG_CAPTURE, mp);
+ mp->context = 0;
+ mp->interface_id = ntohl (if_id);
+ mp->is_enabled = enable;
+ mp->count = ntohl (count);
+ if (pcap_file_set != 0)
+ {
+ vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
+ }
+ vec_free (pcap_file);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+int
+api_pg_enable_disable (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_pg_enable_disable_t *mp;
+
+ u8 enable = 1;
+ u8 stream_name_set = 0;
+ u8 *stream_name = 0;
+ int ret;
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "stream %s", &stream_name))
+ stream_name_set = 1;
+ else if (unformat (input, "disable"))
+ enable = 0;
+ else
+ break;
+ }
+
+ if (stream_name_set > 0)
+ {
+ if (vec_len (stream_name) > 255)
+ {
+ errmsg ("stream name too long");
+ return -99;
+ }
+ }
+
+ /* Construct the API message */
+ M (PG_ENABLE_DISABLE, mp);
+ mp->context = 0;
+ mp->is_enabled = enable;
+ if (stream_name_set != 0)
+ {
+ vl_api_vec_to_api_string (stream_name, &mp->stream_name);
+ }
+ vec_free (stream_name);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+int
+api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_ip_source_and_port_range_check_add_del_t *mp;
+
+ u16 *low_ports = 0;
+ u16 *high_ports = 0;
+ u16 this_low;
+ u16 this_hi;
+ vl_api_prefix_t prefix;
+ u32 tmp, tmp2;
+ u8 prefix_set = 0;
+ u32 vrf_id = ~0;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
+ prefix_set = 1;
+ else if (unformat (input, "vrf %d", &vrf_id))
+ ;
+ else if (unformat (input, "del"))
+ is_add = 0;
+ else if (unformat (input, "port %d", &tmp))
+ {
+ if (tmp == 0 || tmp > 65535)
+ {
+ errmsg ("port %d out of range", tmp);
+ return -99;
+ }
+ this_low = tmp;
+ this_hi = this_low + 1;
+ vec_add1 (low_ports, this_low);
+ vec_add1 (high_ports, this_hi);
+ }
+ else if (unformat (input, "range %d - %d", &tmp, &tmp2))
+ {
+ if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
+ {
+ errmsg ("incorrect range parameters");
+ return -99;
+ }
+ this_low = tmp;
+ /* Note: in debug CLI +1 is added to high before
+ passing to real fn that does "the work"
+ (ip_source_and_port_range_check_add_del).
+ This fn is a wrapper around the binary API fn a
+ control plane will call, which expects this increment
+ to have occurred. Hence letting the binary API control
+ plane fn do the increment for consistency between VAT
+ and other control planes.
+ */
+ this_hi = tmp2;
+ vec_add1 (low_ports, this_low);
+ vec_add1 (high_ports, this_hi);
+ }
+ else
+ break;
+ }
+
+ if (prefix_set == 0)
+ {
+ errmsg ("<address>/<mask> not specified");
+ return -99;
+ }
+
+ if (vrf_id == ~0)
+ {
+ errmsg ("VRF ID required, not specified");
+ return -99;
+ }
+
+ if (vrf_id == 0)
+ {
+ errmsg
+ ("VRF ID should not be default. Should be distinct VRF for this purpose.");
+ return -99;
+ }
+
+ if (vec_len (low_ports) == 0)
+ {
+ errmsg ("At least one port or port range required");
+ return -99;
+ }
+
+ M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
+
+ mp->is_add = is_add;
+
+ clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
+
+ mp->number_of_ranges = vec_len (low_ports);
+
+ clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
+ vec_free (low_ports);
+
+ clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
+ vec_free (high_ports);
+
+ mp->vrf_id = ntohl (vrf_id);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+int
+api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
+ u32 sw_if_index = ~0;
+ int vrf_set = 0;
+ u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
+ u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
+ ;
+ else if (unformat (input, "sw_if_index %d", &sw_if_index))
+ ;
+ else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
+ vrf_set = 1;
+ else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
+ vrf_set = 1;
+ else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
+ vrf_set = 1;
+ else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
+ vrf_set = 1;
+ else if (unformat (input, "del"))
+ is_add = 0;
+ else
+ break;
+ }
+
+ if (sw_if_index == ~0)
+ {
+ errmsg ("Interface required but not specified");
+ return -99;
+ }
+
+ if (vrf_set == 0)