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 api_ip_local_reass_enable_disable (vat_main_t *vat)
1024 api_ip_local_reass_get (vat_main_t *vat)
1030 vl_api_ip_local_reass_get_reply_t_handler (
1031 vl_api_ip_local_reass_get_reply_t *mp)
1036 vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp)
1041 api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam)
1043 unformat_input_t *input = vam->input;
1044 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
1045 u32 sw_if_index = ~0;
1047 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
1048 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
1052 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1054 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1056 else if (unformat (input, "sw_if_index %d", &sw_if_index))
1058 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
1060 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
1062 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
1064 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
1066 else if (unformat (input, "del"))
1072 if (sw_if_index == ~0)
1074 errmsg ("Interface required but not specified");
1080 errmsg ("VRF ID required but not specified");
1084 if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
1087 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
1092 /* Construct the API message */
1093 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
1095 mp->sw_if_index = ntohl (sw_if_index);
1096 mp->is_add = is_add;
1097 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
1098 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
1099 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
1100 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
1105 /* Wait for a reply... */
1111 vl_api_ip_container_proxy_details_t_handler (
1112 vl_api_ip_container_proxy_details_t *mp)
1117 api_ip_container_proxy_dump (vat_main_t *vam)
1123 api_ip_dump (vat_main_t *vam)
1125 vl_api_ip_dump_t *mp;
1126 vl_api_control_ping_t *mp_ping;
1127 unformat_input_t *in = vam->input;
1134 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
1136 if (unformat (in, "ipv4"))
1138 else if (unformat (in, "ipv6"))
1144 if (ipv4_set && ipv6_set)
1146 errmsg ("ipv4 and ipv6 flags cannot be both set");
1150 if ((!ipv4_set) && (!ipv6_set))
1152 errmsg ("no ipv4 nor ipv6 flag set");
1157 vam->is_ipv6 = is_ipv6;
1160 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
1162 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
1164 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
1167 mp->is_ipv6 = ipv6_set;
1170 /* Use a control ping for synchronization */
1171 PING (&ip_test_main, mp_ping);
1179 vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
1184 vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
1186 vat_main_t *vam = ip_test_main.vat_main;
1187 vam->result_ready = 1;
1191 api_ip_mroute_dump (vat_main_t *vam)
1193 unformat_input_t *input = vam->input;
1194 vl_api_control_ping_t *mp_ping;
1195 vl_api_ip_mroute_dump_t *mp;
1200 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1202 if (unformat (input, "table_id %d", &table_id))
1204 else if (unformat (input, "ip6"))
1206 else if (unformat (input, "ip4"))
1213 errmsg ("missing table id");
1217 M (IP_MROUTE_DUMP, mp);
1218 mp->table.table_id = table_id;
1219 mp->table.is_ip6 = is_ip6;
1222 /* Use a control ping for synchronization */
1223 PING (&ip_test_main, mp_ping);
1231 api_sw_interface_ip6_enable_disable (vat_main_t *vam)
1233 unformat_input_t *i = vam->input;
1234 vl_api_sw_interface_ip6_enable_disable_t *mp;
1236 u8 sw_if_index_set = 0;
1240 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1242 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1243 sw_if_index_set = 1;
1244 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1245 sw_if_index_set = 1;
1246 else if (unformat (i, "enable"))
1248 else if (unformat (i, "disable"))
1252 clib_warning ("parse error '%U'", format_unformat_error, i);
1257 if (sw_if_index_set == 0)
1259 errmsg ("missing interface name or sw_if_index");
1263 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
1265 mp->sw_if_index = ntohl (sw_if_index);
1266 mp->enable = enable;
1274 api_set_ip_flow_hash_v2 (vat_main_t *vat)
1280 api_ip_mroute_add_del (vat_main_t *vam)
1282 unformat_input_t *i = vam->input;
1283 u8 path_set = 0, prefix_set = 0, is_add = 1;
1284 vl_api_ip_mroute_add_del_t *mp;
1285 mfib_entry_flags_t eflags = 0;
1286 vl_api_mfib_path_t path;
1287 vl_api_mprefix_t pfx = {};
1291 /* Parse args required to build the message */
1292 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1294 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
1297 pfx.grp_address_length = htons (pfx.grp_address_length);
1299 else if (unformat (i, "del"))
1301 else if (unformat (i, "add"))
1303 else if (unformat (i, "vrf %d", &vrf_id))
1305 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
1306 path.itf_flags = htonl (path.itf_flags);
1307 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
1309 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
1313 clib_warning ("parse error '%U'", format_unformat_error, i);
1318 if (prefix_set == 0)
1320 errmsg ("missing addresses\n");
1325 errmsg ("missing path\n");
1329 /* Construct the API message */
1330 M (IP_MROUTE_ADD_DEL, mp);
1332 mp->is_add = is_add;
1333 mp->is_multipath = 1;
1335 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
1336 mp->route.table_id = htonl (vrf_id);
1337 mp->route.n_paths = 1;
1338 mp->route.entry_flags = htonl (eflags);
1340 clib_memcpy (&mp->route.paths, &path, sizeof (path));
1344 /* Wait for a reply... */
1350 vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
1352 vat_main_t *vam = ip_test_main.vat_main;
1353 vam->result_ready = 1;
1357 api_ip_mtable_dump (vat_main_t *vam)
1359 vl_api_ip_mtable_dump_t *mp;
1360 vl_api_control_ping_t *mp_ping;
1363 M (IP_MTABLE_DUMP, mp);
1366 /* Use a control ping for synchronization */
1367 PING (&ip_test_main, mp_ping);
1375 vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
1377 vat_main_t *vam = ip_test_main.vat_main;
1378 vam->result_ready = 1;
1382 api_ip_table_replace_end (vat_main_t *vam)
1384 unformat_input_t *i = vam->input;
1385 vl_api_ip_table_replace_end_t *mp;
1390 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1392 if (unformat (i, "table %d", &table_id))
1394 else if (unformat (i, "ipv6"))
1398 clib_warning ("parse error '%U'", format_unformat_error, i);
1403 M (IP_TABLE_REPLACE_END, mp);
1405 mp->table.table_id = ntohl (table_id);
1406 mp->table.is_ip6 = is_ipv6;
1414 api_ip_table_dump (vat_main_t *vam)
1416 vl_api_ip_table_dump_t *mp;
1417 vl_api_control_ping_t *mp_ping;
1420 M (IP_TABLE_DUMP, mp);
1423 /* Use a control ping for synchronization */
1424 PING (&ip_test_main, mp_ping);
1432 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
1434 vat_main_t *vam = ip_test_main.vat_main;
1436 fformat (vam->ofp, "%s; table-id %d, prefix %U/%d", mp->table.name,
1437 ntohl (mp->table.table_id));
1438 vam->result_ready = 1;
1442 api_ip_path_mtu_get (vat_main_t *vat)
1448 api_ip_route_v2_dump (vat_main_t *vat)
1454 vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
1459 api_ip_route_dump (vat_main_t *vam)
1461 unformat_input_t *input = vam->input;
1462 vl_api_ip_route_dump_t *mp;
1463 vl_api_control_ping_t *mp_ping;
1469 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1471 if (unformat (input, "table_id %d", &table_id))
1473 else if (unformat (input, "ip6"))
1475 else if (unformat (input, "ip4"))
1482 errmsg ("missing table id");
1486 M (IP_ROUTE_DUMP, mp);
1488 mp->table.table_id = table_id;
1489 mp->table.is_ip6 = is_ip6;
1493 /* Use a control ping for synchronization */
1494 PING (&ip_test_main, mp_ping);
1502 vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
1504 vat_main_t *vam = ip_test_main.vat_main;
1505 static ip_address_details_t empty_ip_address_details = { { 0 } };
1506 ip_address_details_t *address = NULL;
1507 ip_details_t *current_ip_details = NULL;
1508 ip_details_t *details = NULL;
1510 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1512 if (!details || vam->current_sw_if_index >= vec_len (details) ||
1513 !details[vam->current_sw_if_index].present)
1515 errmsg ("ip address details arrived but not stored");
1516 errmsg ("ip_dump should be called first");
1520 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1522 #define addresses (current_ip_details->addr)
1524 vec_validate_init_empty (addresses, vec_len (addresses),
1525 empty_ip_address_details);
1527 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1529 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1530 address->prefix_length = mp->prefix.len;
1535 api_ip_unnumbered_dump (vat_main_t *vam)
1541 vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
1546 vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
1548 vat_main_t *vam = &vat_main;
1549 static ip_details_t empty_ip_details = { 0 };
1550 ip_details_t *ip = NULL;
1551 u32 sw_if_index = ~0;
1553 sw_if_index = ntohl (mp->sw_if_index);
1555 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1556 sw_if_index, empty_ip_details);
1558 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1564 #include <vnet/ip/ip.api_test.c>
1567 * fd.io coding-style-patch-verification: ON
1570 * eval: (c-set-style "gnu")