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 vl_api_ip_route_add_del_v2_reply_t_handler (
529 vl_api_ip_route_add_del_v2_reply_t *mp)
534 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t *mp)
539 vl_api_ip_route_v2_details_t_handler (vl_api_ip_route_v2_details_t *mp)
544 vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *mp)
546 vat_main_t *vam = ip_test_main.vat_main;
547 vam->result_ready = 1;
551 vl_api_ip_route_lookup_reply_t_handler (vl_api_ip_route_lookup_reply_t *mp)
556 vl_api_ip_route_lookup_v2_reply_t_handler (
557 vl_api_ip_route_lookup_v2_reply_t *mp)
562 api_set_ip_flow_hash_router_id (vat_main_t *vat)
568 api_ip_route_lookup (vat_main_t *vat)
574 api_ip_route_lookup_v2 (vat_main_t *vat)
580 api_set_ip_flow_hash (vat_main_t *vam)
582 unformat_input_t *i = vam->input;
583 vl_api_set_ip_flow_hash_t *mp;
595 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
597 if (unformat (i, "vrf %d", &vrf_id))
599 else if (unformat (i, "ipv6"))
601 else if (unformat (i, "src"))
603 else if (unformat (i, "dst"))
605 else if (unformat (i, "sport"))
607 else if (unformat (i, "dport"))
609 else if (unformat (i, "proto"))
611 else if (unformat (i, "reverse"))
616 clib_warning ("parse error '%U'", format_unformat_error, i);
623 errmsg ("missing vrf id");
627 M (SET_IP_FLOW_HASH, mp);
633 mp->reverse = reverse;
634 mp->vrf_id = ntohl (vrf_id);
635 mp->is_ipv6 = is_ipv6;
643 api_mfib_signal_dump (vat_main_t *vat)
649 api_ip_punt_police (vat_main_t *vat)
655 api_ip_punt_redirect (vat_main_t *vat)
661 api_ip_punt_redirect_dump (vat_main_t *vat)
667 vl_api_ip_punt_redirect_details_t_handler (
668 vl_api_ip_punt_redirect_details_t *mp)
673 api_ip_address_dump (vat_main_t *vam)
675 vnet_main_t *vnm = vnet_get_main ();
676 unformat_input_t *i = vam->input;
677 vl_api_ip_address_dump_t *mp;
678 vl_api_control_ping_t *mp_ping;
679 u32 sw_if_index = ~0;
680 u8 sw_if_index_set = 0;
685 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
687 if (unformat (i, "sw_if_index %d", &sw_if_index))
689 else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
692 else if (unformat (i, "ipv4"))
694 else if (unformat (i, "ipv6"))
700 if (ipv4_set && ipv6_set)
702 errmsg ("ipv4 and ipv6 flags cannot be both set");
706 if ((!ipv4_set) && (!ipv6_set))
708 errmsg ("no ipv4 nor ipv6 flag set");
712 if (sw_if_index_set == 0)
714 errmsg ("missing interface name or sw_if_index");
718 vam->current_sw_if_index = sw_if_index;
719 vam->is_ipv6 = ipv6_set;
721 M (IP_ADDRESS_DUMP, mp);
722 mp->sw_if_index = ntohl (sw_if_index);
723 mp->is_ipv6 = ipv6_set;
726 /* Use a control ping for synchronization */
727 PING (&ip_test_main, mp_ping);
735 vl_api_sw_interface_ip6_get_link_local_address_reply_t_handler (
736 vl_api_sw_interface_ip6_get_link_local_address_reply_t *mp)
741 api_sw_interface_ip6_set_link_local_address (vat_main_t *vam)
747 api_sw_interface_ip6_get_link_local_address (vat_main_t *vam)
753 api_ip_path_mtu_replace_end (vat_main_t *vam)
759 api_ioam_enable (vat_main_t *vam)
761 unformat_input_t *input = vam->input;
762 vl_api_ioam_enable_t *mp;
764 int has_trace_option = 0;
765 int has_pot_option = 0;
766 int has_seqno_option = 0;
767 int has_analyse_option = 0;
770 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
772 if (unformat (input, "trace"))
773 has_trace_option = 1;
774 else if (unformat (input, "pot"))
776 else if (unformat (input, "seqno"))
777 has_seqno_option = 1;
778 else if (unformat (input, "analyse"))
779 has_analyse_option = 1;
785 mp->seqno = has_seqno_option;
786 mp->analyse = has_analyse_option;
787 mp->pot_enable = has_pot_option;
788 mp->trace_enable = has_trace_option;
796 api_ip_reassembly_get (vat_main_t *vam)
802 api_ip_path_mtu_replace_begin (vat_main_t *vam)
808 api_ip_path_mtu_update (vat_main_t *vam)
814 api_ioam_disable (vat_main_t *vam)
816 vl_api_ioam_disable_t *mp;
819 M (IOAM_DISABLE, mp);
826 api_ip_source_and_port_range_check_add_del (vat_main_t *vam)
828 unformat_input_t *input = vam->input;
829 vl_api_ip_source_and_port_range_check_add_del_t *mp;
835 vl_api_prefix_t prefix;
842 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
844 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
846 else if (unformat (input, "vrf %d", &vrf_id))
848 else if (unformat (input, "del"))
850 else if (unformat (input, "port %d", &tmp))
852 if (tmp == 0 || tmp > 65535)
854 errmsg ("port %d out of range", tmp);
858 this_hi = this_low + 1;
859 vec_add1 (low_ports, this_low);
860 vec_add1 (high_ports, this_hi);
862 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
864 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
866 errmsg ("incorrect range parameters");
870 /* Note: in debug CLI +1 is added to high before
871 passing to real fn that does "the work"
872 (ip_source_and_port_range_check_add_del).
873 This fn is a wrapper around the binary API fn a
874 control plane will call, which expects this increment
875 to have occurred. Hence letting the binary API control
876 plane fn do the increment for consistency between VAT
877 and other control planes.
880 vec_add1 (low_ports, this_low);
881 vec_add1 (high_ports, this_hi);
889 errmsg ("<address>/<mask> not specified");
895 errmsg ("VRF ID required, not specified");
901 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
906 if (vec_len (low_ports) == 0)
908 errmsg ("At least one port or port range required");
912 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
916 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
918 mp->number_of_ranges = vec_len (low_ports);
920 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
921 vec_free (low_ports);
923 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
924 vec_free (high_ports);
926 mp->vrf_id = ntohl (vrf_id);
934 api_ip_reassembly_set (vat_main_t *vat)
940 api_ip_container_proxy_add_del (vat_main_t *vam)
942 vl_api_ip_container_proxy_add_del_t *mp;
943 unformat_input_t *i = vam->input;
944 u32 sw_if_index = ~0;
945 vl_api_prefix_t pfx = {};
949 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
951 if (unformat (i, "del"))
953 else if (unformat (i, "add"))
955 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
957 else if (unformat (i, "sw_if_index %u", &sw_if_index))
962 if (sw_if_index == ~0 || pfx.len == 0)
964 errmsg ("address and sw_if_index must be set");
968 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
970 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
972 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
980 api_ip_reassembly_enable_disable (vat_main_t *vat)
986 vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp)
991 api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam)
993 vnet_main_t *vnm = vnet_get_main ();
994 unformat_input_t *input = vam->input;
995 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
996 u32 sw_if_index = ~0;
998 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
999 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
1003 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1005 if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
1008 else if (unformat (input, "sw_if_index %d", &sw_if_index))
1010 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
1012 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
1014 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
1016 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
1018 else if (unformat (input, "del"))
1024 if (sw_if_index == ~0)
1026 errmsg ("Interface required but not specified");
1032 errmsg ("VRF ID required but not specified");
1036 if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
1039 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
1044 /* Construct the API message */
1045 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
1047 mp->sw_if_index = ntohl (sw_if_index);
1048 mp->is_add = is_add;
1049 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
1050 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
1051 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
1052 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
1057 /* Wait for a reply... */
1063 vl_api_ip_container_proxy_details_t_handler (
1064 vl_api_ip_container_proxy_details_t *mp)
1069 api_ip_container_proxy_dump (vat_main_t *vam)
1075 api_ip_dump (vat_main_t *vam)
1077 vl_api_ip_dump_t *mp;
1078 vl_api_control_ping_t *mp_ping;
1079 unformat_input_t *in = vam->input;
1086 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
1088 if (unformat (in, "ipv4"))
1090 else if (unformat (in, "ipv6"))
1096 if (ipv4_set && ipv6_set)
1098 errmsg ("ipv4 and ipv6 flags cannot be both set");
1102 if ((!ipv4_set) && (!ipv6_set))
1104 errmsg ("no ipv4 nor ipv6 flag set");
1109 vam->is_ipv6 = is_ipv6;
1112 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
1114 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
1116 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
1119 mp->is_ipv6 = ipv6_set;
1122 /* Use a control ping for synchronization */
1123 PING (&ip_test_main, mp_ping);
1131 vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
1136 vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
1138 vat_main_t *vam = ip_test_main.vat_main;
1139 vam->result_ready = 1;
1143 api_ip_mroute_dump (vat_main_t *vam)
1145 unformat_input_t *input = vam->input;
1146 vl_api_control_ping_t *mp_ping;
1147 vl_api_ip_mroute_dump_t *mp;
1152 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1154 if (unformat (input, "table_id %d", &table_id))
1156 else if (unformat (input, "ip6"))
1158 else if (unformat (input, "ip4"))
1165 errmsg ("missing table id");
1169 M (IP_MROUTE_DUMP, mp);
1170 mp->table.table_id = table_id;
1171 mp->table.is_ip6 = is_ip6;
1174 /* Use a control ping for synchronization */
1175 PING (&ip_test_main, mp_ping);
1183 api_sw_interface_ip6_enable_disable (vat_main_t *vam)
1185 vnet_main_t *vnm = vnet_get_main ();
1186 unformat_input_t *i = vam->input;
1187 vl_api_sw_interface_ip6_enable_disable_t *mp;
1189 u8 sw_if_index_set = 0;
1193 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1195 if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
1196 sw_if_index_set = 1;
1197 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1198 sw_if_index_set = 1;
1199 else if (unformat (i, "enable"))
1201 else if (unformat (i, "disable"))
1205 clib_warning ("parse error '%U'", format_unformat_error, i);
1210 if (sw_if_index_set == 0)
1212 errmsg ("missing interface name or sw_if_index");
1216 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
1218 mp->sw_if_index = ntohl (sw_if_index);
1219 mp->enable = enable;
1227 api_set_ip_flow_hash_v2 (vat_main_t *vat)
1233 api_ip_mroute_add_del (vat_main_t *vam)
1235 unformat_input_t *i = vam->input;
1236 u8 path_set = 0, prefix_set = 0, is_add = 1;
1237 vl_api_ip_mroute_add_del_t *mp;
1238 mfib_entry_flags_t eflags = 0;
1239 vl_api_mfib_path_t path;
1240 vl_api_mprefix_t pfx = {};
1244 /* Parse args required to build the message */
1245 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1247 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
1250 pfx.grp_address_length = htons (pfx.grp_address_length);
1252 else if (unformat (i, "del"))
1254 else if (unformat (i, "add"))
1256 else if (unformat (i, "vrf %d", &vrf_id))
1258 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
1259 path.itf_flags = htonl (path.itf_flags);
1260 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
1262 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
1266 clib_warning ("parse error '%U'", format_unformat_error, i);
1271 if (prefix_set == 0)
1273 errmsg ("missing addresses\n");
1278 errmsg ("missing path\n");
1282 /* Construct the API message */
1283 M (IP_MROUTE_ADD_DEL, mp);
1285 mp->is_add = is_add;
1286 mp->is_multipath = 1;
1288 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
1289 mp->route.table_id = htonl (vrf_id);
1290 mp->route.n_paths = 1;
1291 mp->route.entry_flags = htonl (eflags);
1293 clib_memcpy (&mp->route.paths, &path, sizeof (path));
1297 /* Wait for a reply... */
1303 vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
1305 vat_main_t *vam = ip_test_main.vat_main;
1306 vam->result_ready = 1;
1310 api_ip_mtable_dump (vat_main_t *vam)
1312 vl_api_ip_mtable_dump_t *mp;
1313 vl_api_control_ping_t *mp_ping;
1316 M (IP_MTABLE_DUMP, mp);
1319 /* Use a control ping for synchronization */
1320 PING (&ip_test_main, mp_ping);
1328 vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
1330 vat_main_t *vam = ip_test_main.vat_main;
1331 vam->result_ready = 1;
1335 api_ip_table_replace_end (vat_main_t *vam)
1337 unformat_input_t *i = vam->input;
1338 vl_api_ip_table_replace_end_t *mp;
1343 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1345 if (unformat (i, "table %d", &table_id))
1347 else if (unformat (i, "ipv6"))
1351 clib_warning ("parse error '%U'", format_unformat_error, i);
1356 M (IP_TABLE_REPLACE_END, mp);
1358 mp->table.table_id = ntohl (table_id);
1359 mp->table.is_ip6 = is_ipv6;
1367 api_ip_table_dump (vat_main_t *vam)
1369 vl_api_ip_table_dump_t *mp;
1370 vl_api_control_ping_t *mp_ping;
1373 M (IP_TABLE_DUMP, mp);
1376 /* Use a control ping for synchronization */
1377 PING (&ip_test_main, mp_ping);
1385 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
1387 vat_main_t *vam = ip_test_main.vat_main;
1389 fformat (vam->ofp, "%s; table-id %d, prefix %U/%d", mp->table.name,
1390 ntohl (mp->table.table_id));
1391 vam->result_ready = 1;
1395 api_ip_path_mtu_get (vat_main_t *vat)
1401 api_ip_route_v2_dump (vat_main_t *vat)
1407 vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
1412 api_ip_route_dump (vat_main_t *vam)
1414 unformat_input_t *input = vam->input;
1415 vl_api_ip_route_dump_t *mp;
1416 vl_api_control_ping_t *mp_ping;
1422 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1424 if (unformat (input, "table_id %d", &table_id))
1426 else if (unformat (input, "ip6"))
1428 else if (unformat (input, "ip4"))
1435 errmsg ("missing table id");
1439 M (IP_ROUTE_DUMP, mp);
1441 mp->table.table_id = table_id;
1442 mp->table.is_ip6 = is_ip6;
1446 /* Use a control ping for synchronization */
1447 PING (&ip_test_main, mp_ping);
1455 vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
1457 vat_main_t *vam = ip_test_main.vat_main;
1458 static ip_address_details_t empty_ip_address_details = { { 0 } };
1459 ip_address_details_t *address = NULL;
1460 ip_details_t *current_ip_details = NULL;
1461 ip_details_t *details = NULL;
1463 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1465 if (!details || vam->current_sw_if_index >= vec_len (details) ||
1466 !details[vam->current_sw_if_index].present)
1468 errmsg ("ip address details arrived but not stored");
1469 errmsg ("ip_dump should be called first");
1473 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1475 #define addresses (current_ip_details->addr)
1477 vec_validate_init_empty (addresses, vec_len (addresses),
1478 empty_ip_address_details);
1480 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1482 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1483 address->prefix_length = mp->prefix.len;
1488 api_ip_unnumbered_dump (vat_main_t *vam)
1494 vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
1499 vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
1501 vat_main_t *vam = &vat_main;
1502 static ip_details_t empty_ip_details = { 0 };
1503 ip_details_t *ip = NULL;
1504 u32 sw_if_index = ~0;
1506 sw_if_index = ntohl (mp->sw_if_index);
1508 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1509 sw_if_index, empty_ip_details);
1511 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1517 #include <vnet/ip/ip.api_test.c>
1519 VAT_REGISTER_FEATURE_FUNCTION (vat_ip_plugin_register);
1522 * fd.io coding-style-patch-verification: ON
1525 * eval: (c-set-style "gnu")