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