+ /* Construct the API message */
+ M (PG_CREATE_INTERFACE, mp);
+ mp->context = 0;
+ mp->interface_id = ntohl (if_id);
+
+ 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;
+ }
+ }
+
+ u32 name_len = vec_len (pcap_file);
+ /* 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);
+ mp->pcap_name_length = ntohl (name_len);
+ if (pcap_file_set != 0)
+ {
+ clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
+ }
+ 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;
+ }
+ }
+
+ u32 name_len = vec_len (stream_name);
+ /* Construct the API message */
+ M (PG_ENABLE_DISABLE, mp);
+ mp->context = 0;
+ mp->is_enabled = enable;
+ if (stream_name_set != 0)
+ {
+ mp->stream_name_length = ntohl (name_len);
+ clib_memcpy (mp->stream_name, stream_name, name_len);
+ }
+ 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;
+ ip4_address_t ip4_addr;
+ ip6_address_t ip6_addr;
+ u32 length;
+ u32 tmp, tmp2;
+ u8 prefix_set = 0;
+ u32 vrf_id = ~0;
+ u8 is_add = 1;
+ u8 is_ipv6 = 0;
+ int ret;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
+ {
+ prefix_set = 1;
+ }
+ else
+ if (unformat
+ (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
+ {
+ prefix_set = 1;
+ is_ipv6 = 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;
+
+ if (is_ipv6)
+ {
+ mp->is_ipv6 = 1;
+ clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
+ }
+ else
+ {
+ mp->is_ipv6 = 0;
+ clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
+ }
+
+ mp->mask_length = length;
+ 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)
+ {
+ errmsg ("VRF ID required but not specified");
+ return -99;
+ }
+
+ if (tcp_out_vrf_id == 0
+ || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
+ {
+ errmsg
+ ("VRF ID should not be default. Should be distinct VRF for this purpose.");
+ return -99;
+ }
+
+ /* Construct the API message */
+ M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
+
+ mp->sw_if_index = ntohl (sw_if_index);
+ mp->is_add = is_add;
+ mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
+ mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
+ mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
+ mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+ return ret;
+}
+
+static int
+api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ipsec_gre_add_del_tunnel_t *mp;
+ u32 local_sa_id = 0;
+ u32 remote_sa_id = 0;
+ ip4_address_t src_address;
+ ip4_address_t dst_address;
+ u8 is_add = 1;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "local_sa %d", &local_sa_id))
+ ;
+ else if (unformat (i, "remote_sa %d", &remote_sa_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, "del"))
+ is_add = 0;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
+
+ mp->local_sa_id = ntohl (local_sa_id);
+ mp->remote_sa_id = ntohl (remote_sa_id);
+ clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
+ clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
+ mp->is_add = is_add;
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
+api_punt (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_punt_t *mp;
+ u32 ipv = ~0;
+ u32 protocol = ~0;
+ u32 port = ~0;
+ int is_add = 1;
+ int ret;
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "ip %d", &ipv))
+ ;
+ else if (unformat (i, "protocol %d", &protocol))
+ ;
+ else if (unformat (i, "port %d", &port))
+ ;
+ else if (unformat (i, "del"))
+ is_add = 0;
+ else
+ {
+ clib_warning ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ M (PUNT, mp);
+
+ mp->is_add = (u8) is_add;
+ mp->ipv = (u8) ipv;
+ mp->l4_protocol = (u8) protocol;
+ mp->l4_port = htons ((u16) port);