2 *------------------------------------------------------------------
3 * Copyright (c) 2021 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *------------------------------------------------------------------
19 #include <vlibapi/api.h>
20 #include <vlibmemory/api.h>
21 #include <vppinfra/error.h>
22 #include <vpp/api/types.h>
23 #include <vnet/mpls/packet.h>
24 #include <vnet/ip/ip_types_api.h>
26 #define __plugin_msg_base ip_test_main.msg_id_base
27 #include <vlibapi/vat_helper_macros.h>
29 /* Declare message IDs */
30 #include <vnet/format_fns.h>
31 #include <vnet/ip/ip.api_enum.h>
32 #include <vnet/ip/ip.api_types.h>
34 #define vl_endianfun /* define message structures */
35 #include <vnet/ip/ip.api.h>
40 /* API message ID base */
46 static ip_test_main_t ip_test_main;
49 api_ip_route_add_del_v2 (vat_main_t *vam)
55 set_ip4_address (vl_api_address_t *a, u32 v)
57 if (a->af == ADDRESS_IP4)
59 ip4_address_t *i = (ip4_address_t *) &a->un.ip4;
65 increment_v4_address (vl_api_ip4_address_t *i)
67 ip4_address_t *a = (ip4_address_t *) i;
70 v = ntohl (a->as_u32) + 1;
71 a->as_u32 = ntohl (v);
75 increment_v6_address (vl_api_ip6_address_t *i)
77 ip6_address_t *a = (ip6_address_t *) i;
80 v0 = clib_net_to_host_u64 (a->as_u64[0]);
81 v1 = clib_net_to_host_u64 (a->as_u64[1]);
86 a->as_u64[0] = clib_net_to_host_u64 (v0);
87 a->as_u64[1] = clib_net_to_host_u64 (v1);
91 increment_address (vl_api_address_t *a)
93 if (a->af == ADDRESS_IP4)
94 increment_v4_address (&a->un.ip4);
95 else if (a->af == ADDRESS_IP6)
96 increment_v6_address (&a->un.ip6);
100 unformat_fib_path (unformat_input_t *input, va_list *args)
102 vnet_main_t *vnm = va_arg (*args, vnet_main_t *);
103 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
104 u32 weight, preference;
105 mpls_label_t out_label;
107 clib_memset (path, 0, sizeof (*path));
109 path->sw_if_index = ~0;
113 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
115 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
116 &path->nh.address.ip4, unformat_vnet_sw_interface, vnm,
119 path->proto = FIB_API_PATH_NH_PROTO_IP4;
121 else if (unformat (input, "%U %U", unformat_vl_api_ip6_address,
122 &path->nh.address.ip6, unformat_vnet_sw_interface,
123 vnm, &path->sw_if_index))
125 path->proto = FIB_API_PATH_NH_PROTO_IP6;
127 else if (unformat (input, "weight %u", &weight))
129 path->weight = weight;
131 else if (unformat (input, "preference %u", &preference))
133 path->preference = preference;
135 else if (unformat (input, "%U next-hop-table %d",
136 unformat_vl_api_ip4_address, &path->nh.address.ip4,
139 path->proto = FIB_API_PATH_NH_PROTO_IP4;
141 else if (unformat (input, "%U next-hop-table %d",
142 unformat_vl_api_ip6_address, &path->nh.address.ip6,
145 path->proto = FIB_API_PATH_NH_PROTO_IP6;
147 else if (unformat (input, "%U", unformat_vl_api_ip4_address,
148 &path->nh.address.ip4))
151 * the recursive next-hops are by default in the default table
154 path->sw_if_index = ~0;
155 path->proto = FIB_API_PATH_NH_PROTO_IP4;
157 else if (unformat (input, "%U", unformat_vl_api_ip6_address,
158 &path->nh.address.ip6))
161 * the recursive next-hops are by default in the default table
164 path->sw_if_index = ~0;
165 path->proto = FIB_API_PATH_NH_PROTO_IP6;
167 else if (unformat (input, "resolve-via-host"))
169 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
171 else if (unformat (input, "resolve-via-attached"))
173 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
175 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
177 path->type = FIB_API_PATH_TYPE_LOCAL;
178 path->sw_if_index = ~0;
179 path->proto = FIB_API_PATH_NH_PROTO_IP4;
181 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
183 path->type = FIB_API_PATH_TYPE_LOCAL;
184 path->sw_if_index = ~0;
185 path->proto = FIB_API_PATH_NH_PROTO_IP6;
187 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
189 else if (unformat (input, "via-label %d", &path->nh.via_label))
191 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
192 path->sw_if_index = ~0;
194 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
196 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
197 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
199 else if (unformat (input, "local"))
201 path->type = FIB_API_PATH_TYPE_LOCAL;
203 else if (unformat (input, "out-labels"))
205 while (unformat (input, "%d", &out_label))
207 path->label_stack[path->n_labels].label = out_label;
208 path->label_stack[path->n_labels].is_uniform = 0;
209 path->label_stack[path->n_labels].ttl = 64;
213 else if (unformat (input, "via"))
215 /* new path, back up and return */
216 unformat_put_input (input);
217 unformat_put_input (input);
218 unformat_put_input (input);
219 unformat_put_input (input);
228 path->proto = ntohl (path->proto);
229 path->type = ntohl (path->type);
230 path->flags = ntohl (path->flags);
231 path->table_id = ntohl (path->table_id);
232 path->sw_if_index = ntohl (path->sw_if_index);
238 api_ip_route_add_del (vat_main_t *vam)
240 vnet_main_t *vnm = vnet_get_main ();
241 unformat_input_t *i = vam->input;
242 vl_api_ip_route_add_del_t *mp;
248 vl_api_prefix_t pfx = {};
249 vl_api_fib_path_t paths[8];
253 u32 random_add_del = 0;
254 u32 *random_vector = 0;
255 u32 random_seed = 0xdeaddabe;
257 /* Parse args required to build the message */
258 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
260 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
262 else if (unformat (i, "del"))
264 else if (unformat (i, "add"))
266 else if (unformat (i, "vrf %d", &vrf_id))
268 else if (unformat (i, "count %d", &count))
270 else if (unformat (i, "random"))
272 else if (unformat (i, "multipath"))
274 else if (unformat (i, "seed %d", &random_seed))
276 else if (unformat (i, "via %U", unformat_fib_path, vnm,
282 errmsg ("max 8 paths");
288 clib_warning ("parse error '%U'", format_unformat_error, i);
295 errmsg ("specify a path; via ...");
300 errmsg ("missing prefix");
304 /* Generate a pile of unique, random routes */
307 ip4_address_t *i = (ip4_address_t *) &paths[0].nh.address.ip4;
308 u32 this_random_address;
311 random_hash = hash_create (count, sizeof (uword));
313 hash_set (random_hash, i->as_u32, 1);
314 for (j = 0; j <= count; j++)
318 this_random_address = random_u32 (&random_seed);
319 this_random_address = clib_host_to_net_u32 (this_random_address);
321 while (hash_get (random_hash, this_random_address));
322 vec_add1 (random_vector, this_random_address);
323 hash_set (random_hash, this_random_address, 1);
325 hash_free (random_hash);
326 set_ip4_address (&pfx.address, random_vector[0]);
331 /* Turn on async mode */
333 vam->async_errors = 0;
334 before = vat_time_now (vam);
337 for (j = 0; j < count; j++)
339 /* Construct the API message */
340 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
343 mp->is_multipath = is_multipath;
345 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
346 mp->route.table_id = ntohl (vrf_id);
347 mp->route.n_paths = path_count;
349 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
352 set_ip4_address (&pfx.address, random_vector[j + 1]);
354 increment_address (&pfx.address);
357 /* If we receive SIGTERM, stop now... */
362 /* When testing multiple add/del ops, use a control-ping to sync */
365 vl_api_control_ping_t *mp_ping;
369 /* Shut off async mode */
372 PING (&ip_test_main, mp_ping);
375 timeout = vat_time_now (vam) + 1.0;
376 while (vat_time_now (vam) < timeout)
377 if (vam->result_ready == 1)
382 if (vam->retval == -99)
385 if (vam->async_errors > 0)
387 errmsg ("%d asynchronous errors", vam->async_errors);
390 vam->async_errors = 0;
391 after = vat_time_now (vam);
393 /* slim chance, but we might have eaten SIGTERM on the first iteration */
397 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
398 after - before, count / (after - before));
404 /* Wait for a reply... */
409 /* Return the good/bad news */
410 return (vam->retval);
414 api_ip_table_add_del (vat_main_t *vam)
416 unformat_input_t *i = vam->input;
417 vl_api_ip_table_add_del_t *mp;
423 /* Parse args required to build the message */
424 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
426 if (unformat (i, "ipv6"))
428 else if (unformat (i, "del"))
430 else if (unformat (i, "add"))
432 else if (unformat (i, "table %d", &table_id))
436 clib_warning ("parse error '%U'", format_unformat_error, i);
443 errmsg ("missing table-ID");
447 /* Construct the API message */
448 M (IP_TABLE_ADD_DEL, mp);
450 mp->table.table_id = ntohl (table_id);
451 mp->table.is_ip6 = is_ipv6;
457 /* Wait for a reply... */
464 api_ip_table_replace_begin (vat_main_t *vam)
466 unformat_input_t *i = vam->input;
467 vl_api_ip_table_replace_begin_t *mp;
472 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
474 if (unformat (i, "table %d", &table_id))
476 else if (unformat (i, "ipv6"))
480 clib_warning ("parse error '%U'", format_unformat_error, i);
485 M (IP_TABLE_REPLACE_BEGIN, mp);
487 mp->table.table_id = ntohl (table_id);
488 mp->table.is_ip6 = is_ipv6;
496 api_ip_table_flush (vat_main_t *vam)
498 unformat_input_t *i = vam->input;
499 vl_api_ip_table_flush_t *mp;
504 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
506 if (unformat (i, "table %d", &table_id))
508 else if (unformat (i, "ipv6"))
512 clib_warning ("parse error '%U'", format_unformat_error, i);
517 M (IP_TABLE_FLUSH, mp);
519 mp->table.table_id = ntohl (table_id);
520 mp->table.is_ip6 = is_ipv6;
528 api_ip_table_allocate (vat_main_t *vam)
534 vl_api_ip_table_allocate_reply_t_handler (vl_api_ip_table_allocate_reply_t *mp)
539 vl_api_ip_route_add_del_v2_reply_t_handler (
540 vl_api_ip_route_add_del_v2_reply_t *mp)
545 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t *mp)
550 vl_api_ip_route_v2_details_t_handler (vl_api_ip_route_v2_details_t *mp)
555 vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *mp)
557 vat_main_t *vam = ip_test_main.vat_main;
558 vam->result_ready = 1;
562 vl_api_ip_route_lookup_reply_t_handler (vl_api_ip_route_lookup_reply_t *mp)
567 vl_api_ip_route_lookup_v2_reply_t_handler (
568 vl_api_ip_route_lookup_v2_reply_t *mp)
573 api_set_ip_flow_hash_router_id (vat_main_t *vat)
579 api_ip_route_lookup (vat_main_t *vat)
585 api_ip_route_lookup_v2 (vat_main_t *vat)
591 api_set_ip_flow_hash (vat_main_t *vam)
593 unformat_input_t *i = vam->input;
594 vl_api_set_ip_flow_hash_t *mp;
606 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
608 if (unformat (i, "vrf %d", &vrf_id))
610 else if (unformat (i, "ipv6"))
612 else if (unformat (i, "src"))
614 else if (unformat (i, "dst"))
616 else if (unformat (i, "sport"))
618 else if (unformat (i, "dport"))
620 else if (unformat (i, "proto"))
622 else if (unformat (i, "reverse"))
627 clib_warning ("parse error '%U'", format_unformat_error, i);
634 errmsg ("missing vrf id");
638 M (SET_IP_FLOW_HASH, mp);
644 mp->reverse = reverse;
645 mp->vrf_id = ntohl (vrf_id);
646 mp->is_ipv6 = is_ipv6;
654 api_mfib_signal_dump (vat_main_t *vat)
660 api_ip_punt_police (vat_main_t *vat)
666 api_ip_punt_redirect (vat_main_t *vat)
672 api_add_del_ip_punt_redirect_v2 (vat_main_t *vat)
678 api_ip_punt_redirect_dump (vat_main_t *vat)
684 vl_api_ip_punt_redirect_details_t_handler (
685 vl_api_ip_punt_redirect_details_t *mp)
691 api_ip_punt_redirect_v2_dump (vat_main_t *vat)
697 vl_api_ip_punt_redirect_v2_details_t_handler (
698 vl_api_ip_punt_redirect_v2_details_t *mp)
704 api_ip_address_dump (vat_main_t *vam)
706 vnet_main_t *vnm = vnet_get_main ();
707 unformat_input_t *i = vam->input;
708 vl_api_ip_address_dump_t *mp;
709 vl_api_control_ping_t *mp_ping;
710 u32 sw_if_index = ~0;
711 u8 sw_if_index_set = 0;
716 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
718 if (unformat (i, "sw_if_index %d", &sw_if_index))
720 else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
723 else if (unformat (i, "ipv4"))
725 else if (unformat (i, "ipv6"))
731 if (ipv4_set && ipv6_set)
733 errmsg ("ipv4 and ipv6 flags cannot be both set");
737 if ((!ipv4_set) && (!ipv6_set))
739 errmsg ("no ipv4 nor ipv6 flag set");
743 if (sw_if_index_set == 0)
745 errmsg ("missing interface name or sw_if_index");
749 vam->current_sw_if_index = sw_if_index;
750 vam->is_ipv6 = ipv6_set;
752 M (IP_ADDRESS_DUMP, mp);
753 mp->sw_if_index = ntohl (sw_if_index);
754 mp->is_ipv6 = ipv6_set;
757 /* Use a control ping for synchronization */
758 PING (&ip_test_main, mp_ping);
766 vl_api_sw_interface_ip6_get_link_local_address_reply_t_handler (
767 vl_api_sw_interface_ip6_get_link_local_address_reply_t *mp)
772 api_sw_interface_ip6_set_link_local_address (vat_main_t *vam)
778 api_sw_interface_ip6_get_link_local_address (vat_main_t *vam)
784 api_ip_path_mtu_replace_end (vat_main_t *vam)
790 api_ioam_enable (vat_main_t *vam)
792 unformat_input_t *input = vam->input;
793 vl_api_ioam_enable_t *mp;
795 int has_trace_option = 0;
796 int has_pot_option = 0;
797 int has_seqno_option = 0;
798 int has_analyse_option = 0;
801 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
803 if (unformat (input, "trace"))
804 has_trace_option = 1;
805 else if (unformat (input, "pot"))
807 else if (unformat (input, "seqno"))
808 has_seqno_option = 1;
809 else if (unformat (input, "analyse"))
810 has_analyse_option = 1;
816 mp->seqno = has_seqno_option;
817 mp->analyse = has_analyse_option;
818 mp->pot_enable = has_pot_option;
819 mp->trace_enable = has_trace_option;
827 api_ip_reassembly_get (vat_main_t *vam)
833 api_ip_path_mtu_replace_begin (vat_main_t *vam)
839 api_ip_path_mtu_update (vat_main_t *vam)
845 api_ioam_disable (vat_main_t *vam)
847 vl_api_ioam_disable_t *mp;
850 M (IOAM_DISABLE, mp);
857 api_ip_source_and_port_range_check_add_del (vat_main_t *vam)
859 unformat_input_t *input = vam->input;
860 vl_api_ip_source_and_port_range_check_add_del_t *mp;
866 vl_api_prefix_t prefix;
873 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
875 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
877 else if (unformat (input, "vrf %d", &vrf_id))
879 else if (unformat (input, "del"))
881 else if (unformat (input, "port %d", &tmp))
883 if (tmp == 0 || tmp > 65535)
885 errmsg ("port %d out of range", tmp);
889 this_hi = this_low + 1;
890 vec_add1 (low_ports, this_low);
891 vec_add1 (high_ports, this_hi);
893 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
895 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
897 errmsg ("incorrect range parameters");
901 /* Note: in debug CLI +1 is added to high before
902 passing to real fn that does "the work"
903 (ip_source_and_port_range_check_add_del).
904 This fn is a wrapper around the binary API fn a
905 control plane will call, which expects this increment
906 to have occurred. Hence letting the binary API control
907 plane fn do the increment for consistency between VAT
908 and other control planes.
911 vec_add1 (low_ports, this_low);
912 vec_add1 (high_ports, this_hi);
920 errmsg ("<address>/<mask> not specified");
926 errmsg ("VRF ID required, not specified");
932 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
937 if (vec_len (low_ports) == 0)
939 errmsg ("At least one port or port range required");
943 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
947 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
949 mp->number_of_ranges = vec_len (low_ports);
951 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
952 vec_free (low_ports);
954 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
955 vec_free (high_ports);
957 mp->vrf_id = ntohl (vrf_id);
965 api_ip_reassembly_set (vat_main_t *vat)
971 api_ip_container_proxy_add_del (vat_main_t *vam)
973 vl_api_ip_container_proxy_add_del_t *mp;
974 unformat_input_t *i = vam->input;
975 u32 sw_if_index = ~0;
976 vl_api_prefix_t pfx = {};
980 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
982 if (unformat (i, "del"))
984 else if (unformat (i, "add"))
986 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
988 else if (unformat (i, "sw_if_index %u", &sw_if_index))
993 if (sw_if_index == ~0 || pfx.len == 0)
995 errmsg ("address and sw_if_index must be set");
999 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
1001 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
1002 mp->is_add = is_add;
1003 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
1011 api_ip_reassembly_enable_disable (vat_main_t *vat)
1017 vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp)
1022 api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam)
1024 vnet_main_t *vnm = vnet_get_main ();
1025 unformat_input_t *input = vam->input;
1026 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
1027 u32 sw_if_index = ~0;
1029 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
1030 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
1034 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1036 if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
1039 else if (unformat (input, "sw_if_index %d", &sw_if_index))
1041 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
1043 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
1045 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
1047 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
1049 else if (unformat (input, "del"))
1055 if (sw_if_index == ~0)
1057 errmsg ("Interface required but not specified");
1063 errmsg ("VRF ID required but not specified");
1067 if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
1070 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
1075 /* Construct the API message */
1076 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
1078 mp->sw_if_index = ntohl (sw_if_index);
1079 mp->is_add = is_add;
1080 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
1081 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
1082 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
1083 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
1088 /* Wait for a reply... */
1094 vl_api_ip_container_proxy_details_t_handler (
1095 vl_api_ip_container_proxy_details_t *mp)
1100 api_ip_container_proxy_dump (vat_main_t *vam)
1106 api_ip_dump (vat_main_t *vam)
1108 vl_api_ip_dump_t *mp;
1109 vl_api_control_ping_t *mp_ping;
1110 unformat_input_t *in = vam->input;
1117 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
1119 if (unformat (in, "ipv4"))
1121 else if (unformat (in, "ipv6"))
1127 if (ipv4_set && ipv6_set)
1129 errmsg ("ipv4 and ipv6 flags cannot be both set");
1133 if ((!ipv4_set) && (!ipv6_set))
1135 errmsg ("no ipv4 nor ipv6 flag set");
1140 vam->is_ipv6 = is_ipv6;
1143 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
1145 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
1147 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
1150 mp->is_ipv6 = ipv6_set;
1153 /* Use a control ping for synchronization */
1154 PING (&ip_test_main, mp_ping);
1162 vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
1167 vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
1169 vat_main_t *vam = ip_test_main.vat_main;
1170 vam->result_ready = 1;
1174 api_ip_mroute_dump (vat_main_t *vam)
1176 unformat_input_t *input = vam->input;
1177 vl_api_control_ping_t *mp_ping;
1178 vl_api_ip_mroute_dump_t *mp;
1183 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1185 if (unformat (input, "table_id %d", &table_id))
1187 else if (unformat (input, "ip6"))
1189 else if (unformat (input, "ip4"))
1196 errmsg ("missing table id");
1200 M (IP_MROUTE_DUMP, mp);
1201 mp->table.table_id = table_id;
1202 mp->table.is_ip6 = is_ip6;
1205 /* Use a control ping for synchronization */
1206 PING (&ip_test_main, mp_ping);
1214 api_sw_interface_ip6_enable_disable (vat_main_t *vam)
1216 vnet_main_t *vnm = vnet_get_main ();
1217 unformat_input_t *i = vam->input;
1218 vl_api_sw_interface_ip6_enable_disable_t *mp;
1220 u8 sw_if_index_set = 0;
1224 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1226 if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
1227 sw_if_index_set = 1;
1228 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1229 sw_if_index_set = 1;
1230 else if (unformat (i, "enable"))
1232 else if (unformat (i, "disable"))
1236 clib_warning ("parse error '%U'", format_unformat_error, i);
1241 if (sw_if_index_set == 0)
1243 errmsg ("missing interface name or sw_if_index");
1247 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
1249 mp->sw_if_index = ntohl (sw_if_index);
1250 mp->enable = enable;
1258 api_set_ip_flow_hash_v2 (vat_main_t *vat)
1264 api_ip_mroute_add_del (vat_main_t *vam)
1266 unformat_input_t *i = vam->input;
1267 u8 path_set = 0, prefix_set = 0, is_add = 1;
1268 vl_api_ip_mroute_add_del_t *mp;
1269 mfib_entry_flags_t eflags = 0;
1270 vl_api_mfib_path_t path;
1271 vl_api_mprefix_t pfx = {};
1275 /* Parse args required to build the message */
1276 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1278 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
1281 pfx.grp_address_length = htons (pfx.grp_address_length);
1283 else if (unformat (i, "del"))
1285 else if (unformat (i, "add"))
1287 else if (unformat (i, "vrf %d", &vrf_id))
1289 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
1290 path.itf_flags = htonl (path.itf_flags);
1291 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
1293 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
1297 clib_warning ("parse error '%U'", format_unformat_error, i);
1302 if (prefix_set == 0)
1304 errmsg ("missing addresses\n");
1309 errmsg ("missing path\n");
1313 /* Construct the API message */
1314 M (IP_MROUTE_ADD_DEL, mp);
1316 mp->is_add = is_add;
1317 mp->is_multipath = 1;
1319 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
1320 mp->route.table_id = htonl (vrf_id);
1321 mp->route.n_paths = 1;
1322 mp->route.entry_flags = htonl (eflags);
1324 clib_memcpy (&mp->route.paths, &path, sizeof (path));
1328 /* Wait for a reply... */
1334 vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
1336 vat_main_t *vam = ip_test_main.vat_main;
1337 vam->result_ready = 1;
1341 api_ip_mtable_dump (vat_main_t *vam)
1343 vl_api_ip_mtable_dump_t *mp;
1344 vl_api_control_ping_t *mp_ping;
1347 M (IP_MTABLE_DUMP, mp);
1350 /* Use a control ping for synchronization */
1351 PING (&ip_test_main, mp_ping);
1359 vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
1361 vat_main_t *vam = ip_test_main.vat_main;
1362 vam->result_ready = 1;
1366 api_ip_table_replace_end (vat_main_t *vam)
1368 unformat_input_t *i = vam->input;
1369 vl_api_ip_table_replace_end_t *mp;
1374 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1376 if (unformat (i, "table %d", &table_id))
1378 else if (unformat (i, "ipv6"))
1382 clib_warning ("parse error '%U'", format_unformat_error, i);
1387 M (IP_TABLE_REPLACE_END, mp);
1389 mp->table.table_id = ntohl (table_id);
1390 mp->table.is_ip6 = is_ipv6;
1398 api_ip_table_dump (vat_main_t *vam)
1400 vl_api_ip_table_dump_t *mp;
1401 vl_api_control_ping_t *mp_ping;
1404 M (IP_TABLE_DUMP, mp);
1407 /* Use a control ping for synchronization */
1408 PING (&ip_test_main, mp_ping);
1416 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
1418 vat_main_t *vam = ip_test_main.vat_main;
1420 fformat (vam->ofp, "%s; table-id %d, prefix %U/%d", mp->table.name,
1421 ntohl (mp->table.table_id));
1422 vam->result_ready = 1;
1426 api_ip_path_mtu_get (vat_main_t *vat)
1432 api_ip_route_v2_dump (vat_main_t *vat)
1438 vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
1443 api_ip_route_dump (vat_main_t *vam)
1445 unformat_input_t *input = vam->input;
1446 vl_api_ip_route_dump_t *mp;
1447 vl_api_control_ping_t *mp_ping;
1453 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1455 if (unformat (input, "table_id %d", &table_id))
1457 else if (unformat (input, "ip6"))
1459 else if (unformat (input, "ip4"))
1466 errmsg ("missing table id");
1470 M (IP_ROUTE_DUMP, mp);
1472 mp->table.table_id = table_id;
1473 mp->table.is_ip6 = is_ip6;
1477 /* Use a control ping for synchronization */
1478 PING (&ip_test_main, mp_ping);
1486 vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
1488 vat_main_t *vam = ip_test_main.vat_main;
1489 static ip_address_details_t empty_ip_address_details = { { 0 } };
1490 ip_address_details_t *address = NULL;
1491 ip_details_t *current_ip_details = NULL;
1492 ip_details_t *details = NULL;
1494 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1496 if (!details || vam->current_sw_if_index >= vec_len (details) ||
1497 !details[vam->current_sw_if_index].present)
1499 errmsg ("ip address details arrived but not stored");
1500 errmsg ("ip_dump should be called first");
1504 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1506 #define addresses (current_ip_details->addr)
1508 vec_validate_init_empty (addresses, vec_len (addresses),
1509 empty_ip_address_details);
1511 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1513 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1514 address->prefix_length = mp->prefix.len;
1519 api_ip_unnumbered_dump (vat_main_t *vam)
1525 vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
1530 vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
1532 vat_main_t *vam = &vat_main;
1533 static ip_details_t empty_ip_details = { 0 };
1534 ip_details_t *ip = NULL;
1535 u32 sw_if_index = ~0;
1537 sw_if_index = ntohl (mp->sw_if_index);
1539 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1540 sw_if_index, empty_ip_details);
1542 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1548 #include <vnet/ip/ip.api_test.c>
1551 * fd.io coding-style-patch-verification: ON
1554 * eval: (c-set-style "gnu")