blob: 3ba38d3470e0dd8559e59eec963910c536bc60cf [file] [log] [blame]
Filip Tehlarabfe3652021-07-23 18:24:19 +00001/*
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:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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 *------------------------------------------------------------------
16 */
17
18#include <vat/vat.h>
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>
25
26#define __plugin_msg_base ip_test_main.msg_id_base
27#include <vlibapi/vat_helper_macros.h>
28
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>
Florin Corasa1400ce2021-09-15 09:02:08 -070033#include <vlibmemory/vlib.api_types.h>
Filip Tehlarabfe3652021-07-23 18:24:19 +000034
35#define vl_endianfun /* define message structures */
36#include <vnet/ip/ip.api.h>
37#undef vl_endianfun
38
39typedef struct
40{
41 /* API message ID base */
42 u16 msg_id_base;
43 u32 ping_id;
44 vat_main_t *vat_main;
45} ip_test_main_t;
46
47static ip_test_main_t ip_test_main;
48
49static int
50api_ip_route_add_del_v2 (vat_main_t *vam)
51{
52 return -1;
53}
54
55static void
56set_ip4_address (vl_api_address_t *a, u32 v)
57{
58 if (a->af == ADDRESS_IP4)
59 {
60 ip4_address_t *i = (ip4_address_t *) &a->un.ip4;
61 i->as_u32 = v;
62 }
63}
64
65static void
66increment_v4_address (vl_api_ip4_address_t *i)
67{
68 ip4_address_t *a = (ip4_address_t *) i;
69 u32 v;
70
71 v = ntohl (a->as_u32) + 1;
72 a->as_u32 = ntohl (v);
73}
74
75static void
76increment_v6_address (vl_api_ip6_address_t *i)
77{
78 ip6_address_t *a = (ip6_address_t *) i;
79 u64 v0, v1;
80
81 v0 = clib_net_to_host_u64 (a->as_u64[0]);
82 v1 = clib_net_to_host_u64 (a->as_u64[1]);
83
84 v1 += 1;
85 if (v1 == 0)
86 v0 += 1;
87 a->as_u64[0] = clib_net_to_host_u64 (v0);
88 a->as_u64[1] = clib_net_to_host_u64 (v1);
89}
90
91static void
92increment_address (vl_api_address_t *a)
93{
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);
98}
99
100static uword
101unformat_fib_path (unformat_input_t *input, va_list *args)
102{
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;
107
108 clib_memset (path, 0, sizeof (*path));
109 path->weight = 1;
110 path->sw_if_index = ~0;
111 path->rpf_id = ~0;
112 path->n_labels = 0;
113
114 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
115 {
116 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
117 &path->nh.address.ip4, unformat_vnet_sw_interface, vnm,
118 &path->sw_if_index))
119 {
120 path->proto = FIB_API_PATH_NH_PROTO_IP4;
121 }
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))
125 {
126 path->proto = FIB_API_PATH_NH_PROTO_IP6;
127 }
128 else if (unformat (input, "weight %u", &weight))
129 {
130 path->weight = weight;
131 }
132 else if (unformat (input, "preference %u", &preference))
133 {
134 path->preference = preference;
135 }
136 else if (unformat (input, "%U next-hop-table %d",
137 unformat_vl_api_ip4_address, &path->nh.address.ip4,
138 &path->table_id))
139 {
140 path->proto = FIB_API_PATH_NH_PROTO_IP4;
141 }
142 else if (unformat (input, "%U next-hop-table %d",
143 unformat_vl_api_ip6_address, &path->nh.address.ip6,
144 &path->table_id))
145 {
146 path->proto = FIB_API_PATH_NH_PROTO_IP6;
147 }
148 else if (unformat (input, "%U", unformat_vl_api_ip4_address,
149 &path->nh.address.ip4))
150 {
151 /*
152 * the recursive next-hops are by default in the default table
153 */
154 path->table_id = 0;
155 path->sw_if_index = ~0;
156 path->proto = FIB_API_PATH_NH_PROTO_IP4;
157 }
158 else if (unformat (input, "%U", unformat_vl_api_ip6_address,
159 &path->nh.address.ip6))
160 {
161 /*
162 * the recursive next-hops are by default in the default table
163 */
164 path->table_id = 0;
165 path->sw_if_index = ~0;
166 path->proto = FIB_API_PATH_NH_PROTO_IP6;
167 }
168 else if (unformat (input, "resolve-via-host"))
169 {
170 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
171 }
172 else if (unformat (input, "resolve-via-attached"))
173 {
174 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
175 }
176 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
177 {
178 path->type = FIB_API_PATH_TYPE_LOCAL;
179 path->sw_if_index = ~0;
180 path->proto = FIB_API_PATH_NH_PROTO_IP4;
181 }
182 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
183 {
184 path->type = FIB_API_PATH_TYPE_LOCAL;
185 path->sw_if_index = ~0;
186 path->proto = FIB_API_PATH_NH_PROTO_IP6;
187 }
188 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
189 ;
190 else if (unformat (input, "via-label %d", &path->nh.via_label))
191 {
192 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
193 path->sw_if_index = ~0;
194 }
195 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
196 {
197 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
198 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
199 }
200 else if (unformat (input, "local"))
201 {
202 path->type = FIB_API_PATH_TYPE_LOCAL;
203 }
204 else if (unformat (input, "out-labels"))
205 {
206 while (unformat (input, "%d", &out_label))
207 {
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;
211 path->n_labels++;
212 }
213 }
214 else if (unformat (input, "via"))
215 {
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);
221 break;
222 }
223 else
224 {
225 return (0);
226 }
227 }
228
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);
234
235 return (1);
236}
237
238static int
239api_ip_route_add_del (vat_main_t *vam)
240{
241 vnet_main_t *vnm = vnet_get_main ();
242 unformat_input_t *i = vam->input;
243 vl_api_ip_route_add_del_t *mp;
244 u32 vrf_id = 0;
245 u8 is_add = 1;
246 u8 is_multipath = 0;
247 u8 prefix_set = 0;
248 u8 path_count = 0;
249 vl_api_prefix_t pfx = {};
250 vl_api_fib_path_t paths[8];
251 int count = 1;
252 int j;
253 f64 before = 0;
254 u32 random_add_del = 0;
255 u32 *random_vector = 0;
256 u32 random_seed = 0xdeaddabe;
257
258 /* Parse args required to build the message */
259 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
260 {
261 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
262 prefix_set = 1;
263 else if (unformat (i, "del"))
264 is_add = 0;
265 else if (unformat (i, "add"))
266 is_add = 1;
267 else if (unformat (i, "vrf %d", &vrf_id))
268 ;
269 else if (unformat (i, "count %d", &count))
270 ;
271 else if (unformat (i, "random"))
272 random_add_del = 1;
273 else if (unformat (i, "multipath"))
274 is_multipath = 1;
275 else if (unformat (i, "seed %d", &random_seed))
276 ;
277 else if (unformat (i, "via %U", unformat_fib_path, vnm,
278 &paths[path_count]))
279 {
280 path_count++;
281 if (8 == path_count)
282 {
283 errmsg ("max 8 paths");
284 return -99;
285 }
286 }
287 else
288 {
289 clib_warning ("parse error '%U'", format_unformat_error, i);
290 return -99;
291 }
292 }
293
294 if (!path_count)
295 {
296 errmsg ("specify a path; via ...");
297 return -99;
298 }
299 if (prefix_set == 0)
300 {
301 errmsg ("missing prefix");
302 return -99;
303 }
304
305 /* Generate a pile of unique, random routes */
306 if (random_add_del)
307 {
308 ip4_address_t *i = (ip4_address_t *) &paths[0].nh.address.ip4;
309 u32 this_random_address;
310 uword *random_hash;
311
312 random_hash = hash_create (count, sizeof (uword));
313
314 hash_set (random_hash, i->as_u32, 1);
315 for (j = 0; j <= count; j++)
316 {
317 do
318 {
319 this_random_address = random_u32 (&random_seed);
320 this_random_address = clib_host_to_net_u32 (this_random_address);
321 }
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);
325 }
326 hash_free (random_hash);
327 set_ip4_address (&pfx.address, random_vector[0]);
328 }
329
330 if (count > 1)
331 {
332 /* Turn on async mode */
333 vam->async_mode = 1;
334 vam->async_errors = 0;
335 before = vat_time_now (vam);
336 }
337
338 for (j = 0; j < count; j++)
339 {
340 /* Construct the API message */
341 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
342
343 mp->is_add = is_add;
344 mp->is_multipath = is_multipath;
345
346 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
347 mp->route.table_id = ntohl (vrf_id);
348 mp->route.n_paths = path_count;
349
350 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
351
352 if (random_add_del)
353 set_ip4_address (&pfx.address, random_vector[j + 1]);
354 else
355 increment_address (&pfx.address);
356 /* send it... */
357 S (mp);
358 /* If we receive SIGTERM, stop now... */
359 if (vam->do_exit)
360 break;
361 }
362
363 /* When testing multiple add/del ops, use a control-ping to sync */
364 if (count > 1)
365 {
366 vl_api_control_ping_t *mp_ping;
367 f64 after;
368 f64 timeout;
369
370 /* Shut off async mode */
371 vam->async_mode = 0;
372
373 PING (&ip_test_main, mp_ping);
374 S (mp_ping);
375
376 timeout = vat_time_now (vam) + 1.0;
377 while (vat_time_now (vam) < timeout)
378 if (vam->result_ready == 1)
379 goto out;
380 vam->retval = -99;
381
382 out:
383 if (vam->retval == -99)
384 errmsg ("timeout");
385
386 if (vam->async_errors > 0)
387 {
388 errmsg ("%d asynchronous errors", vam->async_errors);
389 vam->retval = -98;
390 }
391 vam->async_errors = 0;
392 after = vat_time_now (vam);
393
394 /* slim chance, but we might have eaten SIGTERM on the first iteration */
395 if (j > 0)
396 count = j;
397
398 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec", count,
399 after - before, count / (after - before));
400 }
401 else
402 {
403 int ret;
404
405 /* Wait for a reply... */
406 W (ret);
407 return ret;
408 }
409
410 /* Return the good/bad news */
411 return (vam->retval);
412}
413
414static int
415api_ip_table_add_del (vat_main_t *vam)
416{
417 unformat_input_t *i = vam->input;
418 vl_api_ip_table_add_del_t *mp;
419 u32 table_id = ~0;
420 u8 is_ipv6 = 0;
421 u8 is_add = 1;
422 int ret = 0;
423
424 /* Parse args required to build the message */
425 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
426 {
427 if (unformat (i, "ipv6"))
428 is_ipv6 = 1;
429 else if (unformat (i, "del"))
430 is_add = 0;
431 else if (unformat (i, "add"))
432 is_add = 1;
433 else if (unformat (i, "table %d", &table_id))
434 ;
435 else
436 {
437 clib_warning ("parse error '%U'", format_unformat_error, i);
438 return -99;
439 }
440 }
441
442 if (~0 == table_id)
443 {
444 errmsg ("missing table-ID");
445 return -99;
446 }
447
448 /* Construct the API message */
449 M (IP_TABLE_ADD_DEL, mp);
450
451 mp->table.table_id = ntohl (table_id);
452 mp->table.is_ip6 = is_ipv6;
453 mp->is_add = is_add;
454
455 /* send it... */
456 S (mp);
457
458 /* Wait for a reply... */
459 W (ret);
460
461 return ret;
462}
463
464static int
465api_ip_table_replace_begin (vat_main_t *vam)
466{
467 unformat_input_t *i = vam->input;
468 vl_api_ip_table_replace_begin_t *mp;
469 u32 table_id = 0;
470 u8 is_ipv6 = 0;
471
472 int ret;
473 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
474 {
475 if (unformat (i, "table %d", &table_id))
476 ;
477 else if (unformat (i, "ipv6"))
478 is_ipv6 = 1;
479 else
480 {
481 clib_warning ("parse error '%U'", format_unformat_error, i);
482 return -99;
483 }
484 }
485
486 M (IP_TABLE_REPLACE_BEGIN, mp);
487
488 mp->table.table_id = ntohl (table_id);
489 mp->table.is_ip6 = is_ipv6;
490
491 S (mp);
492 W (ret);
493 return ret;
494}
495
496static int
497api_ip_table_flush (vat_main_t *vam)
498{
499 unformat_input_t *i = vam->input;
500 vl_api_ip_table_flush_t *mp;
501 u32 table_id = 0;
502 u8 is_ipv6 = 0;
503
504 int ret;
505 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
506 {
507 if (unformat (i, "table %d", &table_id))
508 ;
509 else if (unformat (i, "ipv6"))
510 is_ipv6 = 1;
511 else
512 {
513 clib_warning ("parse error '%U'", format_unformat_error, i);
514 return -99;
515 }
516 }
517
518 M (IP_TABLE_FLUSH, mp);
519
520 mp->table.table_id = ntohl (table_id);
521 mp->table.is_ip6 = is_ipv6;
522
523 S (mp);
524 W (ret);
525 return ret;
526}
527
Aloys Augustin6e4cfb52021-09-16 20:53:14 +0200528static int
529api_ip_table_allocate (vat_main_t *vam)
530{
531 return -1;
532}
533
534static void
535vl_api_ip_table_allocate_reply_t_handler (vl_api_ip_table_allocate_reply_t *mp)
536{
537}
538
Filip Tehlarabfe3652021-07-23 18:24:19 +0000539static void
540vl_api_ip_route_add_del_v2_reply_t_handler (
541 vl_api_ip_route_add_del_v2_reply_t *mp)
542{
543}
544
545static void
546vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t *mp)
547{
548}
549
550static void
551vl_api_ip_route_v2_details_t_handler (vl_api_ip_route_v2_details_t *mp)
552{
553}
554
555static void
556vl_api_ip_route_add_del_reply_t_handler (vl_api_ip_route_add_del_reply_t *mp)
557{
558 vat_main_t *vam = ip_test_main.vat_main;
559 vam->result_ready = 1;
560}
561
562static void
563vl_api_ip_route_lookup_reply_t_handler (vl_api_ip_route_lookup_reply_t *mp)
564{
565}
566
567static void
568vl_api_ip_route_lookup_v2_reply_t_handler (
569 vl_api_ip_route_lookup_v2_reply_t *mp)
570{
571}
572
573static int
574api_set_ip_flow_hash_router_id (vat_main_t *vat)
575{
576 return -1;
577}
578
579static int
580api_ip_route_lookup (vat_main_t *vat)
581{
582 return -1;
583}
584
585static int
586api_ip_route_lookup_v2 (vat_main_t *vat)
587{
588 return -1;
589}
590
591static int
592api_set_ip_flow_hash (vat_main_t *vam)
593{
594 unformat_input_t *i = vam->input;
595 vl_api_set_ip_flow_hash_t *mp;
596 u32 vrf_id = 0;
597 u8 is_ipv6 = 0;
598 u8 vrf_id_set = 0;
599 u8 src = 0;
600 u8 dst = 0;
601 u8 sport = 0;
602 u8 dport = 0;
603 u8 proto = 0;
604 u8 reverse = 0;
605 int ret;
606
607 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
608 {
609 if (unformat (i, "vrf %d", &vrf_id))
610 vrf_id_set = 1;
611 else if (unformat (i, "ipv6"))
612 is_ipv6 = 1;
613 else if (unformat (i, "src"))
614 src = 1;
615 else if (unformat (i, "dst"))
616 dst = 1;
617 else if (unformat (i, "sport"))
618 sport = 1;
619 else if (unformat (i, "dport"))
620 dport = 1;
621 else if (unformat (i, "proto"))
622 proto = 1;
623 else if (unformat (i, "reverse"))
624 reverse = 1;
625
626 else
627 {
628 clib_warning ("parse error '%U'", format_unformat_error, i);
629 return -99;
630 }
631 }
632
633 if (vrf_id_set == 0)
634 {
635 errmsg ("missing vrf id");
636 return -99;
637 }
638
639 M (SET_IP_FLOW_HASH, mp);
640 mp->src = src;
641 mp->dst = dst;
642 mp->sport = sport;
643 mp->dport = dport;
644 mp->proto = proto;
645 mp->reverse = reverse;
646 mp->vrf_id = ntohl (vrf_id);
647 mp->is_ipv6 = is_ipv6;
648
649 S (mp);
650 W (ret);
651 return ret;
652}
653
654static int
655api_mfib_signal_dump (vat_main_t *vat)
656{
657 return -1;
658}
659
660static int
661api_ip_punt_police (vat_main_t *vat)
662{
663 return -1;
664}
665
666static int
667api_ip_punt_redirect (vat_main_t *vat)
668{
669 return -1;
670}
671
672static int
Nathan Skrzypczak2a1783f2021-08-10 15:05:29 +0200673api_add_del_ip_punt_redirect_v2 (vat_main_t *vat)
674{
675 return -1;
676}
677
678static int
Filip Tehlarabfe3652021-07-23 18:24:19 +0000679api_ip_punt_redirect_dump (vat_main_t *vat)
680{
681 return -1;
682}
683
684static void
685vl_api_ip_punt_redirect_details_t_handler (
686 vl_api_ip_punt_redirect_details_t *mp)
687{
Nathan Skrzypczak2a1783f2021-08-10 15:05:29 +0200688 /**/
689}
690
691static int
692api_ip_punt_redirect_v2_dump (vat_main_t *vat)
693{
694 return -1;
695}
696
697static void
698vl_api_ip_punt_redirect_v2_details_t_handler (
699 vl_api_ip_punt_redirect_v2_details_t *mp)
700{
701 /**/
Filip Tehlarabfe3652021-07-23 18:24:19 +0000702}
703
704static int
705api_ip_address_dump (vat_main_t *vam)
706{
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;
713 u8 ipv4_set = 0;
714 u8 ipv6_set = 0;
715 int ret;
716
717 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
718 {
719 if (unformat (i, "sw_if_index %d", &sw_if_index))
720 sw_if_index_set = 1;
721 else if (unformat (i, "%U", unformat_vnet_sw_interface, vnm,
722 &sw_if_index))
723 sw_if_index_set = 1;
724 else if (unformat (i, "ipv4"))
725 ipv4_set = 1;
726 else if (unformat (i, "ipv6"))
727 ipv6_set = 1;
728 else
729 break;
730 }
731
732 if (ipv4_set && ipv6_set)
733 {
734 errmsg ("ipv4 and ipv6 flags cannot be both set");
735 return -99;
736 }
737
738 if ((!ipv4_set) && (!ipv6_set))
739 {
740 errmsg ("no ipv4 nor ipv6 flag set");
741 return -99;
742 }
743
744 if (sw_if_index_set == 0)
745 {
746 errmsg ("missing interface name or sw_if_index");
747 return -99;
748 }
749
750 vam->current_sw_if_index = sw_if_index;
751 vam->is_ipv6 = ipv6_set;
752
753 M (IP_ADDRESS_DUMP, mp);
754 mp->sw_if_index = ntohl (sw_if_index);
755 mp->is_ipv6 = ipv6_set;
756 S (mp);
757
758 /* Use a control ping for synchronization */
759 PING (&ip_test_main, mp_ping);
760 S (mp_ping);
761
762 W (ret);
763 return ret;
764}
765
766static void
767vl_api_sw_interface_ip6_get_link_local_address_reply_t_handler (
768 vl_api_sw_interface_ip6_get_link_local_address_reply_t *mp)
769{
770}
771
772static int
773api_sw_interface_ip6_set_link_local_address (vat_main_t *vam)
774{
775 return -1;
776}
777
778static int
779api_sw_interface_ip6_get_link_local_address (vat_main_t *vam)
780{
781 return -1;
782}
783
784static int
785api_ip_path_mtu_replace_end (vat_main_t *vam)
786{
787 return -1;
788}
789
790static int
791api_ioam_enable (vat_main_t *vam)
792{
793 unformat_input_t *input = vam->input;
794 vl_api_ioam_enable_t *mp;
795 u32 id = 0;
796 int has_trace_option = 0;
797 int has_pot_option = 0;
798 int has_seqno_option = 0;
799 int has_analyse_option = 0;
800 int ret;
801
802 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
803 {
804 if (unformat (input, "trace"))
805 has_trace_option = 1;
806 else if (unformat (input, "pot"))
807 has_pot_option = 1;
808 else if (unformat (input, "seqno"))
809 has_seqno_option = 1;
810 else if (unformat (input, "analyse"))
811 has_analyse_option = 1;
812 else
813 break;
814 }
815 M (IOAM_ENABLE, mp);
816 mp->id = htons (id);
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;
821
822 S (mp);
823 W (ret);
824 return ret;
825}
826
827static int
828api_ip_reassembly_get (vat_main_t *vam)
829{
830 return -1;
831}
832
833static int
834api_ip_path_mtu_replace_begin (vat_main_t *vam)
835{
836 return -1;
837}
838
839static int
840api_ip_path_mtu_update (vat_main_t *vam)
841{
842 return -1;
843}
844
845static int
846api_ioam_disable (vat_main_t *vam)
847{
848 vl_api_ioam_disable_t *mp;
849 int ret;
850
851 M (IOAM_DISABLE, mp);
852 S (mp);
853 W (ret);
854 return ret;
855}
856
857static int
858api_ip_source_and_port_range_check_add_del (vat_main_t *vam)
859{
860 unformat_input_t *input = vam->input;
861 vl_api_ip_source_and_port_range_check_add_del_t *mp;
862
863 u16 *low_ports = 0;
864 u16 *high_ports = 0;
865 u16 this_low;
866 u16 this_hi;
867 vl_api_prefix_t prefix;
868 u32 tmp, tmp2;
869 u8 prefix_set = 0;
870 u32 vrf_id = ~0;
871 u8 is_add = 1;
872 int ret;
873
874 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
875 {
876 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
877 prefix_set = 1;
878 else if (unformat (input, "vrf %d", &vrf_id))
879 ;
880 else if (unformat (input, "del"))
881 is_add = 0;
882 else if (unformat (input, "port %d", &tmp))
883 {
884 if (tmp == 0 || tmp > 65535)
885 {
886 errmsg ("port %d out of range", tmp);
887 return -99;
888 }
889 this_low = tmp;
890 this_hi = this_low + 1;
891 vec_add1 (low_ports, this_low);
892 vec_add1 (high_ports, this_hi);
893 }
894 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
895 {
896 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
897 {
898 errmsg ("incorrect range parameters");
899 return -99;
900 }
901 this_low = tmp;
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.
910 */
911 this_hi = tmp2;
912 vec_add1 (low_ports, this_low);
913 vec_add1 (high_ports, this_hi);
914 }
915 else
916 break;
917 }
918
919 if (prefix_set == 0)
920 {
921 errmsg ("<address>/<mask> not specified");
922 return -99;
923 }
924
925 if (vrf_id == ~0)
926 {
927 errmsg ("VRF ID required, not specified");
928 return -99;
929 }
930
931 if (vrf_id == 0)
932 {
933 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
934 "purpose.");
935 return -99;
936 }
937
938 if (vec_len (low_ports) == 0)
939 {
940 errmsg ("At least one port or port range required");
941 return -99;
942 }
943
944 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
945
946 mp->is_add = is_add;
947
948 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
949
950 mp->number_of_ranges = vec_len (low_ports);
951
952 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
953 vec_free (low_ports);
954
955 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
956 vec_free (high_ports);
957
958 mp->vrf_id = ntohl (vrf_id);
959
960 S (mp);
961 W (ret);
962 return ret;
963}
964
965static int
966api_ip_reassembly_set (vat_main_t *vat)
967{
968 return -1;
969}
970
971static int
972api_ip_container_proxy_add_del (vat_main_t *vam)
973{
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 = {};
978 u8 is_add = 1;
979 int ret;
980
981 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
982 {
983 if (unformat (i, "del"))
984 is_add = 0;
985 else if (unformat (i, "add"))
986 ;
987 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
988 ;
989 else if (unformat (i, "sw_if_index %u", &sw_if_index))
990 ;
991 else
992 break;
993 }
994 if (sw_if_index == ~0 || pfx.len == 0)
995 {
996 errmsg ("address and sw_if_index must be set");
997 return -99;
998 }
999
1000 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
1001
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));
1005
1006 S (mp);
1007 W (ret);
1008 return ret;
1009}
1010
1011static int
1012api_ip_reassembly_enable_disable (vat_main_t *vat)
1013{
1014 return -1;
1015}
1016
1017static void
1018vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp)
1019{
1020}
1021
1022int
1023api_ip_source_and_port_range_check_interface_add_del (vat_main_t *vam)
1024{
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;
1029 int vrf_set = 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;
1032 u8 is_add = 1;
1033 int ret;
1034
1035 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1036 {
1037 if (unformat (input, "%U", unformat_vnet_sw_interface, vnm,
1038 &sw_if_index))
1039 ;
1040 else if (unformat (input, "sw_if_index %d", &sw_if_index))
1041 ;
1042 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
1043 vrf_set = 1;
1044 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
1045 vrf_set = 1;
1046 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
1047 vrf_set = 1;
1048 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
1049 vrf_set = 1;
1050 else if (unformat (input, "del"))
1051 is_add = 0;
1052 else
1053 break;
1054 }
1055
1056 if (sw_if_index == ~0)
1057 {
1058 errmsg ("Interface required but not specified");
1059 return -99;
1060 }
1061
1062 if (vrf_set == 0)
1063 {
1064 errmsg ("VRF ID required but not specified");
1065 return -99;
1066 }
1067
1068 if (tcp_out_vrf_id == 0 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 ||
1069 udp_in_vrf_id == 0)
1070 {
1071 errmsg ("VRF ID should not be default. Should be distinct VRF for this "
1072 "purpose.");
1073 return -99;
1074 }
1075
1076 /* Construct the API message */
1077 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
1078
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);
1085
1086 /* send it... */
1087 S (mp);
1088
1089 /* Wait for a reply... */
1090 W (ret);
1091 return ret;
1092}
1093
1094static void
1095vl_api_ip_container_proxy_details_t_handler (
1096 vl_api_ip_container_proxy_details_t *mp)
1097{
1098}
1099
1100static int
1101api_ip_container_proxy_dump (vat_main_t *vam)
1102{
1103 return -1;
1104}
1105
1106static int
1107api_ip_dump (vat_main_t *vam)
1108{
1109 vl_api_ip_dump_t *mp;
1110 vl_api_control_ping_t *mp_ping;
1111 unformat_input_t *in = vam->input;
1112 int ipv4_set = 0;
1113 int ipv6_set = 0;
1114 int is_ipv6;
1115 int i;
1116 int ret;
1117
1118 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
1119 {
1120 if (unformat (in, "ipv4"))
1121 ipv4_set = 1;
1122 else if (unformat (in, "ipv6"))
1123 ipv6_set = 1;
1124 else
1125 break;
1126 }
1127
1128 if (ipv4_set && ipv6_set)
1129 {
1130 errmsg ("ipv4 and ipv6 flags cannot be both set");
1131 return -99;
1132 }
1133
1134 if ((!ipv4_set) && (!ipv6_set))
1135 {
1136 errmsg ("no ipv4 nor ipv6 flag set");
1137 return -99;
1138 }
1139
1140 is_ipv6 = ipv6_set;
1141 vam->is_ipv6 = is_ipv6;
1142
1143 /* free old data */
1144 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
1145 {
1146 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
1147 }
1148 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
1149
1150 M (IP_DUMP, mp);
1151 mp->is_ipv6 = ipv6_set;
1152 S (mp);
1153
1154 /* Use a control ping for synchronization */
1155 PING (&ip_test_main, mp_ping);
1156 S (mp_ping);
1157
1158 W (ret);
1159 return ret;
1160}
1161
1162static void
1163vl_api_mfib_signal_details_t_handler (vl_api_mfib_signal_details_t *mp)
1164{
1165}
1166
1167static void
1168vl_api_ip_mroute_details_t_handler (vl_api_ip_mroute_details_t *mp)
1169{
1170 vat_main_t *vam = ip_test_main.vat_main;
1171 vam->result_ready = 1;
1172}
1173
1174static int
1175api_ip_mroute_dump (vat_main_t *vam)
1176{
1177 unformat_input_t *input = vam->input;
1178 vl_api_control_ping_t *mp_ping;
1179 vl_api_ip_mroute_dump_t *mp;
1180 int ret, is_ip6;
1181 u32 table_id;
1182
1183 is_ip6 = 0;
1184 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1185 {
1186 if (unformat (input, "table_id %d", &table_id))
1187 ;
1188 else if (unformat (input, "ip6"))
1189 is_ip6 = 1;
1190 else if (unformat (input, "ip4"))
1191 is_ip6 = 0;
1192 else
1193 break;
1194 }
1195 if (table_id == ~0)
1196 {
1197 errmsg ("missing table id");
1198 return -99;
1199 }
1200
1201 M (IP_MROUTE_DUMP, mp);
1202 mp->table.table_id = table_id;
1203 mp->table.is_ip6 = is_ip6;
1204 S (mp);
1205
1206 /* Use a control ping for synchronization */
1207 PING (&ip_test_main, mp_ping);
1208 S (mp_ping);
1209
1210 W (ret);
1211 return ret;
1212}
1213
1214static int
1215api_sw_interface_ip6_enable_disable (vat_main_t *vam)
1216{
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;
1220 u32 sw_if_index;
1221 u8 sw_if_index_set = 0;
1222 u8 enable = 0;
1223 int ret;
1224
1225 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1226 {
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"))
1232 enable = 1;
1233 else if (unformat (i, "disable"))
1234 enable = 0;
1235 else
1236 {
1237 clib_warning ("parse error '%U'", format_unformat_error, i);
1238 return -99;
1239 }
1240 }
1241
1242 if (sw_if_index_set == 0)
1243 {
1244 errmsg ("missing interface name or sw_if_index");
1245 return -99;
1246 }
1247
1248 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
1249
1250 mp->sw_if_index = ntohl (sw_if_index);
1251 mp->enable = enable;
1252
1253 S (mp);
1254 W (ret);
1255 return ret;
1256}
1257
1258static int
1259api_set_ip_flow_hash_v2 (vat_main_t *vat)
1260{
1261 return -1;
1262}
1263
1264static int
1265api_ip_mroute_add_del (vat_main_t *vam)
1266{
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 = {};
1273 u32 vrf_id = 0;
1274 int ret;
1275
1276 /* Parse args required to build the message */
1277 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1278 {
1279 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
1280 {
1281 prefix_set = 1;
1282 pfx.grp_address_length = htons (pfx.grp_address_length);
1283 }
1284 else if (unformat (i, "del"))
1285 is_add = 0;
1286 else if (unformat (i, "add"))
1287 is_add = 1;
1288 else if (unformat (i, "vrf %d", &vrf_id))
1289 ;
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))
1293 ;
1294 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
1295 path_set = 1;
1296 else
1297 {
1298 clib_warning ("parse error '%U'", format_unformat_error, i);
1299 return -99;
1300 }
1301 }
1302
1303 if (prefix_set == 0)
1304 {
1305 errmsg ("missing addresses\n");
1306 return -99;
1307 }
1308 if (path_set == 0)
1309 {
1310 errmsg ("missing path\n");
1311 return -99;
1312 }
1313
1314 /* Construct the API message */
1315 M (IP_MROUTE_ADD_DEL, mp);
1316
1317 mp->is_add = is_add;
1318 mp->is_multipath = 1;
1319
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);
1324
1325 clib_memcpy (&mp->route.paths, &path, sizeof (path));
1326
1327 /* send it... */
1328 S (mp);
1329 /* Wait for a reply... */
1330 W (ret);
1331 return ret;
1332}
1333
1334static void
1335vl_api_ip_mroute_add_del_reply_t_handler (vl_api_ip_mroute_add_del_reply_t *mp)
1336{
1337 vat_main_t *vam = ip_test_main.vat_main;
1338 vam->result_ready = 1;
1339}
1340
1341static int
1342api_ip_mtable_dump (vat_main_t *vam)
1343{
1344 vl_api_ip_mtable_dump_t *mp;
1345 vl_api_control_ping_t *mp_ping;
1346 int ret;
1347
1348 M (IP_MTABLE_DUMP, mp);
1349 S (mp);
1350
1351 /* Use a control ping for synchronization */
1352 PING (&ip_test_main, mp_ping);
1353 S (mp_ping);
1354
1355 W (ret);
1356 return ret;
1357}
1358
1359static void
1360vl_api_ip_mtable_details_t_handler (vl_api_ip_mtable_details_t *mp)
1361{
1362 vat_main_t *vam = ip_test_main.vat_main;
1363 vam->result_ready = 1;
1364}
1365
1366static int
1367api_ip_table_replace_end (vat_main_t *vam)
1368{
1369 unformat_input_t *i = vam->input;
1370 vl_api_ip_table_replace_end_t *mp;
1371 u32 table_id = 0;
1372 u8 is_ipv6 = 0;
1373
1374 int ret;
1375 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1376 {
1377 if (unformat (i, "table %d", &table_id))
1378 ;
1379 else if (unformat (i, "ipv6"))
1380 is_ipv6 = 1;
1381 else
1382 {
1383 clib_warning ("parse error '%U'", format_unformat_error, i);
1384 return -99;
1385 }
1386 }
1387
1388 M (IP_TABLE_REPLACE_END, mp);
1389
1390 mp->table.table_id = ntohl (table_id);
1391 mp->table.is_ip6 = is_ipv6;
1392
1393 S (mp);
1394 W (ret);
1395 return ret;
1396}
1397
1398static int
1399api_ip_table_dump (vat_main_t *vam)
1400{
1401 vl_api_ip_table_dump_t *mp;
1402 vl_api_control_ping_t *mp_ping;
1403 int ret;
1404
1405 M (IP_TABLE_DUMP, mp);
1406 S (mp);
1407
1408 /* Use a control ping for synchronization */
1409 PING (&ip_test_main, mp_ping);
1410 S (mp_ping);
1411
1412 W (ret);
1413 return ret;
1414}
1415
1416static void
1417vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t *mp)
1418{
1419 vat_main_t *vam = ip_test_main.vat_main;
1420
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;
1424}
1425
1426static int
1427api_ip_path_mtu_get (vat_main_t *vat)
1428{
1429 return -1;
1430}
1431
1432static int
1433api_ip_route_v2_dump (vat_main_t *vat)
1434{
1435 return -1;
1436}
1437
1438static void
1439vl_api_ip_path_mtu_get_reply_t_handler (vl_api_ip_path_mtu_get_reply_t *mp)
1440{
1441}
1442
1443static int
1444api_ip_route_dump (vat_main_t *vam)
1445{
1446 unformat_input_t *input = vam->input;
1447 vl_api_ip_route_dump_t *mp;
1448 vl_api_control_ping_t *mp_ping;
1449 u32 table_id;
1450 u8 is_ip6;
1451 int ret;
1452
1453 is_ip6 = 0;
1454 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1455 {
1456 if (unformat (input, "table_id %d", &table_id))
1457 ;
1458 else if (unformat (input, "ip6"))
1459 is_ip6 = 1;
1460 else if (unformat (input, "ip4"))
1461 is_ip6 = 0;
1462 else
1463 break;
1464 }
1465 if (table_id == ~0)
1466 {
1467 errmsg ("missing table id");
1468 return -99;
1469 }
1470
1471 M (IP_ROUTE_DUMP, mp);
1472
1473 mp->table.table_id = table_id;
1474 mp->table.is_ip6 = is_ip6;
1475
1476 S (mp);
1477
1478 /* Use a control ping for synchronization */
1479 PING (&ip_test_main, mp_ping);
1480 S (mp_ping);
1481
1482 W (ret);
1483 return ret;
1484}
1485
1486static void
1487vl_api_ip_address_details_t_handler (vl_api_ip_address_details_t *mp)
1488{
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;
1494
1495 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1496
1497 if (!details || vam->current_sw_if_index >= vec_len (details) ||
1498 !details[vam->current_sw_if_index].present)
1499 {
1500 errmsg ("ip address details arrived but not stored");
1501 errmsg ("ip_dump should be called first");
1502 return;
1503 }
1504
1505 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1506
1507#define addresses (current_ip_details->addr)
1508
1509 vec_validate_init_empty (addresses, vec_len (addresses),
1510 empty_ip_address_details);
1511
1512 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1513
1514 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1515 address->prefix_length = mp->prefix.len;
1516#undef addresses
1517}
1518
1519static int
1520api_ip_unnumbered_dump (vat_main_t *vam)
1521{
1522 return -1;
1523}
1524
1525static void
1526vl_api_ip_unnumbered_details_t_handler (vl_api_ip_unnumbered_details_t *mp)
1527{
1528}
1529
1530static void
1531vl_api_ip_details_t_handler (vl_api_ip_details_t *mp)
1532{
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;
1537
1538 sw_if_index = ntohl (mp->sw_if_index);
1539
1540 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1541 sw_if_index, empty_ip_details);
1542
1543 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1544 sw_if_index);
1545
1546 ip->present = 1;
1547}
1548
1549#include <vnet/ip/ip.api_test.c>
1550
Filip Tehlarabfe3652021-07-23 18:24:19 +00001551/*
1552 * fd.io coding-style-patch-verification: ON
1553 *
1554 * Local Variables:
1555 * eval: (c-set-style "gnu")
1556 * End:
1557 */