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