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>
33 #include <vlibmemory/vlib.api_types.h>
35 #define vl_endianfun /* define message structures */
36 #include <vnet/ip/ip.api.h>
41 /* 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 vat_main_t *vam = va_arg (*args, vat_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, api_unformat_sw_if_index, vam,
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, api_unformat_sw_if_index, vam,
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 unformat_input_t *i = vam->input;
241 vl_api_ip_route_add_del_t *mp;
247 vl_api_prefix_t pfx = {};
248 vl_api_fib_path_t paths[8];
252 u32 random_add_del = 0;
253 u32 *random_vector = 0;
254 u32 random_seed = 0xdeaddabe;
256 /* Parse args required to build the message */
257 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
259 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
261 else if (unformat (i, "del"))
263 else if (unformat (i, "add"))
265 else if (unformat (i, "vrf %d", &vrf_id))
267 else if (unformat (i, "count %d", &count))
269 else if (unformat (i, "random"))
271 else if (unformat (i, "multipath"))
273 else if (unformat (i, "seed %d", &random_seed))
275 else if (unformat (i, "via %U", unformat_fib_path, vam,
281 errmsg ("max 8 paths");
287 clib_warning ("parse error '%U'", format_unformat_error, i);
294 errmsg ("specify a path; via ...");
299 errmsg ("missing prefix");
303 /* Generate a pile of unique, random routes */
306 ip4_address_t *i = (ip4_address_t *) &paths[0].nh.address.ip4;
307 u32 this_random_address;
310 random_hash = hash_create (count, sizeof (uword));
312 hash_set (random_hash, i->as_u32, 1);
313 for (j = 0; j <= count; j++)
317 this_random_address = random_u32 (&random_seed);
318 this_random_address = clib_host_to_net_u32 (this_random_address);
320 while (hash_get (random_hash, this_random_address));
321 vec_add1 (random_vector, this_random_address);
322 hash_set (random_hash, this_random_address, 1);
324 hash_free (random_hash);
325 set_ip4_address (&pfx.address, random_vector[0]);
330 /* Turn on async mode */
332 vam->async_errors = 0;
333 before = vat_time_now (vam);
336 for (j = 0; j < count; j++)
338 /* Construct the API message */
339 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
342 mp->is_multipath = is_multipath;
344 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
345 mp->route.table_id = ntohl (vrf_id);
346 mp->route.n_paths = path_count;
348 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
351 set_ip4_address (&pfx.address, random_vector[j + 1]);
353 increment_address (&pfx.address);
356 /* If we receive SIGTERM, stop now... */
361 /* When testing multiple add/del ops, use a control-ping to sync */
364 vl_api_control_ping_t *mp_ping;
368 /* Shut off async mode */
371 PING (&ip_test_main, mp_ping);
374 timeout = vat_time_now (vam) + 1.0;
375 while (vat_time_now (vam) < timeout)
376 if (vam->result_ready == 1)
381 if (vam->retval == -99)
384 if (vam->async_errors > 0)
386 errmsg ("%d asynchronous errors", vam->async_errors);
389 vam->async_errors = 0;
390 after = vat_time_now (vam);
392 /* slim chance, but we might have eaten SIGTERM on the first iteration */
396 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
397 after - before, count / (after - before));
403 /* Wait for a reply... */
408 /* Return the good/bad news */
409 return (vam->retval);
413 api_ip_table_add_del (vat_main_t *vam)
415 unformat_input_t *i = vam->input;
416 vl_api_ip_table_add_del_t *mp;
422 /* Parse args required to build the message */
423 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
425 if (unformat (i, "ipv6"))
427 else if (unformat (i, "del"))
429 else if (unformat (i, "add"))
431 else if (unformat (i, "table %d", &table_id))
435 clib_warning ("parse error '%U'", format_unformat_error, i);
442 errmsg ("missing table-ID");
446 /* Construct the API message */
447 M (IP_TABLE_ADD_DEL, mp);
449 mp->table.table_id = ntohl (table_id);
450 mp->table.is_ip6 = is_ipv6;
456 /* Wait for a reply... */
463 api_ip_table_replace_begin (vat_main_t *vam)
465 unformat_input_t *i = vam->input;
466 vl_api_ip_table_replace_begin_t *mp;
471 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
473 if (unformat (i, "table %d", &table_id))
475 else if (unformat (i, "ipv6"))
479 clib_warning ("parse error '%U'", format_unformat_error, i);
484 M (IP_TABLE_REPLACE_BEGIN, mp);
486 mp->table.table_id = ntohl (table_id);
487 mp->table.is_ip6 = is_ipv6;
495 api_ip_table_flush (vat_main_t *vam)
497 unformat_input_t *i = vam->input;
498 vl_api_ip_table_flush_t *mp;
503 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
505 if (unformat (i, "table %d", &table_id))
507 else if (unformat (i, "ipv6"))
511 clib_warning ("parse error '%U'", format_unformat_error, i);
516 M (IP_TABLE_FLUSH, mp);
518 mp->table.table_id = ntohl (table_id);
519 mp->table.is_ip6 = is_ipv6;
527 api_ip_table_allocate (vat_main_t *vam)
533 vl_api_ip_table_allocate_reply_t_handler (vl_api_ip_table_allocate_reply_t *mp)
538 vl_api_ip_route_add_del_v2_reply_t_handler (
539 vl_api_ip_route_add_del_v2_reply_t *mp)
544 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t *mp)
549 vl_api_ip_route_v2_details_t_handler (vl_api_ip_route_v2_details_t *mp)
554 vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *mp)
556 vat_main_t *vam = ip_test_main.vat_main;
557 vam->result_ready = 1;
561 vl_api_ip_route_lookup_reply_t_handler (vl_api_ip_route_lookup_reply_t *mp)
566 vl_api_ip_route_lookup_v2_reply_t_handler (
567 vl_api_ip_route_lookup_v2_reply_t *mp)
572 api_set_ip_flow_hash_router_id (vat_main_t *vat)
578 api_ip_route_lookup (vat_main_t *vat)
584 api_ip_route_lookup_v2 (vat_main_t *vat)
590 api_set_ip_flow_hash (vat_main_t *vam)
592 unformat_input_t *i = vam->input;
593 vl_api_set_ip_flow_hash_t *mp;
605 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
607 if (unformat (i, "vrf %d", &vrf_id))
609 else if (unformat (i, "ipv6"))
611 else if (unformat (i, "src"))
613 else if (unformat (i, "dst"))
615 else if (unformat (i, "sport"))
617 else if (unformat (i, "dport"))
619 else if (unformat (i, "proto"))
621 else if (unformat (i, "reverse"))
626 clib_warning ("parse error '%U'", format_unformat_error, i);
633 errmsg ("missing vrf id");
637 M (SET_IP_FLOW_HASH, mp);
643 mp->reverse = reverse;
644 mp->vrf_id = ntohl (vrf_id);
645 mp->is_ipv6 = is_ipv6;
653 api_mfib_signal_dump (vat_main_t *vat)
659 api_ip_punt_police (vat_main_t *vat)
665 api_ip_punt_redirect (vat_main_t *vat)
671 api_add_del_ip_punt_redirect_v2 (vat_main_t *vat)
677 api_ip_punt_redirect_dump (vat_main_t *vat)
683 vl_api_ip_punt_redirect_details_t_handler (
684 vl_api_ip_punt_redirect_details_t *mp)
690 api_ip_punt_redirect_v2_dump (vat_main_t *vat)
696 vl_api_ip_punt_redirect_v2_details_t_handler (
697 vl_api_ip_punt_redirect_v2_details_t *mp)
703 api_ip_address_dump (vat_main_t *vam)
705 unformat_input_t *i = vam->input;
706 vl_api_ip_address_dump_t *mp;
707 vl_api_control_ping_t *mp_ping;
708 u32 sw_if_index = ~0;
709 u8 sw_if_index_set = 0;
714 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
716 if (unformat (i, "sw_if_index %d", &sw_if_index))
718 else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
720 else if (unformat (i, "ipv4"))
722 else if (unformat (i, "ipv6"))
728 if (ipv4_set && ipv6_set)
730 errmsg ("ipv4 and ipv6 flags cannot be both set");
734 if ((!ipv4_set) && (!ipv6_set))
736 errmsg ("no ipv4 nor ipv6 flag set");
740 if (sw_if_index_set == 0)
742 errmsg ("missing interface name or sw_if_index");
746 vam->current_sw_if_index = sw_if_index;
747 vam->is_ipv6 = ipv6_set;
749 M (IP_ADDRESS_DUMP, mp);
750 mp->sw_if_index = ntohl (sw_if_index);
751 mp->is_ipv6 = ipv6_set;
754 /* Use a control ping for synchronization */
755 PING (&ip_test_main, mp_ping);
763 vl_api_sw_interface_ip6_get_link_local_address_reply_t_handler (
764 vl_api_sw_interface_ip6_get_link_local_address_reply_t *mp)
769 api_sw_interface_ip6_set_link_local_address (vat_main_t *vam)
775 api_sw_interface_ip6_get_link_local_address (vat_main_t *vam)
781 api_ip_path_mtu_replace_end (vat_main_t *vam)
787 api_ioam_enable (vat_main_t *vam)
789 unformat_input_t *input = vam->input;
790 vl_api_ioam_enable_t *mp;
792 int has_trace_option = 0;
793 int has_pot_option = 0;
794 int has_seqno_option = 0;
795 int has_analyse_option = 0;
798 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
800 if (unformat (input, "trace"))
801 has_trace_option = 1;
802 else if (unformat (input, "pot"))
804 else if (unformat (input, "seqno"))
805 has_seqno_option = 1;
806 else if (unformat (input, "analyse"))
807 has_analyse_option = 1;
813 mp->seqno = has_seqno_option;
814 mp->analyse = has_analyse_option;
815 mp->pot_enable = has_pot_option;
816 mp->trace_enable = has_trace_option;
824 api_ip_reassembly_get (vat_main_t *vam)
830 api_ip_path_mtu_replace_begin (vat_main_t *vam)
836 api_ip_path_mtu_update (vat_main_t *vam)
842 api_ioam_disable (vat_main_t *vam)
844 vl_api_ioam_disable_t *mp;
847 M (IOAM_DISABLE, mp);
854 api_ip_source_and_port_range_check_add_del (vat_main_t *vam)
856 unformat_input_t *input = vam->input;
857 vl_api_ip_source_and_port_range_check_add_del_t *mp;
863 vl_api_prefix_t prefix;
870 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
872 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
874 else if (unformat (input, "vrf %d", &vrf_id))
876 else if (unformat (input, "del"))
878 else if (unformat (input, "port %d", &tmp))
880 if (tmp == 0 || tmp > 65535)
882 errmsg ("port %d out of range", tmp);
886 this_hi = this_low + 1;
887 vec_add1 (low_ports, this_low);
888 vec_add1 (high_ports, this_hi);
890 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
892 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
894 errmsg ("incorrect range parameters");
898 /* Note: in debug CLI +1 is added to high before
899 passing to real fn that does "the work"
900 (ip_source_and_port_range_check_add_del).
901 This fn is a wrapper around the binary API fn a
902 control plane will call, which expects this increment
903 to have occurred. Hence letting the binary API control
904 plane fn do the increment for consistency between VAT
905 and other control planes.
908 vec_add1 (low_ports, this_low);
909 vec_add1 (high_ports, this_hi);
917 errmsg ("<address>/<mask> not specified");
923 errmsg ("VRF ID required, not specified");
929 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
934 if (vec_len (low_ports) == 0)
936 errmsg ("At least one port or port range required");
940 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
944 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
946 mp->number_of_ranges = vec_len (low_ports);
948 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
949 vec_free (low_ports);
951 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
952 vec_free (high_ports);
954 mp->vrf_id = ntohl (vrf_id);
962 api_ip_reassembly_set (vat_main_t *vat)
968 api_ip_container_proxy_add_del (vat_main_t *vam)
970 vl_api_ip_container_proxy_add_del_t *mp;
971 unformat_input_t *i = vam->input;
972 u32 sw_if_index = ~0;
973 vl_api_prefix_t pfx = {};
977 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
979 if (unformat (i, "del"))
981 else if (unformat (i, "add"))
983 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
985 else if (unformat (i, "sw_if_index %u", &sw_if_index))
990 if (sw_if_index == ~0 || pfx.len == 0)
992 errmsg ("address and sw_if_index must be set");
996 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
998 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
1000 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
1008 api_ip_reassembly_enable_disable (vat_main_t *vat)
1014 vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp)
1019 api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam)
1021 unformat_input_t *input = vam->input;
1022 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
1023 u32 sw_if_index = ~0;
1025 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
1026 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
1030 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1032 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1034 else if (unformat (input, "sw_if_index %d", &sw_if_index))
1036 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
1038 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
1040 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
1042 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
1044 else if (unformat (input, "del"))
1050 if (sw_if_index == ~0)
1052 errmsg ("Interface required but not specified");
1058 errmsg ("VRF ID required but not specified");
1062 if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
1065 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
1070 /* Construct the API message */
1071 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
1073 mp->sw_if_index = ntohl (sw_if_index);
1074 mp->is_add = is_add;
1075 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
1076 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
1077 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
1078 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
1083 /* Wait for a reply... */
1089 vl_api_ip_container_proxy_details_t_handler (
1090 vl_api_ip_container_proxy_details_t *mp)
1095 api_ip_container_proxy_dump (vat_main_t *vam)
1101 api_ip_dump (vat_main_t *vam)
1103 vl_api_ip_dump_t *mp;
1104 vl_api_control_ping_t *mp_ping;
1105 unformat_input_t *in = vam->input;
1112 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
1114 if (unformat (in, "ipv4"))
1116 else if (unformat (in, "ipv6"))
1122 if (ipv4_set && ipv6_set)
1124 errmsg ("ipv4 and ipv6 flags cannot be both set");
1128 if ((!ipv4_set) && (!ipv6_set))
1130 errmsg ("no ipv4 nor ipv6 flag set");
1135 vam->is_ipv6 = is_ipv6;
1138 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
1140 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
1142 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
1145 mp->is_ipv6 = ipv6_set;
1148 /* Use a control ping for synchronization */
1149 PING (&ip_test_main, mp_ping);
1157 vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
1162 vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
1164 vat_main_t *vam = ip_test_main.vat_main;
1165 vam->result_ready = 1;
1169 api_ip_mroute_dump (vat_main_t *vam)
1171 unformat_input_t *input = vam->input;
1172 vl_api_control_ping_t *mp_ping;
1173 vl_api_ip_mroute_dump_t *mp;
1178 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1180 if (unformat (input, "table_id %d", &table_id))
1182 else if (unformat (input, "ip6"))
1184 else if (unformat (input, "ip4"))
1191 errmsg ("missing table id");
1195 M (IP_MROUTE_DUMP, mp);
1196 mp->table.table_id = table_id;
1197 mp->table.is_ip6 = is_ip6;
1200 /* Use a control ping for synchronization */
1201 PING (&ip_test_main, mp_ping);
1209 api_sw_interface_ip6_enable_disable (vat_main_t *vam)
1211 unformat_input_t *i = vam->input;
1212 vl_api_sw_interface_ip6_enable_disable_t *mp;
1214 u8 sw_if_index_set = 0;
1218 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1220 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1221 sw_if_index_set = 1;
1222 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1223 sw_if_index_set = 1;
1224 else if (unformat (i, "enable"))
1226 else if (unformat (i, "disable"))
1230 clib_warning ("parse error '%U'", format_unformat_error, i);
1235 if (sw_if_index_set == 0)
1237 errmsg ("missing interface name or sw_if_index");
1241 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
1243 mp->sw_if_index = ntohl (sw_if_index);
1244 mp->enable = enable;
1252 api_set_ip_flow_hash_v2 (vat_main_t *vat)
1258 api_ip_mroute_add_del (vat_main_t *vam)
1260 unformat_input_t *i = vam->input;
1261 u8 path_set = 0, prefix_set = 0, is_add = 1;
1262 vl_api_ip_mroute_add_del_t *mp;
1263 mfib_entry_flags_t eflags = 0;
1264 vl_api_mfib_path_t path;
1265 vl_api_mprefix_t pfx = {};
1269 /* Parse args required to build the message */
1270 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1272 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
1275 pfx.grp_address_length = htons (pfx.grp_address_length);
1277 else if (unformat (i, "del"))
1279 else if (unformat (i, "add"))
1281 else if (unformat (i, "vrf %d", &vrf_id))
1283 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
1284 path.itf_flags = htonl (path.itf_flags);
1285 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
1287 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
1291 clib_warning ("parse error '%U'", format_unformat_error, i);
1296 if (prefix_set == 0)
1298 errmsg ("missing addresses\n");
1303 errmsg ("missing path\n");
1307 /* Construct the API message */
1308 M (IP_MROUTE_ADD_DEL, mp);
1310 mp->is_add = is_add;
1311 mp->is_multipath = 1;
1313 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
1314 mp->route.table_id = htonl (vrf_id);
1315 mp->route.n_paths = 1;
1316 mp->route.entry_flags = htonl (eflags);
1318 clib_memcpy (&mp->route.paths, &path, sizeof (path));
1322 /* Wait for a reply... */
1328 vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
1330 vat_main_t *vam = ip_test_main.vat_main;
1331 vam->result_ready = 1;
1335 api_ip_mtable_dump (vat_main_t *vam)
1337 vl_api_ip_mtable_dump_t *mp;
1338 vl_api_control_ping_t *mp_ping;
1341 M (IP_MTABLE_DUMP, mp);
1344 /* Use a control ping for synchronization */
1345 PING (&ip_test_main, mp_ping);
1353 vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
1355 vat_main_t *vam = ip_test_main.vat_main;
1356 vam->result_ready = 1;
1360 api_ip_table_replace_end (vat_main_t *vam)
1362 unformat_input_t *i = vam->input;
1363 vl_api_ip_table_replace_end_t *mp;
1368 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1370 if (unformat (i, "table %d", &table_id))
1372 else if (unformat (i, "ipv6"))
1376 clib_warning ("parse error '%U'", format_unformat_error, i);
1381 M (IP_TABLE_REPLACE_END, mp);
1383 mp->table.table_id = ntohl (table_id);
1384 mp->table.is_ip6 = is_ipv6;
1392 api_ip_table_dump (vat_main_t *vam)
1394 vl_api_ip_table_dump_t *mp;
1395 vl_api_control_ping_t *mp_ping;
1398 M (IP_TABLE_DUMP, mp);
1401 /* Use a control ping for synchronization */
1402 PING (&ip_test_main, mp_ping);
1410 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
1412 vat_main_t *vam = ip_test_main.vat_main;
1414 fformat (vam->ofp, "%s; table-id %d, prefix %U/%d", mp->table.name,
1415 ntohl (mp->table.table_id));
1416 vam->result_ready = 1;
1420 api_ip_path_mtu_get (vat_main_t *vat)
1426 api_ip_route_v2_dump (vat_main_t *vat)
1432 vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
1437 api_ip_route_dump (vat_main_t *vam)
1439 unformat_input_t *input = vam->input;
1440 vl_api_ip_route_dump_t *mp;
1441 vl_api_control_ping_t *mp_ping;
1447 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1449 if (unformat (input, "table_id %d", &table_id))
1451 else if (unformat (input, "ip6"))
1453 else if (unformat (input, "ip4"))
1460 errmsg ("missing table id");
1464 M (IP_ROUTE_DUMP, mp);
1466 mp->table.table_id = table_id;
1467 mp->table.is_ip6 = is_ip6;
1471 /* Use a control ping for synchronization */
1472 PING (&ip_test_main, mp_ping);
1480 vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
1482 vat_main_t *vam = ip_test_main.vat_main;
1483 static ip_address_details_t empty_ip_address_details = { { 0 } };
1484 ip_address_details_t *address = NULL;
1485 ip_details_t *current_ip_details = NULL;
1486 ip_details_t *details = NULL;
1488 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1490 if (!details || vam->current_sw_if_index >= vec_len (details) ||
1491 !details[vam->current_sw_if_index].present)
1493 errmsg ("ip address details arrived but not stored");
1494 errmsg ("ip_dump should be called first");
1498 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1500 #define addresses (current_ip_details->addr)
1502 vec_validate_init_empty (addresses, vec_len (addresses),
1503 empty_ip_address_details);
1505 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1507 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1508 address->prefix_length = mp->prefix.len;
1513 api_ip_unnumbered_dump (vat_main_t *vam)
1519 vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
1524 vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
1526 vat_main_t *vam = &vat_main;
1527 static ip_details_t empty_ip_details = { 0 };
1528 ip_details_t *ip = NULL;
1529 u32 sw_if_index = ~0;
1531 sw_if_index = ntohl (mp->sw_if_index);
1533 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1534 sw_if_index, empty_ip_details);
1536 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1542 #include <vnet/ip/ip.api_test.c>
1545 * fd.io coding-style-patch-verification: ON
1548 * eval: (c-set-style "gnu")