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 */
47 static ip_test_main_t ip_test_main;
50 api_ip_route_add_del_v2 (vat_main_t *vam)
56 set_ip4_address (vl_api_address_t *a, u32 v)
58 if (a->af == ADDRESS_IP4)
60 ip4_address_t *i = (ip4_address_t *) &a->un.ip4;
66 increment_v4_address (vl_api_ip4_address_t *i)
68 ip4_address_t *a = (ip4_address_t *) i;
71 v = ntohl (a->as_u32) + 1;
72 a->as_u32 = ntohl (v);
76 increment_v6_address (vl_api_ip6_address_t *i)
78 ip6_address_t *a = (ip6_address_t *) i;
81 v0 = clib_net_to_host_u64 (a->as_u64[0]);
82 v1 = clib_net_to_host_u64 (a->as_u64[1]);
87 a->as_u64[0] = clib_net_to_host_u64 (v0);
88 a->as_u64[1] = clib_net_to_host_u64 (v1);
92 increment_address (vl_api_address_t *a)
94 if (a->af == ADDRESS_IP4)
95 increment_v4_address (&a->un.ip4);
96 else if (a->af == ADDRESS_IP6)
97 increment_v6_address (&a->un.ip6);
101 unformat_fib_path (unformat_input_t *input, va_list *args)
103 vnet_main_t *vnm = va_arg (*args, vnet_main_t *);
104 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
105 u32 weight, preference;
106 mpls_label_t out_label;
108 clib_memset (path, 0, sizeof (*path));
110 path->sw_if_index = ~0;
114 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
116 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
117 &path->nh.address.ip4, unformat_vnet_sw_interface, vnm,
120 path->proto = FIB_API_PATH_NH_PROTO_IP4;
122 else if (unformat (input, "%U %U", unformat_vl_api_ip6_address,
123 &path->nh.address.ip6, unformat_vnet_sw_interface,
124 vnm, &path->sw_if_index))
126 path->proto = FIB_API_PATH_NH_PROTO_IP6;
128 else if (unformat (input, "weight %u", &weight))
130 path->weight = weight;
132 else if (unformat (input, "preference %u", &preference))
134 path->preference = preference;
136 else if (unformat (input, "%U next-hop-table %d",
137 unformat_vl_api_ip4_address, &path->nh.address.ip4,
140 path->proto = FIB_API_PATH_NH_PROTO_IP4;
142 else if (unformat (input, "%U next-hop-table %d",
143 unformat_vl_api_ip6_address, &path->nh.address.ip6,
146 path->proto = FIB_API_PATH_NH_PROTO_IP6;
148 else if (unformat (input, "%U", unformat_vl_api_ip4_address,
149 &path->nh.address.ip4))
152 * the recursive next-hops are by default in the default table
155 path->sw_if_index = ~0;
156 path->proto = FIB_API_PATH_NH_PROTO_IP4;
158 else if (unformat (input, "%U", unformat_vl_api_ip6_address,
159 &path->nh.address.ip6))
162 * the recursive next-hops are by default in the default table
165 path->sw_if_index = ~0;
166 path->proto = FIB_API_PATH_NH_PROTO_IP6;
168 else if (unformat (input, "resolve-via-host"))
170 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
172 else if (unformat (input, "resolve-via-attached"))
174 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
176 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
178 path->type = FIB_API_PATH_TYPE_LOCAL;
179 path->sw_if_index = ~0;
180 path->proto = FIB_API_PATH_NH_PROTO_IP4;
182 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
184 path->type = FIB_API_PATH_TYPE_LOCAL;
185 path->sw_if_index = ~0;
186 path->proto = FIB_API_PATH_NH_PROTO_IP6;
188 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
190 else if (unformat (input, "via-label %d", &path->nh.via_label))
192 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
193 path->sw_if_index = ~0;
195 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
197 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
198 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
200 else if (unformat (input, "local"))
202 path->type = FIB_API_PATH_TYPE_LOCAL;
204 else if (unformat (input, "out-labels"))
206 while (unformat (input, "%d", &out_label))
208 path->label_stack[path->n_labels].label = out_label;
209 path->label_stack[path->n_labels].is_uniform = 0;
210 path->label_stack[path->n_labels].ttl = 64;
214 else if (unformat (input, "via"))
216 /* new path, back up and return */
217 unformat_put_input (input);
218 unformat_put_input (input);
219 unformat_put_input (input);
220 unformat_put_input (input);
229 path->proto = ntohl (path->proto);
230 path->type = ntohl (path->type);
231 path->flags = ntohl (path->flags);
232 path->table_id = ntohl (path->table_id);
233 path->sw_if_index = ntohl (path->sw_if_index);
239 api_ip_route_add_del (vat_main_t *vam)
241 vnet_main_t *vnm = vnet_get_main ();
242 unformat_input_t *i = vam->input;
243 vl_api_ip_route_add_del_t *mp;
249 vl_api_prefix_t pfx = {};
250 vl_api_fib_path_t paths[8];
254 u32 random_add_del = 0;
255 u32 *random_vector = 0;
256 u32 random_seed = 0xdeaddabe;
258 /* Parse args required to build the message */
259 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
261 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
263 else if (unformat (i, "del"))
265 else if (unformat (i, "add"))
267 else if (unformat (i, "vrf %d", &vrf_id))
269 else if (unformat (i, "count %d", &count))
271 else if (unformat (i, "random"))
273 else if (unformat (i, "multipath"))
275 else if (unformat (i, "seed %d", &random_seed))
277 else if (unformat (i, "via %U", unformat_fib_path, vnm,
283 errmsg ("max 8 paths");
289 clib_warning ("parse error '%U'", format_unformat_error, i);
296 errmsg ("specify a path; via ...");
301 errmsg ("missing prefix");
305 /* Generate a pile of unique, random routes */
308 ip4_address_t *i = (ip4_address_t *) &paths[0].nh.address.ip4;
309 u32 this_random_address;
312 random_hash = hash_create (count, sizeof (uword));
314 hash_set (random_hash, i->as_u32, 1);
315 for (j = 0; j <= count; j++)
319 this_random_address = random_u32 (&random_seed);
320 this_random_address = clib_host_to_net_u32 (this_random_address);
322 while (hash_get (random_hash, this_random_address));
323 vec_add1 (random_vector, this_random_address);
324 hash_set (random_hash, this_random_address, 1);
326 hash_free (random_hash);
327 set_ip4_address (&pfx.address, random_vector[0]);
332 /* Turn on async mode */
334 vam->async_errors = 0;
335 before = vat_time_now (vam);
338 for (j = 0; j < count; j++)
340 /* Construct the API message */
341 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
344 mp->is_multipath = is_multipath;
346 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
347 mp->route.table_id = ntohl (vrf_id);
348 mp->route.n_paths = path_count;
350 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
353 set_ip4_address (&pfx.address, random_vector[j + 1]);
355 increment_address (&pfx.address);
358 /* If we receive SIGTERM, stop now... */
363 /* When testing multiple add/del ops, use a control-ping to sync */
366 vl_api_control_ping_t *mp_ping;
370 /* Shut off async mode */
373 PING (&ip_test_main, mp_ping);
376 timeout = vat_time_now (vam) + 1.0;
377 while (vat_time_now (vam) < timeout)
378 if (vam->result_ready == 1)
383 if (vam->retval == -99)
386 if (vam->async_errors > 0)
388 errmsg ("%d asynchronous errors", vam->async_errors);
391 vam->async_errors = 0;
392 after = vat_time_now (vam);
394 /* slim chance, but we might have eaten SIGTERM on the first iteration */
398 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
399 after - before, count / (after - before));
405 /* Wait for a reply... */
410 /* Return the good/bad news */
411 return (vam->retval);
415 api_ip_table_add_del (vat_main_t *vam)
417 unformat_input_t *i = vam->input;
418 vl_api_ip_table_add_del_t *mp;
424 /* Parse args required to build the message */
425 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
427 if (unformat (i, "ipv6"))
429 else if (unformat (i, "del"))
431 else if (unformat (i, "add"))
433 else if (unformat (i, "table %d", &table_id))
437 clib_warning ("parse error '%U'", format_unformat_error, i);
444 errmsg ("missing table-ID");
448 /* Construct the API message */
449 M (IP_TABLE_ADD_DEL, mp);
451 mp->table.table_id = ntohl (table_id);
452 mp->table.is_ip6 = is_ipv6;
458 /* Wait for a reply... */
465 api_ip_table_replace_begin (vat_main_t *vam)
467 unformat_input_t *i = vam->input;
468 vl_api_ip_table_replace_begin_t *mp;
473 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
475 if (unformat (i, "table %d", &table_id))
477 else if (unformat (i, "ipv6"))
481 clib_warning ("parse error '%U'", format_unformat_error, i);
486 M (IP_TABLE_REPLACE_BEGIN, mp);
488 mp->table.table_id = ntohl (table_id);
489 mp->table.is_ip6 = is_ipv6;
497 api_ip_table_flush (vat_main_t *vam)
499 unformat_input_t *i = vam->input;
500 vl_api_ip_table_flush_t *mp;
505 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
507 if (unformat (i, "table %d", &table_id))
509 else if (unformat (i, "ipv6"))
513 clib_warning ("parse error '%U'", format_unformat_error, i);
518 M (IP_TABLE_FLUSH, mp);
520 mp->table.table_id = ntohl (table_id);
521 mp->table.is_ip6 = is_ipv6;
529 api_ip_table_allocate (vat_main_t *vam)
535 vl_api_ip_table_allocate_reply_t_handler (vl_api_ip_table_allocate_reply_t *mp)
540 vl_api_ip_route_add_del_v2_reply_t_handler (
541 vl_api_ip_route_add_del_v2_reply_t *mp)
546 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t *mp)
551 vl_api_ip_route_v2_details_t_handler (vl_api_ip_route_v2_details_t *mp)
556 vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *mp)
558 vat_main_t *vam = ip_test_main.vat_main;
559 vam->result_ready = 1;
563 vl_api_ip_route_lookup_reply_t_handler (vl_api_ip_route_lookup_reply_t *mp)
568 vl_api_ip_route_lookup_v2_reply_t_handler (
569 vl_api_ip_route_lookup_v2_reply_t *mp)
574 api_set_ip_flow_hash_router_id (vat_main_t *vat)
580 api_ip_route_lookup (vat_main_t *vat)
586 api_ip_route_lookup_v2 (vat_main_t *vat)
592 api_set_ip_flow_hash (vat_main_t *vam)
594 unformat_input_t *i = vam->input;
595 vl_api_set_ip_flow_hash_t *mp;
607 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
609 if (unformat (i, "vrf %d", &vrf_id))
611 else if (unformat (i, "ipv6"))
613 else if (unformat (i, "src"))
615 else if (unformat (i, "dst"))
617 else if (unformat (i, "sport"))
619 else if (unformat (i, "dport"))
621 else if (unformat (i, "proto"))
623 else if (unformat (i, "reverse"))
628 clib_warning ("parse error '%U'", format_unformat_error, i);
635 errmsg ("missing vrf id");
639 M (SET_IP_FLOW_HASH, mp);
645 mp->reverse = reverse;
646 mp->vrf_id = ntohl (vrf_id);
647 mp->is_ipv6 = is_ipv6;
655 api_mfib_signal_dump (vat_main_t *vat)
661 api_ip_punt_police (vat_main_t *vat)
667 api_ip_punt_redirect (vat_main_t *vat)
673 api_add_del_ip_punt_redirect_v2 (vat_main_t *vat)
679 api_ip_punt_redirect_dump (vat_main_t *vat)
685 vl_api_ip_punt_redirect_details_t_handler (
686 vl_api_ip_punt_redirect_details_t *mp)
692 api_ip_punt_redirect_v2_dump (vat_main_t *vat)
698 vl_api_ip_punt_redirect_v2_details_t_handler (
699 vl_api_ip_punt_redirect_v2_details_t *mp)
705 api_ip_address_dump (vat_main_t *vam)
707 vnet_main_t *vnm = vnet_get_main ();
708 unformat_input_t *i = vam->input;
709 vl_api_ip_address_dump_t *mp;
710 vl_api_control_ping_t *mp_ping;
711 u32 sw_if_index = ~0;
712 u8 sw_if_index_set = 0;
717 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
719 if (unformat (i, "sw_if_index %d", &sw_if_index))
721 else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
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 vnet_main_t *vnm = vnet_get_main ();
1026 unformat_input_t *input = vam->input;
1027 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
1028 u32 sw_if_index = ~0;
1030 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
1031 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
1035 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1037 if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
1040 else if (unformat (input, "sw_if_index %d", &sw_if_index))
1042 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
1044 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
1046 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
1048 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
1050 else if (unformat (input, "del"))
1056 if (sw_if_index == ~0)
1058 errmsg ("Interface required but not specified");
1064 errmsg ("VRF ID required but not specified");
1068 if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
1071 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
1076 /* Construct the API message */
1077 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
1079 mp->sw_if_index = ntohl (sw_if_index);
1080 mp->is_add = is_add;
1081 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
1082 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
1083 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
1084 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
1089 /* Wait for a reply... */
1095 vl_api_ip_container_proxy_details_t_handler (
1096 vl_api_ip_container_proxy_details_t *mp)
1101 api_ip_container_proxy_dump (vat_main_t *vam)
1107 api_ip_dump (vat_main_t *vam)
1109 vl_api_ip_dump_t *mp;
1110 vl_api_control_ping_t *mp_ping;
1111 unformat_input_t *in = vam->input;
1118 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
1120 if (unformat (in, "ipv4"))
1122 else if (unformat (in, "ipv6"))
1128 if (ipv4_set && ipv6_set)
1130 errmsg ("ipv4 and ipv6 flags cannot be both set");
1134 if ((!ipv4_set) && (!ipv6_set))
1136 errmsg ("no ipv4 nor ipv6 flag set");
1141 vam->is_ipv6 = is_ipv6;
1144 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
1146 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
1148 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
1151 mp->is_ipv6 = ipv6_set;
1154 /* Use a control ping for synchronization */
1155 PING (&ip_test_main, mp_ping);
1163 vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
1168 vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
1170 vat_main_t *vam = ip_test_main.vat_main;
1171 vam->result_ready = 1;
1175 api_ip_mroute_dump (vat_main_t *vam)
1177 unformat_input_t *input = vam->input;
1178 vl_api_control_ping_t *mp_ping;
1179 vl_api_ip_mroute_dump_t *mp;
1184 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1186 if (unformat (input, "table_id %d", &table_id))
1188 else if (unformat (input, "ip6"))
1190 else if (unformat (input, "ip4"))
1197 errmsg ("missing table id");
1201 M (IP_MROUTE_DUMP, mp);
1202 mp->table.table_id = table_id;
1203 mp->table.is_ip6 = is_ip6;
1206 /* Use a control ping for synchronization */
1207 PING (&ip_test_main, mp_ping);
1215 api_sw_interface_ip6_enable_disable (vat_main_t *vam)
1217 vnet_main_t *vnm = vnet_get_main ();
1218 unformat_input_t *i = vam->input;
1219 vl_api_sw_interface_ip6_enable_disable_t *mp;
1221 u8 sw_if_index_set = 0;
1225 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1227 if (unformat (i, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
1228 sw_if_index_set = 1;
1229 else if (unformat (i, "sw_if_index %d", &sw_if_index))
1230 sw_if_index_set = 1;
1231 else if (unformat (i, "enable"))
1233 else if (unformat (i, "disable"))
1237 clib_warning ("parse error '%U'", format_unformat_error, i);
1242 if (sw_if_index_set == 0)
1244 errmsg ("missing interface name or sw_if_index");
1248 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
1250 mp->sw_if_index = ntohl (sw_if_index);
1251 mp->enable = enable;
1259 api_set_ip_flow_hash_v2 (vat_main_t *vat)
1265 api_ip_mroute_add_del (vat_main_t *vam)
1267 unformat_input_t *i = vam->input;
1268 u8 path_set = 0, prefix_set = 0, is_add = 1;
1269 vl_api_ip_mroute_add_del_t *mp;
1270 mfib_entry_flags_t eflags = 0;
1271 vl_api_mfib_path_t path;
1272 vl_api_mprefix_t pfx = {};
1276 /* Parse args required to build the message */
1277 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1279 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
1282 pfx.grp_address_length = htons (pfx.grp_address_length);
1284 else if (unformat (i, "del"))
1286 else if (unformat (i, "add"))
1288 else if (unformat (i, "vrf %d", &vrf_id))
1290 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
1291 path.itf_flags = htonl (path.itf_flags);
1292 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
1294 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
1298 clib_warning ("parse error '%U'", format_unformat_error, i);
1303 if (prefix_set == 0)
1305 errmsg ("missing addresses\n");
1310 errmsg ("missing path\n");
1314 /* Construct the API message */
1315 M (IP_MROUTE_ADD_DEL, mp);
1317 mp->is_add = is_add;
1318 mp->is_multipath = 1;
1320 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
1321 mp->route.table_id = htonl (vrf_id);
1322 mp->route.n_paths = 1;
1323 mp->route.entry_flags = htonl (eflags);
1325 clib_memcpy (&mp->route.paths, &path, sizeof (path));
1329 /* Wait for a reply... */
1335 vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
1337 vat_main_t *vam = ip_test_main.vat_main;
1338 vam->result_ready = 1;
1342 api_ip_mtable_dump (vat_main_t *vam)
1344 vl_api_ip_mtable_dump_t *mp;
1345 vl_api_control_ping_t *mp_ping;
1348 M (IP_MTABLE_DUMP, mp);
1351 /* Use a control ping for synchronization */
1352 PING (&ip_test_main, mp_ping);
1360 vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
1362 vat_main_t *vam = ip_test_main.vat_main;
1363 vam->result_ready = 1;
1367 api_ip_table_replace_end (vat_main_t *vam)
1369 unformat_input_t *i = vam->input;
1370 vl_api_ip_table_replace_end_t *mp;
1375 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1377 if (unformat (i, "table %d", &table_id))
1379 else if (unformat (i, "ipv6"))
1383 clib_warning ("parse error '%U'", format_unformat_error, i);
1388 M (IP_TABLE_REPLACE_END, mp);
1390 mp->table.table_id = ntohl (table_id);
1391 mp->table.is_ip6 = is_ipv6;
1399 api_ip_table_dump (vat_main_t *vam)
1401 vl_api_ip_table_dump_t *mp;
1402 vl_api_control_ping_t *mp_ping;
1405 M (IP_TABLE_DUMP, mp);
1408 /* Use a control ping for synchronization */
1409 PING (&ip_test_main, mp_ping);
1417 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
1419 vat_main_t *vam = ip_test_main.vat_main;
1421 fformat (vam->ofp, "%s; table-id %d, prefix %U/%d", mp->table.name,
1422 ntohl (mp->table.table_id));
1423 vam->result_ready = 1;
1427 api_ip_path_mtu_get (vat_main_t *vat)
1433 api_ip_route_v2_dump (vat_main_t *vat)
1439 vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
1444 api_ip_route_dump (vat_main_t *vam)
1446 unformat_input_t *input = vam->input;
1447 vl_api_ip_route_dump_t *mp;
1448 vl_api_control_ping_t *mp_ping;
1454 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1456 if (unformat (input, "table_id %d", &table_id))
1458 else if (unformat (input, "ip6"))
1460 else if (unformat (input, "ip4"))
1467 errmsg ("missing table id");
1471 M (IP_ROUTE_DUMP, mp);
1473 mp->table.table_id = table_id;
1474 mp->table.is_ip6 = is_ip6;
1478 /* Use a control ping for synchronization */
1479 PING (&ip_test_main, mp_ping);
1487 vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
1489 vat_main_t *vam = ip_test_main.vat_main;
1490 static ip_address_details_t empty_ip_address_details = { { 0 } };
1491 ip_address_details_t *address = NULL;
1492 ip_details_t *current_ip_details = NULL;
1493 ip_details_t *details = NULL;
1495 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1497 if (!details || vam->current_sw_if_index >= vec_len (details) ||
1498 !details[vam->current_sw_if_index].present)
1500 errmsg ("ip address details arrived but not stored");
1501 errmsg ("ip_dump should be called first");
1505 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1507 #define addresses (current_ip_details->addr)
1509 vec_validate_init_empty (addresses, vec_len (addresses),
1510 empty_ip_address_details);
1512 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1514 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1515 address->prefix_length = mp->prefix.len;
1520 api_ip_unnumbered_dump (vat_main_t *vam)
1526 vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
1531 vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
1533 vat_main_t *vam = &vat_main;
1534 static ip_details_t empty_ip_details = { 0 };
1535 ip_details_t *ip = NULL;
1536 u32 sw_if_index = ~0;
1538 sw_if_index = ntohl (mp->sw_if_index);
1540 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1541 sw_if_index, empty_ip_details);
1543 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1549 #include <vnet/ip/ip.api_test.c>
1552 * fd.io coding-style-patch-verification: ON
1555 * eval: (c-set-style "gnu")