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>
39 #define vl_calcsizefun
40 #include <vnet/ip/ip.api.h>
45 /* API message ID base */
50 static ip_test_main_t ip_test_main;
53 api_ip_route_add_del_v2 (vat_main_t *vam)
59 set_ip4_address (vl_api_address_t *a, u32 v)
61 if (a->af == ADDRESS_IP4)
63 ip4_address_t *i = (ip4_address_t *) &a->un.ip4;
69 increment_v4_address (vl_api_ip4_address_t *i)
71 ip4_address_t *a = (ip4_address_t *) i;
74 v = ntohl (a->as_u32) + 1;
75 a->as_u32 = ntohl (v);
79 increment_v6_address (vl_api_ip6_address_t *i)
81 ip6_address_t *a = (ip6_address_t *) i;
84 v0 = clib_net_to_host_u64 (a->as_u64[0]);
85 v1 = clib_net_to_host_u64 (a->as_u64[1]);
90 a->as_u64[0] = clib_net_to_host_u64 (v0);
91 a->as_u64[1] = clib_net_to_host_u64 (v1);
95 increment_address (vl_api_address_t *a)
97 if (a->af == ADDRESS_IP4)
98 increment_v4_address (&a->un.ip4);
99 else if (a->af == ADDRESS_IP6)
100 increment_v6_address (&a->un.ip6);
104 unformat_fib_path (unformat_input_t *input, va_list *args)
106 vat_main_t *vam = va_arg (*args, vat_main_t *);
107 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
108 u32 weight, preference;
109 mpls_label_t out_label;
111 clib_memset (path, 0, sizeof (*path));
113 path->sw_if_index = ~0;
117 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
119 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
120 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
123 path->proto = FIB_API_PATH_NH_PROTO_IP4;
125 else if (unformat (input, "%U %U", unformat_vl_api_ip6_address,
126 &path->nh.address.ip6, api_unformat_sw_if_index, vam,
129 path->proto = FIB_API_PATH_NH_PROTO_IP6;
131 else if (unformat (input, "weight %u", &weight))
133 path->weight = weight;
135 else if (unformat (input, "preference %u", &preference))
137 path->preference = preference;
139 else if (unformat (input, "%U next-hop-table %d",
140 unformat_vl_api_ip4_address, &path->nh.address.ip4,
143 path->proto = FIB_API_PATH_NH_PROTO_IP4;
145 else if (unformat (input, "%U next-hop-table %d",
146 unformat_vl_api_ip6_address, &path->nh.address.ip6,
149 path->proto = FIB_API_PATH_NH_PROTO_IP6;
151 else if (unformat (input, "%U", unformat_vl_api_ip4_address,
152 &path->nh.address.ip4))
155 * the recursive next-hops are by default in the default table
158 path->sw_if_index = ~0;
159 path->proto = FIB_API_PATH_NH_PROTO_IP4;
161 else if (unformat (input, "%U", unformat_vl_api_ip6_address,
162 &path->nh.address.ip6))
165 * the recursive next-hops are by default in the default table
168 path->sw_if_index = ~0;
169 path->proto = FIB_API_PATH_NH_PROTO_IP6;
171 else if (unformat (input, "resolve-via-host"))
173 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
175 else if (unformat (input, "resolve-via-attached"))
177 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
179 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
181 path->type = FIB_API_PATH_TYPE_LOCAL;
182 path->sw_if_index = ~0;
183 path->proto = FIB_API_PATH_NH_PROTO_IP4;
185 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
187 path->type = FIB_API_PATH_TYPE_LOCAL;
188 path->sw_if_index = ~0;
189 path->proto = FIB_API_PATH_NH_PROTO_IP6;
191 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
193 else if (unformat (input, "via-label %d", &path->nh.via_label))
195 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
196 path->sw_if_index = ~0;
198 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
200 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
201 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
203 else if (unformat (input, "local"))
205 path->type = FIB_API_PATH_TYPE_LOCAL;
207 else if (unformat (input, "out-labels"))
209 while (unformat (input, "%d", &out_label))
211 path->label_stack[path->n_labels].label = out_label;
212 path->label_stack[path->n_labels].is_uniform = 0;
213 path->label_stack[path->n_labels].ttl = 64;
217 else if (unformat (input, "via"))
219 /* new path, back up and return */
220 unformat_put_input (input);
221 unformat_put_input (input);
222 unformat_put_input (input);
223 unformat_put_input (input);
232 path->proto = ntohl (path->proto);
233 path->type = ntohl (path->type);
234 path->flags = ntohl (path->flags);
235 path->table_id = ntohl (path->table_id);
236 path->sw_if_index = ntohl (path->sw_if_index);
242 api_ip_route_add_del (vat_main_t *vam)
244 unformat_input_t *i = vam->input;
245 vl_api_ip_route_add_del_t *mp;
251 vl_api_prefix_t pfx = {};
252 vl_api_fib_path_t paths[8];
256 u32 random_add_del = 0;
257 u32 *random_vector = 0;
258 u32 random_seed = 0xdeaddabe;
260 /* Parse args required to build the message */
261 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
263 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
265 else if (unformat (i, "del"))
267 else if (unformat (i, "add"))
269 else if (unformat (i, "vrf %d", &vrf_id))
271 else if (unformat (i, "count %d", &count))
273 else if (unformat (i, "random"))
275 else if (unformat (i, "multipath"))
277 else if (unformat (i, "seed %d", &random_seed))
279 else if (unformat (i, "via %U", unformat_fib_path, vam,
285 errmsg ("max 8 paths");
291 clib_warning ("parse error '%U'", format_unformat_error, i);
298 errmsg ("specify a path; via ...");
303 errmsg ("missing prefix");
307 /* Generate a pile of unique, random routes */
310 ip4_address_t *i = (ip4_address_t *) &paths[0].nh.address.ip4;
311 u32 this_random_address;
314 random_hash = hash_create (count, sizeof (uword));
316 hash_set (random_hash, i->as_u32, 1);
317 for (j = 0; j <= count; j++)
321 this_random_address = random_u32 (&random_seed);
322 this_random_address = clib_host_to_net_u32 (this_random_address);
324 while (hash_get (random_hash, this_random_address));
325 vec_add1 (random_vector, this_random_address);
326 hash_set (random_hash, this_random_address, 1);
328 hash_free (random_hash);
329 set_ip4_address (&pfx.address, random_vector[0]);
334 /* Turn on async mode */
336 vam->async_errors = 0;
337 before = vat_time_now (vam);
340 for (j = 0; j < count; j++)
342 /* Construct the API message */
343 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
346 mp->is_multipath = is_multipath;
348 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
349 mp->route.table_id = ntohl (vrf_id);
350 mp->route.n_paths = path_count;
352 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
355 set_ip4_address (&pfx.address, random_vector[j + 1]);
357 increment_address (&pfx.address);
360 /* If we receive SIGTERM, stop now... */
365 /* When testing multiple add/del ops, use a control-ping to sync */
368 vl_api_control_ping_t *mp_ping;
372 /* Shut off async mode */
375 PING (&ip_test_main, mp_ping);
378 timeout = vat_time_now (vam) + 1.0;
379 while (vat_time_now (vam) < timeout)
380 if (vam->result_ready == 1)
385 if (vam->retval == -99)
388 if (vam->async_errors > 0)
390 errmsg ("%d asynchronous errors", vam->async_errors);
393 vam->async_errors = 0;
394 after = vat_time_now (vam);
396 /* slim chance, but we might have eaten SIGTERM on the first iteration */
400 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
401 after - before, count / (after - before));
407 /* Wait for a reply... */
412 /* Return the good/bad news */
413 return (vam->retval);
417 api_ip_table_add_del (vat_main_t *vam)
419 unformat_input_t *i = vam->input;
420 vl_api_ip_table_add_del_t *mp;
426 /* Parse args required to build the message */
427 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
429 if (unformat (i, "ipv6"))
431 else if (unformat (i, "del"))
433 else if (unformat (i, "add"))
435 else if (unformat (i, "table %d", &table_id))
439 clib_warning ("parse error '%U'", format_unformat_error, i);
446 errmsg ("missing table-ID");
450 /* Construct the API message */
451 M (IP_TABLE_ADD_DEL, mp);
453 mp->table.table_id = ntohl (table_id);
454 mp->table.is_ip6 = is_ipv6;
460 /* Wait for a reply... */
467 api_ip_table_replace_begin (vat_main_t *vam)
469 unformat_input_t *i = vam->input;
470 vl_api_ip_table_replace_begin_t *mp;
475 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
477 if (unformat (i, "table %d", &table_id))
479 else if (unformat (i, "ipv6"))
483 clib_warning ("parse error '%U'", format_unformat_error, i);
488 M (IP_TABLE_REPLACE_BEGIN, mp);
490 mp->table.table_id = ntohl (table_id);
491 mp->table.is_ip6 = is_ipv6;
499 api_ip_table_flush (vat_main_t *vam)
501 unformat_input_t *i = vam->input;
502 vl_api_ip_table_flush_t *mp;
507 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
509 if (unformat (i, "table %d", &table_id))
511 else if (unformat (i, "ipv6"))
515 clib_warning ("parse error '%U'", format_unformat_error, i);
520 M (IP_TABLE_FLUSH, mp);
522 mp->table.table_id = ntohl (table_id);
523 mp->table.is_ip6 = is_ipv6;
531 api_ip_table_allocate (vat_main_t *vam)
537 vl_api_ip_table_allocate_reply_t_handler (vl_api_ip_table_allocate_reply_t *mp)
542 vl_api_ip_route_add_del_v2_reply_t_handler (
543 vl_api_ip_route_add_del_v2_reply_t *mp)
548 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t *mp)
553 vl_api_ip_route_v2_details_t_handler (vl_api_ip_route_v2_details_t *mp)
558 vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *mp)
560 vat_main_t *vam = ip_test_main.vat_main;
561 vam->result_ready = 1;
565 vl_api_ip_route_lookup_reply_t_handler (vl_api_ip_route_lookup_reply_t *mp)
570 vl_api_ip_route_lookup_v2_reply_t_handler (
571 vl_api_ip_route_lookup_v2_reply_t *mp)
576 api_set_ip_flow_hash_router_id (vat_main_t *vat)
582 api_ip_route_lookup (vat_main_t *vat)
588 api_ip_route_lookup_v2 (vat_main_t *vat)
594 api_set_ip_flow_hash (vat_main_t *vam)
596 unformat_input_t *i = vam->input;
597 vl_api_set_ip_flow_hash_t *mp;
609 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
611 if (unformat (i, "vrf %d", &vrf_id))
613 else if (unformat (i, "ipv6"))
615 else if (unformat (i, "src"))
617 else if (unformat (i, "dst"))
619 else if (unformat (i, "sport"))
621 else if (unformat (i, "dport"))
623 else if (unformat (i, "proto"))
625 else if (unformat (i, "reverse"))
630 clib_warning ("parse error '%U'", format_unformat_error, i);
637 errmsg ("missing vrf id");
641 M (SET_IP_FLOW_HASH, mp);
647 mp->reverse = reverse;
648 mp->vrf_id = ntohl (vrf_id);
649 mp->is_ipv6 = is_ipv6;
657 api_mfib_signal_dump (vat_main_t *vat)
663 api_ip_punt_police (vat_main_t *vat)
669 api_ip_punt_redirect (vat_main_t *vat)
675 api_add_del_ip_punt_redirect_v2 (vat_main_t *vat)
681 api_ip_punt_redirect_dump (vat_main_t *vat)
687 vl_api_ip_punt_redirect_details_t_handler (
688 vl_api_ip_punt_redirect_details_t *mp)
694 api_ip_punt_redirect_v2_dump (vat_main_t *vat)
700 vl_api_ip_punt_redirect_v2_details_t_handler (
701 vl_api_ip_punt_redirect_v2_details_t *mp)
707 api_ip_address_dump (vat_main_t *vam)
709 unformat_input_t *i = vam->input;
710 vl_api_ip_address_dump_t *mp;
711 vl_api_control_ping_t *mp_ping;
712 u32 sw_if_index = ~0;
713 u8 sw_if_index_set = 0;
718 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
720 if (unformat (i, "sw_if_index %d", &sw_if_index))
722 else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
724 else if (unformat (i, "ipv4"))
726 else if (unformat (i, "ipv6"))
732 if (ipv4_set && ipv6_set)
734 errmsg ("ipv4 and ipv6 flags cannot be both set");
738 if ((!ipv4_set) && (!ipv6_set))
740 errmsg ("no ipv4 nor ipv6 flag set");
744 if (sw_if_index_set == 0)
746 errmsg ("missing interface name or sw_if_index");
750 vam->current_sw_if_index = sw_if_index;
751 vam->is_ipv6 = ipv6_set;
753 M (IP_ADDRESS_DUMP, mp);
754 mp->sw_if_index = ntohl (sw_if_index);
755 mp->is_ipv6 = ipv6_set;
758 /* Use a control ping for synchronization */
759 PING (&ip_test_main, mp_ping);
767 vl_api_sw_interface_ip6_get_link_local_address_reply_t_handler (
768 vl_api_sw_interface_ip6_get_link_local_address_reply_t *mp)
773 api_sw_interface_ip6_set_link_local_address (vat_main_t *vam)
779 api_sw_interface_ip6_get_link_local_address (vat_main_t *vam)
785 api_ip_path_mtu_replace_end (vat_main_t *vam)
791 api_ioam_enable (vat_main_t *vam)
793 unformat_input_t *input = vam->input;
794 vl_api_ioam_enable_t *mp;
796 int has_trace_option = 0;
797 int has_pot_option = 0;
798 int has_seqno_option = 0;
799 int has_analyse_option = 0;
802 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
804 if (unformat (input, "trace"))
805 has_trace_option = 1;
806 else if (unformat (input, "pot"))
808 else if (unformat (input, "seqno"))
809 has_seqno_option = 1;
810 else if (unformat (input, "analyse"))
811 has_analyse_option = 1;
817 mp->seqno = has_seqno_option;
818 mp->analyse = has_analyse_option;
819 mp->pot_enable = has_pot_option;
820 mp->trace_enable = has_trace_option;
828 api_ip_reassembly_get (vat_main_t *vam)
834 api_ip_path_mtu_replace_begin (vat_main_t *vam)
840 api_ip_path_mtu_update (vat_main_t *vam)
846 api_ioam_disable (vat_main_t *vam)
848 vl_api_ioam_disable_t *mp;
851 M (IOAM_DISABLE, mp);
858 api_ip_source_and_port_range_check_add_del (vat_main_t *vam)
860 unformat_input_t *input = vam->input;
861 vl_api_ip_source_and_port_range_check_add_del_t *mp;
867 vl_api_prefix_t prefix;
874 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
876 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
878 else if (unformat (input, "vrf %d", &vrf_id))
880 else if (unformat (input, "del"))
882 else if (unformat (input, "port %d", &tmp))
884 if (tmp == 0 || tmp > 65535)
886 errmsg ("port %d out of range", tmp);
890 this_hi = this_low + 1;
891 vec_add1 (low_ports, this_low);
892 vec_add1 (high_ports, this_hi);
894 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
896 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
898 errmsg ("incorrect range parameters");
902 /* Note: in debug CLI +1 is added to high before
903 passing to real fn that does "the work"
904 (ip_source_and_port_range_check_add_del).
905 This fn is a wrapper around the binary API fn a
906 control plane will call, which expects this increment
907 to have occurred. Hence letting the binary API control
908 plane fn do the increment for consistency between VAT
909 and other control planes.
912 vec_add1 (low_ports, this_low);
913 vec_add1 (high_ports, this_hi);
921 errmsg ("<address>/<mask> not specified");
927 errmsg ("VRF ID required, not specified");
933 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
938 if (vec_len (low_ports) == 0)
940 errmsg ("At least one port or port range required");
944 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
948 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
950 mp->number_of_ranges = vec_len (low_ports);
952 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
953 vec_free (low_ports);
955 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
956 vec_free (high_ports);
958 mp->vrf_id = ntohl (vrf_id);
966 api_ip_reassembly_set (vat_main_t *vat)
972 api_ip_container_proxy_add_del (vat_main_t *vam)
974 vl_api_ip_container_proxy_add_del_t *mp;
975 unformat_input_t *i = vam->input;
976 u32 sw_if_index = ~0;
977 vl_api_prefix_t pfx = {};
981 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
983 if (unformat (i, "del"))
985 else if (unformat (i, "add"))
987 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
989 else if (unformat (i, "sw_if_index %u", &sw_if_index))
994 if (sw_if_index == ~0 || pfx.len == 0)
996 errmsg ("address and sw_if_index must be set");
1000 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
1002 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
1003 mp->is_add = is_add;
1004 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
1012 api_ip_reassembly_enable_disable (vat_main_t *vat)
1018 vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp)
1023 api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam)
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", api_unformat_sw_if_index, vam, &sw_if_index))
1038 else if (unformat (input, "sw_if_index %d", &sw_if_index))
1040 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
1042 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
1044 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
1046 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
1048 else if (unformat (input, "del"))
1054 if (sw_if_index == ~0)
1056 errmsg ("Interface required but not specified");
1062 errmsg ("VRF ID required but not specified");
1066 if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
1069 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
1074 /* Construct the API message */
1075 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
1077 mp->sw_if_index = ntohl (sw_if_index);
1078 mp->is_add = is_add;
1079 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
1080 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
1081 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
1082 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
1087 /* Wait for a reply... */
1093 vl_api_ip_container_proxy_details_t_handler (
1094 vl_api_ip_container_proxy_details_t *mp)
1099 api_ip_container_proxy_dump (vat_main_t *vam)
1105 api_ip_dump (vat_main_t *vam)
1107 vl_api_ip_dump_t *mp;
1108 vl_api_control_ping_t *mp_ping;
1109 unformat_input_t *in = vam->input;
1116 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
1118 if (unformat (in, "ipv4"))
1120 else if (unformat (in, "ipv6"))
1126 if (ipv4_set && ipv6_set)
1128 errmsg ("ipv4 and ipv6 flags cannot be both set");
1132 if ((!ipv4_set) && (!ipv6_set))
1134 errmsg ("no ipv4 nor ipv6 flag set");
1139 vam->is_ipv6 = is_ipv6;
1142 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
1144 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
1146 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
1149 mp->is_ipv6 = ipv6_set;
1152 /* Use a control ping for synchronization */
1153 PING (&ip_test_main, mp_ping);
1161 vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
1166 vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
1168 vat_main_t *vam = ip_test_main.vat_main;
1169 vam->result_ready = 1;
1173 api_ip_mroute_dump (vat_main_t *vam)
1175 unformat_input_t *input = vam->input;
1176 vl_api_control_ping_t *mp_ping;
1177 vl_api_ip_mroute_dump_t *mp;
1182 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1184 if (unformat (input, "table_id %d", &table_id))
1186 else if (unformat (input, "ip6"))
1188 else if (unformat (input, "ip4"))
1195 errmsg ("missing table id");
1199 M (IP_MROUTE_DUMP, mp);
1200 mp->table.table_id = table_id;
1201 mp->table.is_ip6 = is_ip6;
1204 /* Use a control ping for synchronization */
1205 PING (&ip_test_main, mp_ping);
1213 api_sw_interface_ip6_enable_disable (vat_main_t *vam)
1215 unformat_input_t *i = vam->input;
1216 vl_api_sw_interface_ip6_enable_disable_t *mp;
1218 u8 sw_if_index_set = 0;
1222 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1224 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1225 sw_if_index_set = 1;
1226 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1227 sw_if_index_set = 1;
1228 else if (unformat (i, "enable"))
1230 else if (unformat (i, "disable"))
1234 clib_warning ("parse error '%U'", format_unformat_error, i);
1239 if (sw_if_index_set == 0)
1241 errmsg ("missing interface name or sw_if_index");
1245 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
1247 mp->sw_if_index = ntohl (sw_if_index);
1248 mp->enable = enable;
1256 api_set_ip_flow_hash_v2 (vat_main_t *vat)
1262 api_ip_mroute_add_del (vat_main_t *vam)
1264 unformat_input_t *i = vam->input;
1265 u8 path_set = 0, prefix_set = 0, is_add = 1;
1266 vl_api_ip_mroute_add_del_t *mp;
1267 mfib_entry_flags_t eflags = 0;
1268 vl_api_mfib_path_t path;
1269 vl_api_mprefix_t pfx = {};
1273 /* Parse args required to build the message */
1274 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1276 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
1279 pfx.grp_address_length = htons (pfx.grp_address_length);
1281 else if (unformat (i, "del"))
1283 else if (unformat (i, "add"))
1285 else if (unformat (i, "vrf %d", &vrf_id))
1287 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
1288 path.itf_flags = htonl (path.itf_flags);
1289 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
1291 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
1295 clib_warning ("parse error '%U'", format_unformat_error, i);
1300 if (prefix_set == 0)
1302 errmsg ("missing addresses\n");
1307 errmsg ("missing path\n");
1311 /* Construct the API message */
1312 M (IP_MROUTE_ADD_DEL, mp);
1314 mp->is_add = is_add;
1315 mp->is_multipath = 1;
1317 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
1318 mp->route.table_id = htonl (vrf_id);
1319 mp->route.n_paths = 1;
1320 mp->route.entry_flags = htonl (eflags);
1322 clib_memcpy (&mp->route.paths, &path, sizeof (path));
1326 /* Wait for a reply... */
1332 vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
1334 vat_main_t *vam = ip_test_main.vat_main;
1335 vam->result_ready = 1;
1339 api_ip_mtable_dump (vat_main_t *vam)
1341 vl_api_ip_mtable_dump_t *mp;
1342 vl_api_control_ping_t *mp_ping;
1345 M (IP_MTABLE_DUMP, mp);
1348 /* Use a control ping for synchronization */
1349 PING (&ip_test_main, mp_ping);
1357 vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
1359 vat_main_t *vam = ip_test_main.vat_main;
1360 vam->result_ready = 1;
1364 api_ip_table_replace_end (vat_main_t *vam)
1366 unformat_input_t *i = vam->input;
1367 vl_api_ip_table_replace_end_t *mp;
1372 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1374 if (unformat (i, "table %d", &table_id))
1376 else if (unformat (i, "ipv6"))
1380 clib_warning ("parse error '%U'", format_unformat_error, i);
1385 M (IP_TABLE_REPLACE_END, mp);
1387 mp->table.table_id = ntohl (table_id);
1388 mp->table.is_ip6 = is_ipv6;
1396 api_ip_table_dump (vat_main_t *vam)
1398 vl_api_ip_table_dump_t *mp;
1399 vl_api_control_ping_t *mp_ping;
1402 M (IP_TABLE_DUMP, mp);
1405 /* Use a control ping for synchronization */
1406 PING (&ip_test_main, mp_ping);
1414 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
1416 vat_main_t *vam = ip_test_main.vat_main;
1418 fformat (vam->ofp, "%s; table-id %d, prefix %U/%d", mp->table.name,
1419 ntohl (mp->table.table_id));
1420 vam->result_ready = 1;
1424 api_ip_path_mtu_get (vat_main_t *vat)
1430 api_ip_route_v2_dump (vat_main_t *vat)
1436 vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
1441 api_ip_route_dump (vat_main_t *vam)
1443 unformat_input_t *input = vam->input;
1444 vl_api_ip_route_dump_t *mp;
1445 vl_api_control_ping_t *mp_ping;
1451 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1453 if (unformat (input, "table_id %d", &table_id))
1455 else if (unformat (input, "ip6"))
1457 else if (unformat (input, "ip4"))
1464 errmsg ("missing table id");
1468 M (IP_ROUTE_DUMP, mp);
1470 mp->table.table_id = table_id;
1471 mp->table.is_ip6 = is_ip6;
1475 /* Use a control ping for synchronization */
1476 PING (&ip_test_main, mp_ping);
1484 vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
1486 vat_main_t *vam = ip_test_main.vat_main;
1487 static ip_address_details_t empty_ip_address_details = { { 0 } };
1488 ip_address_details_t *address = NULL;
1489 ip_details_t *current_ip_details = NULL;
1490 ip_details_t *details = NULL;
1492 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1494 if (!details || vam->current_sw_if_index >= vec_len (details) ||
1495 !details[vam->current_sw_if_index].present)
1497 errmsg ("ip address details arrived but not stored");
1498 errmsg ("ip_dump should be called first");
1502 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1504 #define addresses (current_ip_details->addr)
1506 vec_validate_init_empty (addresses, vec_len (addresses),
1507 empty_ip_address_details);
1509 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1511 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1512 address->prefix_length = mp->prefix.len;
1517 api_ip_unnumbered_dump (vat_main_t *vam)
1523 vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
1528 vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
1530 vat_main_t *vam = &vat_main;
1531 static ip_details_t empty_ip_details = { 0 };
1532 ip_details_t *ip = NULL;
1533 u32 sw_if_index = ~0;
1535 sw_if_index = ntohl (mp->sw_if_index);
1537 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1538 sw_if_index, empty_ip_details);
1540 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1546 #include <vnet/ip/ip.api_test.c>
1549 * fd.io coding-style-patch-verification: ON
1552 * eval: (c-set-style "gnu")