2 *------------------------------------------------------------------
5 * Copyright (c) 2014-2020 Cisco and/or its affiliates.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *------------------------------------------------------------------
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/udp/udp_local.h>
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/in_out_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ip/ip6_hop_by_hop.h>
42 #include <vnet/ip/ip_source_and_port_range_check.h>
43 #include <vnet/policer/xlate.h>
44 #include <vnet/span/span.h>
45 #include <vnet/policer/policer.h>
46 #include <vnet/policer/police.h>
47 #include <vnet/mfib/mfib_types.h>
48 #include <vnet/bonding/node.h>
49 #include <vnet/qos/qos_types.h>
50 #include <vnet/ethernet/ethernet_types_api.h>
51 #include <vnet/ip/ip_types_api.h>
52 #include "vat/json_format.h"
53 #include <vnet/ip/ip_types_api.h>
54 #include <vnet/ethernet/ethernet_types_api.h>
59 #define vl_typedefs /* define message structures */
60 #include <vpp/api/vpe_all_api_h.h>
63 /* declare message handlers for each api */
65 #define vl_endianfun /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
69 /* instantiate all the print functions we know about */
70 #if VPP_API_TEST_BUILTIN == 0
71 #define vl_print(handle, ...)
73 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
76 #include <vpp/api/vpe_all_api_h.h>
79 #define __plugin_msg_base 0
80 #include <vlibapi/vat_helper_macros.h>
82 void vl_api_set_elog_main (elog_main_t * m);
83 int vl_api_set_elog_trace_api_messages (int enable);
85 #if VPP_API_TEST_BUILTIN == 0
95 vat_socket_connect (vat_main_t * vam)
98 api_main_t *am = vlibapi_get_main ();
99 vam->socket_client_main = &socket_client_main;
100 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
102 0 /* default socket rx, tx buffer */ )))
105 /* vpp expects the client index in network order */
106 vam->my_client_index = htonl (socket_client_main.client_index);
107 am->my_client_index = vam->my_client_index;
110 #else /* vpp built-in case, we don't do sockets... */
112 vat_socket_connect (vat_main_t * vam)
118 vl_socket_client_read (int wait)
124 vl_socket_client_write ()
130 vl_socket_client_msg_alloc (int nbytes)
138 vat_time_now (vat_main_t * vam)
140 #if VPP_API_TEST_BUILTIN
141 return vlib_time_now (vam->vlib_main);
143 return clib_time_now (&vam->clib_time);
148 errmsg (char *fmt, ...)
150 vat_main_t *vam = &vat_main;
155 s = va_format (0, fmt, &va);
160 #if VPP_API_TEST_BUILTIN
161 vlib_cli_output (vam->vlib_main, (char *) s);
164 if (vam->ifp != stdin)
165 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
166 vam->input_line_number);
168 fformat (vam->ofp, "%s\n", (char *) s);
176 #if VPP_API_TEST_BUILTIN == 0
178 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
180 vat_main_t *vam = va_arg (*args, vat_main_t *);
181 u32 *result = va_arg (*args, u32 *);
185 if (!unformat (input, "%s", &if_name))
188 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
195 /* Parse an IP4 address %d.%d.%d.%d. */
197 unformat_ip4_address (unformat_input_t * input, va_list * args)
199 u8 *result = va_arg (*args, u8 *);
202 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
205 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217 unformat_ethernet_address (unformat_input_t * input, va_list * args)
219 u8 *result = va_arg (*args, u8 *);
222 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
223 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
227 for (i = 0; i < 6; i++)
228 if (a[i] >= (1 << 8))
231 for (i = 0; i < 6; i++)
237 /* Returns ethernet type as an int in host byte order. */
239 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
242 u16 *result = va_arg (*args, u16 *);
246 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
248 if (type >= (1 << 16))
256 /* Parse an IP46 address. */
258 unformat_ip46_address (unformat_input_t * input, va_list * args)
260 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
261 ip46_type_t type = va_arg (*args, ip46_type_t);
262 if ((type != IP46_TYPE_IP6) &&
263 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
265 ip46_address_mask_ip4 (ip46);
268 else if ((type != IP46_TYPE_IP4) &&
269 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
276 /* Parse an IP6 address. */
278 unformat_ip6_address (unformat_input_t * input, va_list * args)
280 ip6_address_t *result = va_arg (*args, ip6_address_t *);
282 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
283 uword c, n_colon, double_colon_index;
285 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
286 double_colon_index = ARRAY_LEN (hex_quads);
287 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
290 if (c >= '0' && c <= '9')
292 else if (c >= 'a' && c <= 'f')
293 hex_digit = c + 10 - 'a';
294 else if (c >= 'A' && c <= 'F')
295 hex_digit = c + 10 - 'A';
296 else if (c == ':' && n_colon < 2)
300 unformat_put_input (input);
304 /* Too many hex quads. */
305 if (n_hex_quads >= ARRAY_LEN (hex_quads))
310 hex_quad = (hex_quad << 4) | hex_digit;
312 /* Hex quad must fit in 16 bits. */
313 if (n_hex_digits >= 4)
320 /* Save position of :: */
323 /* More than one :: ? */
324 if (double_colon_index < ARRAY_LEN (hex_quads))
326 double_colon_index = n_hex_quads;
329 if (n_colon > 0 && n_hex_digits > 0)
331 hex_quads[n_hex_quads++] = hex_quad;
337 if (n_hex_digits > 0)
338 hex_quads[n_hex_quads++] = hex_quad;
343 /* Expand :: to appropriate number of zero hex quads. */
344 if (double_colon_index < ARRAY_LEN (hex_quads))
346 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
348 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
349 hex_quads[n_zero + i] = hex_quads[i];
351 for (i = 0; i < n_zero; i++)
352 hex_quads[double_colon_index + i] = 0;
354 n_hex_quads = ARRAY_LEN (hex_quads);
357 /* Too few hex quads given. */
358 if (n_hex_quads < ARRAY_LEN (hex_quads))
361 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
362 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
369 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
371 u32 *r = va_arg (*args, u32 *);
374 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
375 foreach_ipsec_policy_action
383 format_ipsec_crypto_alg (u8 * s, va_list * args)
385 u32 i = va_arg (*args, u32);
390 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
391 foreach_ipsec_crypto_alg
394 return format (s, "unknown");
396 return format (s, "%s", t);
400 format_ipsec_integ_alg (u8 * s, va_list * args)
402 u32 i = va_arg (*args, u32);
407 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
408 foreach_ipsec_integ_alg
411 return format (s, "unknown");
413 return format (s, "%s", t);
416 #else /* VPP_API_TEST_BUILTIN == 1 */
418 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
420 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
421 vnet_main_t *vnm = vnet_get_main ();
422 u32 *result = va_arg (*args, u32 *);
424 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
427 #endif /* VPP_API_TEST_BUILTIN */
429 #if (VPP_API_TEST_BUILTIN==0)
431 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
432 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
433 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
434 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
437 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
439 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
440 mfib_itf_attribute_t attr;
443 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
445 if (unformat (input, mfib_itf_flag_long_names[attr]))
446 *iflags |= (1 << attr);
448 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
450 if (unformat (input, mfib_itf_flag_names[attr]))
451 *iflags |= (1 << attr);
454 return (old == *iflags ? 0 : 1);
458 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
460 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
461 mfib_entry_attribute_t attr;
464 FOR_EACH_MFIB_ATTRIBUTE (attr)
466 if (unformat (input, mfib_flag_long_names[attr]))
467 *eflags |= (1 << attr);
469 FOR_EACH_MFIB_ATTRIBUTE (attr)
471 if (unformat (input, mfib_flag_names[attr]))
472 *eflags |= (1 << attr);
475 return (old == *eflags ? 0 : 1);
479 format_ip4_address (u8 * s, va_list * args)
481 u8 *a = va_arg (*args, u8 *);
482 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
486 format_ip6_address (u8 * s, va_list * args)
488 ip6_address_t *a = va_arg (*args, ip6_address_t *);
489 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
491 i_max_n_zero = ARRAY_LEN (a->as_u16);
493 i_first_zero = i_max_n_zero;
495 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
497 u32 is_zero = a->as_u16[i] == 0;
498 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
504 if ((!is_zero && n_zeros > max_n_zeros)
505 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
507 i_max_n_zero = i_first_zero;
508 max_n_zeros = n_zeros;
509 i_first_zero = ARRAY_LEN (a->as_u16);
514 last_double_colon = 0;
515 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
517 if (i == i_max_n_zero && max_n_zeros > 1)
519 s = format (s, "::");
520 i += max_n_zeros - 1;
521 last_double_colon = 1;
525 s = format (s, "%s%x",
526 (last_double_colon || i == 0) ? "" : ":",
527 clib_net_to_host_u16 (a->as_u16[i]));
528 last_double_colon = 0;
535 /* Format an IP46 address. */
537 format_ip46_address (u8 * s, va_list * args)
539 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
540 ip46_type_t type = va_arg (*args, ip46_type_t);
546 is_ip4 = ip46_address_is_ip4 (ip46);
557 format (s, "%U", format_ip4_address, &ip46->ip4) :
558 format (s, "%U", format_ip6_address, &ip46->ip6);
562 format_ethernet_address (u8 * s, va_list * args)
564 u8 *a = va_arg (*args, u8 *);
566 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
567 a[0], a[1], a[2], a[3], a[4], a[5]);
572 increment_v4_address (vl_api_ip4_address_t * i)
574 ip4_address_t *a = (ip4_address_t *) i;
577 v = ntohl (a->as_u32) + 1;
578 a->as_u32 = ntohl (v);
582 increment_v6_address (vl_api_ip6_address_t * i)
584 ip6_address_t *a = (ip6_address_t *) i;
587 v0 = clib_net_to_host_u64 (a->as_u64[0]);
588 v1 = clib_net_to_host_u64 (a->as_u64[1]);
593 a->as_u64[0] = clib_net_to_host_u64 (v0);
594 a->as_u64[1] = clib_net_to_host_u64 (v1);
598 increment_address (vl_api_address_t * a)
600 if (a->af == ADDRESS_IP4)
601 increment_v4_address (&a->un.ip4);
602 else if (a->af == ADDRESS_IP6)
603 increment_v6_address (&a->un.ip6);
607 set_ip4_address (vl_api_address_t * a, u32 v)
609 if (a->af == ADDRESS_IP4)
611 ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
617 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
620 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
622 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
623 sizeof (ip6_address_t));
627 vat_json_object_add_address (vat_json_node_t * node,
628 const char *str, const vl_api_address_t * addr)
630 if (ADDRESS_IP6 == addr->af)
634 clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
635 vat_json_object_add_ip6 (node, str, ip6);
641 clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
642 vat_json_object_add_ip4 (node, str, ip4);
647 vat_json_object_add_prefix (vat_json_node_t * node,
648 const vl_api_prefix_t * prefix)
650 vat_json_object_add_uint (node, "len", prefix->len);
651 vat_json_object_add_address (node, "address", &prefix->address);
654 static void vl_api_create_loopback_reply_t_handler
655 (vl_api_create_loopback_reply_t * mp)
657 vat_main_t *vam = &vat_main;
658 i32 retval = ntohl (mp->retval);
660 vam->retval = retval;
661 vam->regenerate_interface_table = 1;
662 vam->sw_if_index = ntohl (mp->sw_if_index);
663 vam->result_ready = 1;
666 static void vl_api_create_loopback_reply_t_handler_json
667 (vl_api_create_loopback_reply_t * mp)
669 vat_main_t *vam = &vat_main;
670 vat_json_node_t node;
672 vat_json_init_object (&node);
673 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
674 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
676 vat_json_print (vam->ofp, &node);
677 vat_json_free (&node);
678 vam->retval = ntohl (mp->retval);
679 vam->result_ready = 1;
682 static void vl_api_create_loopback_instance_reply_t_handler
683 (vl_api_create_loopback_instance_reply_t * mp)
685 vat_main_t *vam = &vat_main;
686 i32 retval = ntohl (mp->retval);
688 vam->retval = retval;
689 vam->regenerate_interface_table = 1;
690 vam->sw_if_index = ntohl (mp->sw_if_index);
691 vam->result_ready = 1;
694 static void vl_api_create_loopback_instance_reply_t_handler_json
695 (vl_api_create_loopback_instance_reply_t * mp)
697 vat_main_t *vam = &vat_main;
698 vat_json_node_t node;
700 vat_json_init_object (&node);
701 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
702 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
704 vat_json_print (vam->ofp, &node);
705 vat_json_free (&node);
706 vam->retval = ntohl (mp->retval);
707 vam->result_ready = 1;
710 static void vl_api_create_vlan_subif_reply_t_handler
711 (vl_api_create_vlan_subif_reply_t * mp)
713 vat_main_t *vam = &vat_main;
714 i32 retval = ntohl (mp->retval);
716 vam->retval = retval;
717 vam->regenerate_interface_table = 1;
718 vam->sw_if_index = ntohl (mp->sw_if_index);
719 vam->result_ready = 1;
722 static void vl_api_create_vlan_subif_reply_t_handler_json
723 (vl_api_create_vlan_subif_reply_t * mp)
725 vat_main_t *vam = &vat_main;
726 vat_json_node_t node;
728 vat_json_init_object (&node);
729 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
730 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
732 vat_json_print (vam->ofp, &node);
733 vat_json_free (&node);
735 vam->retval = ntohl (mp->retval);
736 vam->result_ready = 1;
739 static void vl_api_create_subif_reply_t_handler
740 (vl_api_create_subif_reply_t * mp)
742 vat_main_t *vam = &vat_main;
743 i32 retval = ntohl (mp->retval);
745 vam->retval = retval;
746 vam->regenerate_interface_table = 1;
747 vam->sw_if_index = ntohl (mp->sw_if_index);
748 vam->result_ready = 1;
751 static void vl_api_create_subif_reply_t_handler_json
752 (vl_api_create_subif_reply_t * mp)
754 vat_main_t *vam = &vat_main;
755 vat_json_node_t node;
757 vat_json_init_object (&node);
758 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
759 vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
761 vat_json_print (vam->ofp, &node);
762 vat_json_free (&node);
764 vam->retval = ntohl (mp->retval);
765 vam->result_ready = 1;
768 static void vl_api_interface_name_renumber_reply_t_handler
769 (vl_api_interface_name_renumber_reply_t * mp)
771 vat_main_t *vam = &vat_main;
772 i32 retval = ntohl (mp->retval);
774 vam->retval = retval;
775 vam->regenerate_interface_table = 1;
776 vam->result_ready = 1;
779 static void vl_api_interface_name_renumber_reply_t_handler_json
780 (vl_api_interface_name_renumber_reply_t * mp)
782 vat_main_t *vam = &vat_main;
783 vat_json_node_t node;
785 vat_json_init_object (&node);
786 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
788 vat_json_print (vam->ofp, &node);
789 vat_json_free (&node);
791 vam->retval = ntohl (mp->retval);
792 vam->result_ready = 1;
796 * Special-case: build the interface table, maintain
797 * the next loopback sw_if_index vbl.
799 static void vl_api_sw_interface_details_t_handler
800 (vl_api_sw_interface_details_t * mp)
802 vat_main_t *vam = &vat_main;
803 u8 *s = format (0, "%s%c", mp->interface_name, 0);
805 hash_set_mem (vam->sw_if_index_by_interface_name, s,
806 ntohl (mp->sw_if_index));
808 /* In sub interface case, fill the sub interface table entry */
809 if (mp->sw_if_index != mp->sup_sw_if_index)
811 sw_interface_subif_t *sub = NULL;
813 vec_add2 (vam->sw_if_subif_table, sub, 1);
815 vec_validate (sub->interface_name, strlen ((char *) s) + 1);
816 strncpy ((char *) sub->interface_name, (char *) s,
817 vec_len (sub->interface_name));
818 sub->sw_if_index = ntohl (mp->sw_if_index);
819 sub->sub_id = ntohl (mp->sub_id);
821 sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
823 sub->sub_number_of_tags = mp->sub_number_of_tags;
824 sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
825 sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
827 /* vlan tag rewrite */
828 sub->vtr_op = ntohl (mp->vtr_op);
829 sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
830 sub->vtr_tag1 = ntohl (mp->vtr_tag1);
831 sub->vtr_tag2 = ntohl (mp->vtr_tag2);
835 static void vl_api_sw_interface_details_t_handler_json
836 (vl_api_sw_interface_details_t * mp)
838 vat_main_t *vam = &vat_main;
839 vat_json_node_t *node = NULL;
841 if (VAT_JSON_ARRAY != vam->json_tree.type)
843 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
844 vat_json_init_array (&vam->json_tree);
846 node = vat_json_array_add (&vam->json_tree);
848 vat_json_init_object (node);
849 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
850 vat_json_object_add_uint (node, "sup_sw_if_index",
851 ntohl (mp->sup_sw_if_index));
852 vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
853 sizeof (mp->l2_address));
854 vat_json_object_add_string_copy (node, "interface_name",
856 vat_json_object_add_string_copy (node, "interface_dev_type",
857 mp->interface_dev_type);
858 vat_json_object_add_uint (node, "flags", mp->flags);
859 vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
860 vat_json_object_add_uint (node, "link_speed", mp->link_speed);
861 vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
862 vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
863 vat_json_object_add_uint (node, "sub_number_of_tags",
864 mp->sub_number_of_tags);
865 vat_json_object_add_uint (node, "sub_outer_vlan_id",
866 ntohs (mp->sub_outer_vlan_id));
867 vat_json_object_add_uint (node, "sub_inner_vlan_id",
868 ntohs (mp->sub_inner_vlan_id));
869 vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
870 vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
871 vat_json_object_add_uint (node, "vtr_push_dot1q",
872 ntohl (mp->vtr_push_dot1q));
873 vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
874 vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
875 if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
877 vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
879 format_ethernet_address,
881 vat_json_object_add_string_copy (node, "pbb_vtr_smac",
883 format_ethernet_address,
885 vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
886 vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
890 #if VPP_API_TEST_BUILTIN == 0
891 static void vl_api_sw_interface_event_t_handler
892 (vl_api_sw_interface_event_t * mp)
894 vat_main_t *vam = &vat_main;
895 if (vam->interface_event_display)
896 errmsg ("interface flags: sw_if_index %d %s %s",
897 ntohl (mp->sw_if_index),
898 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
899 "admin-up" : "admin-down",
900 ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
901 "link-up" : "link-down");
905 __clib_unused static void
906 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
908 /* JSON output not supported */
912 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
914 vat_main_t *vam = &vat_main;
915 i32 retval = ntohl (mp->retval);
917 vam->retval = retval;
918 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
919 vam->result_ready = 1;
923 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
925 vat_main_t *vam = &vat_main;
926 vat_json_node_t node;
930 vat_json_init_object (&node);
931 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
932 vat_json_object_add_uint (&node, "reply_in_shmem",
933 ntohl (mp->reply_in_shmem));
934 /* Toss the shared-memory original... */
935 oldheap = vl_msg_push_heap ();
937 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
940 vl_msg_pop_heap (oldheap);
942 vat_json_print (vam->ofp, &node);
943 vat_json_free (&node);
945 vam->retval = ntohl (mp->retval);
946 vam->result_ready = 1;
950 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
952 vat_main_t *vam = &vat_main;
953 i32 retval = ntohl (mp->retval);
955 vec_reset_length (vam->cmd_reply);
957 vam->retval = retval;
959 vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
960 vam->result_ready = 1;
964 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
966 vat_main_t *vam = &vat_main;
967 vat_json_node_t node;
968 u8 *reply = 0; /* reply vector */
970 reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
971 vec_reset_length (vam->cmd_reply);
973 vat_json_init_object (&node);
974 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
975 vat_json_object_add_string_copy (&node, "reply", reply);
977 vat_json_print (vam->ofp, &node);
978 vat_json_free (&node);
981 vam->retval = ntohl (mp->retval);
982 vam->result_ready = 1;
985 static void vl_api_get_node_index_reply_t_handler
986 (vl_api_get_node_index_reply_t * mp)
988 vat_main_t *vam = &vat_main;
989 i32 retval = ntohl (mp->retval);
992 vam->async_errors += (retval < 0);
996 vam->retval = retval;
998 errmsg ("node index %d", ntohl (mp->node_index));
999 vam->result_ready = 1;
1003 static void vl_api_get_node_index_reply_t_handler_json
1004 (vl_api_get_node_index_reply_t * mp)
1006 vat_main_t *vam = &vat_main;
1007 vat_json_node_t node;
1009 vat_json_init_object (&node);
1010 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1011 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1013 vat_json_print (vam->ofp, &node);
1014 vat_json_free (&node);
1016 vam->retval = ntohl (mp->retval);
1017 vam->result_ready = 1;
1020 static void vl_api_get_next_index_reply_t_handler
1021 (vl_api_get_next_index_reply_t * mp)
1023 vat_main_t *vam = &vat_main;
1024 i32 retval = ntohl (mp->retval);
1025 if (vam->async_mode)
1027 vam->async_errors += (retval < 0);
1031 vam->retval = retval;
1033 errmsg ("next node index %d", ntohl (mp->next_index));
1034 vam->result_ready = 1;
1038 static void vl_api_get_next_index_reply_t_handler_json
1039 (vl_api_get_next_index_reply_t * mp)
1041 vat_main_t *vam = &vat_main;
1042 vat_json_node_t node;
1044 vat_json_init_object (&node);
1045 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1046 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1048 vat_json_print (vam->ofp, &node);
1049 vat_json_free (&node);
1051 vam->retval = ntohl (mp->retval);
1052 vam->result_ready = 1;
1055 static void vl_api_add_node_next_reply_t_handler
1056 (vl_api_add_node_next_reply_t * mp)
1058 vat_main_t *vam = &vat_main;
1059 i32 retval = ntohl (mp->retval);
1060 if (vam->async_mode)
1062 vam->async_errors += (retval < 0);
1066 vam->retval = retval;
1068 errmsg ("next index %d", ntohl (mp->next_index));
1069 vam->result_ready = 1;
1073 static void vl_api_add_node_next_reply_t_handler_json
1074 (vl_api_add_node_next_reply_t * mp)
1076 vat_main_t *vam = &vat_main;
1077 vat_json_node_t node;
1079 vat_json_init_object (&node);
1080 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1081 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1083 vat_json_print (vam->ofp, &node);
1084 vat_json_free (&node);
1086 vam->retval = ntohl (mp->retval);
1087 vam->result_ready = 1;
1090 static void vl_api_show_version_reply_t_handler
1091 (vl_api_show_version_reply_t * mp)
1093 vat_main_t *vam = &vat_main;
1094 i32 retval = ntohl (mp->retval);
1098 errmsg (" program: %s", mp->program);
1099 errmsg (" version: %s", mp->version);
1100 errmsg (" build date: %s", mp->build_date);
1101 errmsg ("build directory: %s", mp->build_directory);
1103 vam->retval = retval;
1104 vam->result_ready = 1;
1107 static void vl_api_show_version_reply_t_handler_json
1108 (vl_api_show_version_reply_t * mp)
1110 vat_main_t *vam = &vat_main;
1111 vat_json_node_t node;
1113 vat_json_init_object (&node);
1114 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1115 vat_json_object_add_string_copy (&node, "program", mp->program);
1116 vat_json_object_add_string_copy (&node, "version", mp->version);
1117 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1118 vat_json_object_add_string_copy (&node, "build_directory",
1119 mp->build_directory);
1121 vat_json_print (vam->ofp, &node);
1122 vat_json_free (&node);
1124 vam->retval = ntohl (mp->retval);
1125 vam->result_ready = 1;
1128 static void vl_api_show_threads_reply_t_handler
1129 (vl_api_show_threads_reply_t * mp)
1131 vat_main_t *vam = &vat_main;
1132 i32 retval = ntohl (mp->retval);
1136 count = ntohl (mp->count);
1138 for (i = 0; i < count; i++)
1140 "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1141 ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1142 mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1143 ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1144 ntohl (mp->thread_data[i].cpu_socket));
1146 vam->retval = retval;
1147 vam->result_ready = 1;
1150 static void vl_api_show_threads_reply_t_handler_json
1151 (vl_api_show_threads_reply_t * mp)
1153 vat_main_t *vam = &vat_main;
1154 vat_json_node_t node;
1155 vl_api_thread_data_t *td;
1156 i32 retval = ntohl (mp->retval);
1160 count = ntohl (mp->count);
1162 vat_json_init_object (&node);
1163 vat_json_object_add_int (&node, "retval", retval);
1164 vat_json_object_add_uint (&node, "count", count);
1166 for (i = 0; i < count; i++)
1168 td = &mp->thread_data[i];
1169 vat_json_object_add_uint (&node, "id", ntohl (td->id));
1170 vat_json_object_add_string_copy (&node, "name", td->name);
1171 vat_json_object_add_string_copy (&node, "type", td->type);
1172 vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1173 vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1174 vat_json_object_add_int (&node, "core", ntohl (td->id));
1175 vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1178 vat_json_print (vam->ofp, &node);
1179 vat_json_free (&node);
1181 vam->retval = retval;
1182 vam->result_ready = 1;
1186 api_show_threads (vat_main_t * vam)
1188 vl_api_show_threads_t *mp;
1192 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1193 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1195 M (SHOW_THREADS, mp);
1202 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1203 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1205 static void vl_api_control_ping_reply_t_handler
1206 (vl_api_control_ping_reply_t * mp)
1208 vat_main_t *vam = &vat_main;
1209 i32 retval = ntohl (mp->retval);
1210 if (vam->async_mode)
1212 vam->async_errors += (retval < 0);
1216 vam->retval = retval;
1217 vam->result_ready = 1;
1219 if (vam->socket_client_main)
1220 vam->socket_client_main->control_pings_outstanding--;
1223 static void vl_api_control_ping_reply_t_handler_json
1224 (vl_api_control_ping_reply_t * mp)
1226 vat_main_t *vam = &vat_main;
1227 i32 retval = ntohl (mp->retval);
1229 if (VAT_JSON_NONE != vam->json_tree.type)
1231 vat_json_print (vam->ofp, &vam->json_tree);
1232 vat_json_free (&vam->json_tree);
1233 vam->json_tree.type = VAT_JSON_NONE;
1238 vat_json_init_array (&vam->json_tree);
1239 vat_json_print (vam->ofp, &vam->json_tree);
1240 vam->json_tree.type = VAT_JSON_NONE;
1243 vam->retval = retval;
1244 vam->result_ready = 1;
1248 static void vl_api_ip_address_details_t_handler
1249 (vl_api_ip_address_details_t * mp)
1251 vat_main_t *vam = &vat_main;
1252 static ip_address_details_t empty_ip_address_details = { {0} };
1253 ip_address_details_t *address = NULL;
1254 ip_details_t *current_ip_details = NULL;
1255 ip_details_t *details = NULL;
1257 details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1259 if (!details || vam->current_sw_if_index >= vec_len (details)
1260 || !details[vam->current_sw_if_index].present)
1262 errmsg ("ip address details arrived but not stored");
1263 errmsg ("ip_dump should be called first");
1267 current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1269 #define addresses (current_ip_details->addr)
1271 vec_validate_init_empty (addresses, vec_len (addresses),
1272 empty_ip_address_details);
1274 address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1276 clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
1277 address->prefix_length = mp->prefix.len;
1281 static void vl_api_ip_address_details_t_handler_json
1282 (vl_api_ip_address_details_t * mp)
1284 vat_main_t *vam = &vat_main;
1285 vat_json_node_t *node = NULL;
1287 if (VAT_JSON_ARRAY != vam->json_tree.type)
1289 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1290 vat_json_init_array (&vam->json_tree);
1292 node = vat_json_array_add (&vam->json_tree);
1294 vat_json_init_object (node);
1295 vat_json_object_add_prefix (node, &mp->prefix);
1299 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1301 vat_main_t *vam = &vat_main;
1302 static ip_details_t empty_ip_details = { 0 };
1303 ip_details_t *ip = NULL;
1304 u32 sw_if_index = ~0;
1306 sw_if_index = ntohl (mp->sw_if_index);
1308 vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1309 sw_if_index, empty_ip_details);
1311 ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1318 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1320 vat_main_t *vam = &vat_main;
1322 if (VAT_JSON_ARRAY != vam->json_tree.type)
1324 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1325 vat_json_init_array (&vam->json_tree);
1327 vat_json_array_add_uint (&vam->json_tree,
1328 clib_net_to_host_u32 (mp->sw_if_index));
1331 static void vl_api_get_first_msg_id_reply_t_handler
1332 (vl_api_get_first_msg_id_reply_t * mp)
1334 vat_main_t *vam = &vat_main;
1335 i32 retval = ntohl (mp->retval);
1337 if (vam->async_mode)
1339 vam->async_errors += (retval < 0);
1343 vam->retval = retval;
1344 vam->result_ready = 1;
1348 errmsg ("first message id %d", ntohs (mp->first_msg_id));
1352 static void vl_api_get_first_msg_id_reply_t_handler_json
1353 (vl_api_get_first_msg_id_reply_t * mp)
1355 vat_main_t *vam = &vat_main;
1356 vat_json_node_t node;
1358 vat_json_init_object (&node);
1359 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1360 vat_json_object_add_uint (&node, "first_msg_id",
1361 (uint) ntohs (mp->first_msg_id));
1363 vat_json_print (vam->ofp, &node);
1364 vat_json_free (&node);
1366 vam->retval = ntohl (mp->retval);
1367 vam->result_ready = 1;
1370 static void vl_api_get_node_graph_reply_t_handler
1371 (vl_api_get_node_graph_reply_t * mp)
1373 vat_main_t *vam = &vat_main;
1374 i32 retval = ntohl (mp->retval);
1375 u8 *pvt_copy, *reply;
1380 if (vam->async_mode)
1382 vam->async_errors += (retval < 0);
1386 vam->retval = retval;
1387 vam->result_ready = 1;
1390 /* "Should never happen..." */
1394 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1395 pvt_copy = vec_dup (reply);
1397 /* Toss the shared-memory original... */
1398 oldheap = vl_msg_push_heap ();
1402 vl_msg_pop_heap (oldheap);
1404 if (vam->graph_nodes)
1406 hash_free (vam->graph_node_index_by_name);
1408 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
1410 node = vam->graph_nodes[0][i];
1411 vec_free (node->name);
1412 vec_free (node->next_nodes);
1415 vec_free (vam->graph_nodes[0]);
1416 vec_free (vam->graph_nodes);
1419 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
1420 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1421 vec_free (pvt_copy);
1423 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
1425 node = vam->graph_nodes[0][i];
1426 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1430 static void vl_api_get_node_graph_reply_t_handler_json
1431 (vl_api_get_node_graph_reply_t * mp)
1433 vat_main_t *vam = &vat_main;
1435 vat_json_node_t node;
1438 /* $$$$ make this real? */
1439 vat_json_init_object (&node);
1440 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1441 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
1443 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1445 /* Toss the shared-memory original... */
1446 oldheap = vl_msg_push_heap ();
1450 vl_msg_pop_heap (oldheap);
1452 vat_json_print (vam->ofp, &node);
1453 vat_json_free (&node);
1455 vam->retval = ntohl (mp->retval);
1456 vam->result_ready = 1;
1459 /* Format hex dump. */
1461 format_hex_bytes (u8 * s, va_list * va)
1463 u8 *bytes = va_arg (*va, u8 *);
1464 int n_bytes = va_arg (*va, int);
1467 /* Print short or long form depending on byte count. */
1468 uword short_form = n_bytes <= 32;
1469 u32 indent = format_get_indent (s);
1474 for (i = 0; i < n_bytes; i++)
1476 if (!short_form && (i % 32) == 0)
1477 s = format (s, "%08x: ", i);
1478 s = format (s, "%02x", bytes[i]);
1479 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
1480 s = format (s, "\n%U", format_white_space, indent);
1487 * Generate boilerplate reply handlers, which
1488 * dig the return value out of the xxx_reply_t API message,
1489 * stick it into vam->retval, and set vam->result_ready
1491 * Could also do this by pointing N message decode slots at
1492 * a single function, but that could break in subtle ways.
1495 #define foreach_standard_reply_retval_handler \
1496 _(sw_interface_set_flags_reply) \
1497 _(sw_interface_add_del_address_reply) \
1498 _(sw_interface_set_rx_placement_reply) \
1499 _(sw_interface_set_table_reply) \
1500 _(ip_route_add_del_reply) \
1501 _(ip_table_add_del_reply) \
1502 _(ip_table_replace_begin_reply) \
1503 _(ip_table_flush_reply) \
1504 _(ip_table_replace_end_reply) \
1505 _(ip_mroute_add_del_reply) \
1506 _(sw_interface_set_unnumbered_reply) \
1507 _(set_ip_flow_hash_reply) \
1508 _(sw_interface_ip6_enable_disable_reply) \
1509 _(delete_loopback_reply) \
1510 _(want_interface_events_reply) \
1511 _(sw_interface_clear_stats_reply) \
1512 _(ioam_enable_reply) \
1513 _(ioam_disable_reply) \
1514 _(ip_source_and_port_range_check_add_del_reply) \
1515 _(ip_source_and_port_range_check_interface_add_del_reply)\
1516 _(delete_subif_reply) \
1517 _(sw_interface_tag_add_del_reply) \
1518 _(sw_interface_add_del_mac_address_reply) \
1519 _(hw_interface_set_mtu_reply) \
1520 _(session_rule_add_del_reply) \
1521 _(ip_container_proxy_add_del_reply) \
1524 static void vl_api_##n##_t_handler \
1525 (vl_api_##n##_t * mp) \
1527 vat_main_t * vam = &vat_main; \
1528 i32 retval = ntohl(mp->retval); \
1529 if (vam->async_mode) { \
1530 vam->async_errors += (retval < 0); \
1532 vam->retval = retval; \
1533 vam->result_ready = 1; \
1536 foreach_standard_reply_retval_handler;
1540 static void vl_api_##n##_t_handler_json \
1541 (vl_api_##n##_t * mp) \
1543 vat_main_t * vam = &vat_main; \
1544 vat_json_node_t node; \
1545 vat_json_init_object(&node); \
1546 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
1547 vat_json_print(vam->ofp, &node); \
1548 vam->retval = ntohl(mp->retval); \
1549 vam->result_ready = 1; \
1551 foreach_standard_reply_retval_handler;
1555 * Table of message reply handlers, must include boilerplate handlers
1559 #define foreach_vpe_api_reply_msg \
1560 _(CREATE_LOOPBACK_REPLY, create_loopback_reply) \
1561 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply) \
1562 _(SW_INTERFACE_DETAILS, sw_interface_details) \
1563 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply) \
1564 _(CONTROL_PING_REPLY, control_ping_reply) \
1565 _(CLI_REPLY, cli_reply) \
1566 _(CLI_INBAND_REPLY, cli_inband_reply) \
1567 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \
1568 sw_interface_add_del_address_reply) \
1569 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply) \
1570 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
1571 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \
1572 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply) \
1573 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply) \
1574 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply) \
1575 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply) \
1576 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply) \
1577 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply) \
1578 _(SW_INTERFACE_SET_UNNUMBERED_REPLY, \
1579 sw_interface_set_unnumbered_reply) \
1580 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply) \
1581 _(CREATE_SUBIF_REPLY, create_subif_reply) \
1582 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply) \
1583 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY, \
1584 sw_interface_ip6_enable_disable_reply) \
1585 _(GET_NODE_INDEX_REPLY, get_node_index_reply) \
1586 _(ADD_NODE_NEXT_REPLY, add_node_next_reply) \
1587 _(SHOW_VERSION_REPLY, show_version_reply) \
1588 _(SHOW_THREADS_REPLY, show_threads_reply) \
1589 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply) \
1590 _(IP_ADDRESS_DETAILS, ip_address_details) \
1591 _(IP_DETAILS, ip_details) \
1592 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply) \
1593 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply) \
1594 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
1595 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
1596 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply) \
1597 _(IOAM_ENABLE_REPLY, ioam_enable_reply) \
1598 _(IOAM_DISABLE_REPLY, ioam_disable_reply) \
1599 _(GET_NEXT_INDEX_REPLY, get_next_index_reply) \
1600 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY, \
1601 ip_source_and_port_range_check_add_del_reply) \
1602 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY, \
1603 ip_source_and_port_range_check_interface_add_del_reply) \
1604 _(DELETE_SUBIF_REPLY, delete_subif_reply) \
1605 _(IP_TABLE_DETAILS, ip_table_details) \
1606 _(IP_ROUTE_DETAILS, ip_route_details) \
1607 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply) \
1608 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
1609 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply) \
1610 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply) \
1611 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
1612 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
1613 _(SESSION_RULES_DETAILS, session_rules_details) \
1614 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply) \
1616 #define foreach_standalone_reply_msg \
1617 _(SW_INTERFACE_EVENT, sw_interface_event)
1625 #define STR_VTR_OP_CASE(op) \
1626 case L2_VTR_ ## op: \
1630 str_vtr_op (u32 vtr_op)
1634 STR_VTR_OP_CASE (DISABLED);
1635 STR_VTR_OP_CASE (PUSH_1);
1636 STR_VTR_OP_CASE (PUSH_2);
1637 STR_VTR_OP_CASE (POP_1);
1638 STR_VTR_OP_CASE (POP_2);
1639 STR_VTR_OP_CASE (TRANSLATE_1_1);
1640 STR_VTR_OP_CASE (TRANSLATE_1_2);
1641 STR_VTR_OP_CASE (TRANSLATE_2_1);
1642 STR_VTR_OP_CASE (TRANSLATE_2_2);
1649 dump_sub_interface_table (vat_main_t * vam)
1651 const sw_interface_subif_t *sub = NULL;
1653 if (vam->json_output)
1656 ("JSON output supported only for VPE API calls and dump_stats_table");
1661 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
1662 "Interface", "sw_if_index",
1663 "sub id", "dot1ad", "tags", "outer id",
1664 "inner id", "exact", "default", "outer any", "inner any");
1666 vec_foreach (sub, vam->sw_if_subif_table)
1669 "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
1670 sub->interface_name,
1672 sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
1673 sub->sub_number_of_tags, sub->sub_outer_vlan_id,
1674 sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
1675 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
1676 if (sub->vtr_op != L2_VTR_DISABLED)
1679 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
1680 "tag1: %d tag2: %d ]",
1681 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
1682 sub->vtr_tag1, sub->vtr_tag2);
1690 name_sort_cmp (void *a1, void *a2)
1692 name_sort_t *n1 = a1;
1693 name_sort_t *n2 = a2;
1695 return strcmp ((char *) n1->name, (char *) n2->name);
1699 dump_interface_table (vat_main_t * vam)
1702 name_sort_t *nses = 0, *ns;
1704 if (vam->json_output)
1707 ("JSON output supported only for VPE API calls and dump_stats_table");
1712 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1714 vec_add2 (nses, ns, 1);
1715 ns->name = (u8 *)(p->key);
1716 ns->value = (u32) p->value[0];
1720 vec_sort_with_function (nses, name_sort_cmp);
1722 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
1723 vec_foreach (ns, nses)
1725 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
1732 dump_ip_table (vat_main_t * vam, int is_ipv6)
1734 const ip_details_t *det = NULL;
1735 const ip_address_details_t *address = NULL;
1738 print (vam->ofp, "%-12s", "sw_if_index");
1740 vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
1747 print (vam->ofp, "%-12d", i);
1748 print (vam->ofp, " %-30s%-13s", "Address", "Prefix length");
1753 vec_foreach (address, det->addr)
1757 is_ipv6 ? format_ip6_address : format_ip4_address,
1758 address->ip, address->prefix_length);
1766 dump_ipv4_table (vat_main_t * vam)
1768 if (vam->json_output)
1771 ("JSON output supported only for VPE API calls and dump_stats_table");
1775 return dump_ip_table (vam, 0);
1779 dump_ipv6_table (vat_main_t * vam)
1781 if (vam->json_output)
1784 ("JSON output supported only for VPE API calls and dump_stats_table");
1788 return dump_ip_table (vam, 1);
1792 * Pass CLI buffers directly in the CLI_INBAND API message,
1793 * instead of an additional shared memory area.
1796 exec_inband (vat_main_t * vam)
1798 vl_api_cli_inband_t *mp;
1799 unformat_input_t *i = vam->input;
1802 if (vec_len (i->buffer) == 0)
1805 if (vam->exec_mode == 0 && unformat (i, "mode"))
1810 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
1817 * In order for the CLI command to work, it
1818 * must be a vector ending in \n, not a C-string ending
1821 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
1822 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
1826 /* json responses may or may not include a useful reply... */
1827 if (vec_len (vam->cmd_reply))
1828 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
1833 exec (vat_main_t * vam)
1835 return exec_inband (vam);
1839 api_create_loopback (vat_main_t * vam)
1841 unformat_input_t *i = vam->input;
1842 vl_api_create_loopback_t *mp;
1843 vl_api_create_loopback_instance_t *mp_lbi;
1846 u8 is_specified = 0;
1847 u32 user_instance = 0;
1850 clib_memset (mac_address, 0, sizeof (mac_address));
1852 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1854 if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
1856 if (unformat (i, "instance %d", &user_instance))
1864 M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
1865 mp_lbi->is_specified = is_specified;
1867 mp_lbi->user_instance = htonl (user_instance);
1869 clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
1874 /* Construct the API message */
1875 M (CREATE_LOOPBACK, mp);
1877 clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
1886 api_delete_loopback (vat_main_t * vam)
1888 unformat_input_t *i = vam->input;
1889 vl_api_delete_loopback_t *mp;
1890 u32 sw_if_index = ~0;
1893 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1895 if (unformat (i, "sw_if_index %d", &sw_if_index))
1901 if (sw_if_index == ~0)
1903 errmsg ("missing sw_if_index");
1907 /* Construct the API message */
1908 M (DELETE_LOOPBACK, mp);
1909 mp->sw_if_index = ntohl (sw_if_index);
1917 api_want_interface_events (vat_main_t * vam)
1919 unformat_input_t *i = vam->input;
1920 vl_api_want_interface_events_t *mp;
1924 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1926 if (unformat (i, "enable"))
1928 else if (unformat (i, "disable"))
1936 errmsg ("missing enable|disable");
1940 M (WANT_INTERFACE_EVENTS, mp);
1941 mp->enable_disable = enable;
1943 vam->interface_event_display = enable;
1951 /* Note: non-static, called once to set up the initial intfc table */
1953 api_sw_interface_dump (vat_main_t * vam)
1955 vl_api_sw_interface_dump_t *mp;
1956 vl_api_control_ping_t *mp_ping;
1958 name_sort_t *nses = 0, *ns;
1959 sw_interface_subif_t *sub = NULL;
1962 /* Toss the old name table */
1964 hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1966 vec_add2 (nses, ns, 1);
1967 ns->name = (u8 *)(p->key);
1968 ns->value = (u32) p->value[0];
1972 hash_free (vam->sw_if_index_by_interface_name);
1974 vec_foreach (ns, nses) vec_free (ns->name);
1978 vec_foreach (sub, vam->sw_if_subif_table)
1980 vec_free (sub->interface_name);
1982 vec_free (vam->sw_if_subif_table);
1984 /* recreate the interface name hash table */
1985 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
1988 * Ask for all interface names. Otherwise, the epic catalog of
1989 * name filters becomes ridiculously long, and vat ends up needing
1990 * to be taught about new interface types.
1992 M (SW_INTERFACE_DUMP, mp);
1995 /* Use a control ping for synchronization */
1996 MPING (CONTROL_PING, mp_ping);
2004 api_sw_interface_set_flags (vat_main_t * vam)
2006 unformat_input_t *i = vam->input;
2007 vl_api_sw_interface_set_flags_t *mp;
2009 u8 sw_if_index_set = 0;
2013 /* Parse args required to build the message */
2014 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2016 if (unformat (i, "admin-up"))
2018 else if (unformat (i, "admin-down"))
2021 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2022 sw_if_index_set = 1;
2023 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2024 sw_if_index_set = 1;
2029 if (sw_if_index_set == 0)
2031 errmsg ("missing interface name or sw_if_index");
2035 /* Construct the API message */
2036 M (SW_INTERFACE_SET_FLAGS, mp);
2037 mp->sw_if_index = ntohl (sw_if_index);
2038 mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
2043 /* Wait for a reply, return the good/bad news... */
2049 api_sw_interface_set_rx_placement (vat_main_t * vam)
2051 unformat_input_t *i = vam->input;
2052 vl_api_sw_interface_set_rx_placement_t *mp;
2054 u8 sw_if_index_set = 0;
2057 u32 queue_id, thread_index;
2059 /* Parse args required to build the message */
2060 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2062 if (unformat (i, "queue %d", &queue_id))
2064 else if (unformat (i, "main"))
2066 else if (unformat (i, "worker %d", &thread_index))
2069 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2070 sw_if_index_set = 1;
2071 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2072 sw_if_index_set = 1;
2077 if (sw_if_index_set == 0)
2079 errmsg ("missing interface name or sw_if_index");
2085 /* Construct the API message */
2086 M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
2087 mp->sw_if_index = ntohl (sw_if_index);
2088 mp->worker_id = ntohl (thread_index);
2089 mp->queue_id = ntohl (queue_id);
2090 mp->is_main = is_main;
2094 /* Wait for a reply, return the good/bad news... */
2099 static void vl_api_sw_interface_rx_placement_details_t_handler
2100 (vl_api_sw_interface_rx_placement_details_t * mp)
2102 vat_main_t *vam = &vat_main;
2103 u32 worker_id = ntohl (mp->worker_id);
2106 "\n%-11d %-11s %-6d %-5d %-9s",
2107 ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
2108 worker_id, ntohl (mp->queue_id),
2110 1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
2113 static void vl_api_sw_interface_rx_placement_details_t_handler_json
2114 (vl_api_sw_interface_rx_placement_details_t * mp)
2116 vat_main_t *vam = &vat_main;
2117 vat_json_node_t *node = NULL;
2119 if (VAT_JSON_ARRAY != vam->json_tree.type)
2121 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2122 vat_json_init_array (&vam->json_tree);
2124 node = vat_json_array_add (&vam->json_tree);
2126 vat_json_init_object (node);
2127 vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2128 vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
2129 vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
2130 vat_json_object_add_uint (node, "mode", mp->mode);
2134 api_sw_interface_rx_placement_dump (vat_main_t * vam)
2136 unformat_input_t *i = vam->input;
2137 vl_api_sw_interface_rx_placement_dump_t *mp;
2138 vl_api_control_ping_t *mp_ping;
2141 u8 sw_if_index_set = 0;
2143 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2145 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2147 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2154 "\n%-11s %-11s %-6s %-5s %-4s",
2155 "sw_if_index", "main/worker", "thread", "queue", "mode");
2157 /* Dump Interface rx placement */
2158 M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
2160 if (sw_if_index_set)
2161 mp->sw_if_index = htonl (sw_if_index);
2163 mp->sw_if_index = ~0;
2167 /* Use a control ping for synchronization */
2168 MPING (CONTROL_PING, mp_ping);
2176 api_sw_interface_clear_stats (vat_main_t * vam)
2178 unformat_input_t *i = vam->input;
2179 vl_api_sw_interface_clear_stats_t *mp;
2181 u8 sw_if_index_set = 0;
2184 /* Parse args required to build the message */
2185 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2187 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2188 sw_if_index_set = 1;
2189 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2190 sw_if_index_set = 1;
2195 /* Construct the API message */
2196 M (SW_INTERFACE_CLEAR_STATS, mp);
2198 if (sw_if_index_set == 1)
2199 mp->sw_if_index = ntohl (sw_if_index);
2201 mp->sw_if_index = ~0;
2206 /* Wait for a reply, return the good/bad news... */
2212 api_sw_interface_add_del_address (vat_main_t * vam)
2214 unformat_input_t *i = vam->input;
2215 vl_api_sw_interface_add_del_address_t *mp;
2217 u8 sw_if_index_set = 0;
2218 u8 is_add = 1, del_all = 0;
2219 u32 address_length = 0;
2220 u8 v4_address_set = 0;
2221 u8 v6_address_set = 0;
2222 ip4_address_t v4address;
2223 ip6_address_t v6address;
2226 /* Parse args required to build the message */
2227 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2229 if (unformat (i, "del-all"))
2231 else if (unformat (i, "del"))
2234 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2235 sw_if_index_set = 1;
2236 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2237 sw_if_index_set = 1;
2238 else if (unformat (i, "%U/%d",
2239 unformat_ip4_address, &v4address, &address_length))
2241 else if (unformat (i, "%U/%d",
2242 unformat_ip6_address, &v6address, &address_length))
2248 if (sw_if_index_set == 0)
2250 errmsg ("missing interface name or sw_if_index");
2253 if (v4_address_set && v6_address_set)
2255 errmsg ("both v4 and v6 addresses set");
2258 if (!v4_address_set && !v6_address_set && !del_all)
2260 errmsg ("no addresses set");
2264 /* Construct the API message */
2265 M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
2267 mp->sw_if_index = ntohl (sw_if_index);
2268 mp->is_add = is_add;
2269 mp->del_all = del_all;
2272 mp->prefix.address.af = ADDRESS_IP6;
2273 clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
2277 mp->prefix.address.af = ADDRESS_IP4;
2278 clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
2280 mp->prefix.len = address_length;
2285 /* Wait for a reply, return good/bad news */
2291 api_sw_interface_set_table (vat_main_t * vam)
2293 unformat_input_t *i = vam->input;
2294 vl_api_sw_interface_set_table_t *mp;
2295 u32 sw_if_index, vrf_id = 0;
2296 u8 sw_if_index_set = 0;
2300 /* Parse args required to build the message */
2301 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2303 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2304 sw_if_index_set = 1;
2305 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2306 sw_if_index_set = 1;
2307 else if (unformat (i, "vrf %d", &vrf_id))
2309 else if (unformat (i, "ipv6"))
2315 if (sw_if_index_set == 0)
2317 errmsg ("missing interface name or sw_if_index");
2321 /* Construct the API message */
2322 M (SW_INTERFACE_SET_TABLE, mp);
2324 mp->sw_if_index = ntohl (sw_if_index);
2325 mp->is_ipv6 = is_ipv6;
2326 mp->vrf_id = ntohl (vrf_id);
2331 /* Wait for a reply... */
2336 static void vl_api_sw_interface_get_table_reply_t_handler
2337 (vl_api_sw_interface_get_table_reply_t * mp)
2339 vat_main_t *vam = &vat_main;
2341 print (vam->ofp, "%d", ntohl (mp->vrf_id));
2343 vam->retval = ntohl (mp->retval);
2344 vam->result_ready = 1;
2348 static void vl_api_sw_interface_get_table_reply_t_handler_json
2349 (vl_api_sw_interface_get_table_reply_t * mp)
2351 vat_main_t *vam = &vat_main;
2352 vat_json_node_t node;
2354 vat_json_init_object (&node);
2355 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2356 vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
2358 vat_json_print (vam->ofp, &node);
2359 vat_json_free (&node);
2361 vam->retval = ntohl (mp->retval);
2362 vam->result_ready = 1;
2366 api_sw_interface_get_table (vat_main_t * vam)
2368 unformat_input_t *i = vam->input;
2369 vl_api_sw_interface_get_table_t *mp;
2371 u8 sw_if_index_set = 0;
2375 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2377 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2378 sw_if_index_set = 1;
2379 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2380 sw_if_index_set = 1;
2381 else if (unformat (i, "ipv6"))
2387 if (sw_if_index_set == 0)
2389 errmsg ("missing interface name or sw_if_index");
2393 M (SW_INTERFACE_GET_TABLE, mp);
2394 mp->sw_if_index = htonl (sw_if_index);
2395 mp->is_ipv6 = is_ipv6;
2403 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
2405 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
2408 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
2411 addr->domain = x[0];
2414 addr->function = x[3];
2420 api_ip_table_add_del (vat_main_t *vam)
2422 unformat_input_t *i = vam->input;
2423 vl_api_ip_table_add_del_t *mp;
2429 /* Parse args required to build the message */
2430 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2432 if (unformat (i, "ipv6"))
2434 else if (unformat (i, "del"))
2436 else if (unformat (i, "add"))
2438 else if (unformat (i, "table %d", &table_id))
2442 clib_warning ("parse error '%U'", format_unformat_error, i);
2449 errmsg ("missing table-ID");
2453 /* Construct the API message */
2454 M (IP_TABLE_ADD_DEL, mp);
2456 mp->table.table_id = ntohl (table_id);
2457 mp->table.is_ip6 = is_ipv6;
2458 mp->is_add = is_add;
2463 /* Wait for a reply... */
2470 unformat_fib_path (unformat_input_t *input, va_list *args)
2472 vat_main_t *vam = va_arg (*args, vat_main_t *);
2473 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
2474 u32 weight, preference;
2475 mpls_label_t out_label;
2477 clib_memset (path, 0, sizeof (*path));
2479 path->sw_if_index = ~0;
2483 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2485 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
2486 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
2487 &path->sw_if_index))
2489 path->proto = FIB_API_PATH_NH_PROTO_IP4;
2491 else if (unformat (input, "%U %U",
2492 unformat_vl_api_ip6_address,
2493 &path->nh.address.ip6,
2494 api_unformat_sw_if_index, vam, &path->sw_if_index))
2496 path->proto = FIB_API_PATH_NH_PROTO_IP6;
2498 else if (unformat (input, "weight %u", &weight))
2500 path->weight = weight;
2502 else if (unformat (input, "preference %u", &preference))
2504 path->preference = preference;
2506 else if (unformat (input, "%U next-hop-table %d",
2507 unformat_vl_api_ip4_address,
2508 &path->nh.address.ip4, &path->table_id))
2510 path->proto = FIB_API_PATH_NH_PROTO_IP4;
2512 else if (unformat (input, "%U next-hop-table %d",
2513 unformat_vl_api_ip6_address,
2514 &path->nh.address.ip6, &path->table_id))
2516 path->proto = FIB_API_PATH_NH_PROTO_IP6;
2518 else if (unformat (input, "%U",
2519 unformat_vl_api_ip4_address, &path->nh.address.ip4))
2522 * the recursive next-hops are by default in the default table
2525 path->sw_if_index = ~0;
2526 path->proto = FIB_API_PATH_NH_PROTO_IP4;
2528 else if (unformat (input, "%U",
2529 unformat_vl_api_ip6_address, &path->nh.address.ip6))
2532 * the recursive next-hops are by default in the default table
2535 path->sw_if_index = ~0;
2536 path->proto = FIB_API_PATH_NH_PROTO_IP6;
2538 else if (unformat (input, "resolve-via-host"))
2540 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
2542 else if (unformat (input, "resolve-via-attached"))
2544 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
2546 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
2548 path->type = FIB_API_PATH_TYPE_LOCAL;
2549 path->sw_if_index = ~0;
2550 path->proto = FIB_API_PATH_NH_PROTO_IP4;
2552 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
2554 path->type = FIB_API_PATH_TYPE_LOCAL;
2555 path->sw_if_index = ~0;
2556 path->proto = FIB_API_PATH_NH_PROTO_IP6;
2558 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
2560 else if (unformat (input, "via-label %d", &path->nh.via_label))
2562 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
2563 path->sw_if_index = ~0;
2565 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
2567 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
2568 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
2570 else if (unformat (input, "local"))
2572 path->type = FIB_API_PATH_TYPE_LOCAL;
2574 else if (unformat (input, "out-labels"))
2576 while (unformat (input, "%d", &out_label))
2578 path->label_stack[path->n_labels].label = out_label;
2579 path->label_stack[path->n_labels].is_uniform = 0;
2580 path->label_stack[path->n_labels].ttl = 64;
2584 else if (unformat (input, "via"))
2586 /* new path, back up and return */
2587 unformat_put_input (input);
2588 unformat_put_input (input);
2589 unformat_put_input (input);
2590 unformat_put_input (input);
2599 path->proto = ntohl (path->proto);
2600 path->type = ntohl (path->type);
2601 path->flags = ntohl (path->flags);
2602 path->table_id = ntohl (path->table_id);
2603 path->sw_if_index = ntohl (path->sw_if_index);
2609 api_ip_route_add_del (vat_main_t * vam)
2611 unformat_input_t *i = vam->input;
2612 vl_api_ip_route_add_del_t *mp;
2615 u8 is_multipath = 0;
2618 vl_api_prefix_t pfx = { };
2619 vl_api_fib_path_t paths[8];
2623 u32 random_add_del = 0;
2624 u32 *random_vector = 0;
2625 u32 random_seed = 0xdeaddabe;
2627 /* Parse args required to build the message */
2628 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2630 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
2632 else if (unformat (i, "del"))
2634 else if (unformat (i, "add"))
2636 else if (unformat (i, "vrf %d", &vrf_id))
2638 else if (unformat (i, "count %d", &count))
2640 else if (unformat (i, "random"))
2642 else if (unformat (i, "multipath"))
2644 else if (unformat (i, "seed %d", &random_seed))
2648 (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
2651 if (8 == path_count)
2653 errmsg ("max 8 paths");
2659 clib_warning ("parse error '%U'", format_unformat_error, i);
2666 errmsg ("specify a path; via ...");
2669 if (prefix_set == 0)
2671 errmsg ("missing prefix");
2675 /* Generate a pile of unique, random routes */
2678 ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
2679 u32 this_random_address;
2682 random_hash = hash_create (count, sizeof (uword));
2684 hash_set (random_hash, i->as_u32, 1);
2685 for (j = 0; j <= count; j++)
2689 this_random_address = random_u32 (&random_seed);
2690 this_random_address =
2691 clib_host_to_net_u32 (this_random_address);
2693 while (hash_get (random_hash, this_random_address));
2694 vec_add1 (random_vector, this_random_address);
2695 hash_set (random_hash, this_random_address, 1);
2697 hash_free (random_hash);
2698 set_ip4_address (&pfx.address, random_vector[0]);
2703 /* Turn on async mode */
2704 vam->async_mode = 1;
2705 vam->async_errors = 0;
2706 before = vat_time_now (vam);
2709 for (j = 0; j < count; j++)
2711 /* Construct the API message */
2712 M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
2714 mp->is_add = is_add;
2715 mp->is_multipath = is_multipath;
2717 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
2718 mp->route.table_id = ntohl (vrf_id);
2719 mp->route.n_paths = path_count;
2721 clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
2724 set_ip4_address (&pfx.address, random_vector[j + 1]);
2726 increment_address (&pfx.address);
2729 /* If we receive SIGTERM, stop now... */
2734 /* When testing multiple add/del ops, use a control-ping to sync */
2737 vl_api_control_ping_t *mp_ping;
2741 /* Shut off async mode */
2742 vam->async_mode = 0;
2744 MPING (CONTROL_PING, mp_ping);
2747 timeout = vat_time_now (vam) + 1.0;
2748 while (vat_time_now (vam) < timeout)
2749 if (vam->result_ready == 1)
2754 if (vam->retval == -99)
2757 if (vam->async_errors > 0)
2759 errmsg ("%d asynchronous errors", vam->async_errors);
2762 vam->async_errors = 0;
2763 after = vat_time_now (vam);
2765 /* slim chance, but we might have eaten SIGTERM on the first iteration */
2769 print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
2770 count, after - before, count / (after - before));
2776 /* Wait for a reply... */
2781 /* Return the good/bad news */
2782 return (vam->retval);
2786 api_ip_mroute_add_del (vat_main_t * vam)
2788 unformat_input_t *i = vam->input;
2789 u8 path_set = 0, prefix_set = 0, is_add = 1;
2790 vl_api_ip_mroute_add_del_t *mp;
2791 mfib_entry_flags_t eflags = 0;
2792 vl_api_mfib_path_t path;
2793 vl_api_mprefix_t pfx = { };
2797 /* Parse args required to build the message */
2798 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2800 if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
2803 pfx.grp_address_length = htons (pfx.grp_address_length);
2805 else if (unformat (i, "del"))
2807 else if (unformat (i, "add"))
2809 else if (unformat (i, "vrf %d", &vrf_id))
2811 else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
2812 path.itf_flags = htonl (path.itf_flags);
2813 else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
2815 else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
2819 clib_warning ("parse error '%U'", format_unformat_error, i);
2824 if (prefix_set == 0)
2826 errmsg ("missing addresses\n");
2831 errmsg ("missing path\n");
2835 /* Construct the API message */
2836 M (IP_MROUTE_ADD_DEL, mp);
2838 mp->is_add = is_add;
2839 mp->is_multipath = 1;
2841 clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
2842 mp->route.table_id = htonl (vrf_id);
2843 mp->route.n_paths = 1;
2844 mp->route.entry_flags = htonl (eflags);
2846 clib_memcpy (&mp->route.paths, &path, sizeof (path));
2850 /* Wait for a reply... */
2856 api_sw_interface_set_unnumbered (vat_main_t * vam)
2858 unformat_input_t *i = vam->input;
2859 vl_api_sw_interface_set_unnumbered_t *mp;
2861 u32 unnum_sw_index = ~0;
2863 u8 sw_if_index_set = 0;
2866 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2868 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2869 sw_if_index_set = 1;
2870 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2871 sw_if_index_set = 1;
2872 else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
2874 else if (unformat (i, "del"))
2878 clib_warning ("parse error '%U'", format_unformat_error, i);
2883 if (sw_if_index_set == 0)
2885 errmsg ("missing interface name or sw_if_index");
2889 M (SW_INTERFACE_SET_UNNUMBERED, mp);
2891 mp->sw_if_index = ntohl (sw_if_index);
2892 mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
2893 mp->is_add = is_add;
2902 api_create_vlan_subif (vat_main_t * vam)
2904 unformat_input_t *i = vam->input;
2905 vl_api_create_vlan_subif_t *mp;
2907 u8 sw_if_index_set = 0;
2912 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2914 if (unformat (i, "sw_if_index %d", &sw_if_index))
2915 sw_if_index_set = 1;
2917 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2918 sw_if_index_set = 1;
2919 else if (unformat (i, "vlan %d", &vlan_id))
2923 clib_warning ("parse error '%U'", format_unformat_error, i);
2928 if (sw_if_index_set == 0)
2930 errmsg ("missing interface name or sw_if_index");
2934 if (vlan_id_set == 0)
2936 errmsg ("missing vlan_id");
2939 M (CREATE_VLAN_SUBIF, mp);
2941 mp->sw_if_index = ntohl (sw_if_index);
2942 mp->vlan_id = ntohl (vlan_id);
2949 #define foreach_create_subif_bit \
2956 _(outer_vlan_id_any) \
2957 _(inner_vlan_id_any)
2959 #define foreach_create_subif_flag \
2964 _(4, "exact_match") \
2965 _(5, "default_sub") \
2966 _(6, "outer_vlan_id_any") \
2967 _(7, "inner_vlan_id_any")
2970 api_create_subif (vat_main_t * vam)
2972 unformat_input_t *i = vam->input;
2973 vl_api_create_subif_t *mp;
2975 u8 sw_if_index_set = 0;
2978 u32 __attribute__ ((unused)) no_tags = 0;
2979 u32 __attribute__ ((unused)) one_tag = 0;
2980 u32 __attribute__ ((unused)) two_tags = 0;
2981 u32 __attribute__ ((unused)) dot1ad = 0;
2982 u32 __attribute__ ((unused)) exact_match = 0;
2983 u32 __attribute__ ((unused)) default_sub = 0;
2984 u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
2985 u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
2987 u16 outer_vlan_id = 0;
2988 u16 inner_vlan_id = 0;
2991 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2993 if (unformat (i, "sw_if_index %d", &sw_if_index))
2994 sw_if_index_set = 1;
2996 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2997 sw_if_index_set = 1;
2998 else if (unformat (i, "sub_id %d", &sub_id))
3000 else if (unformat (i, "outer_vlan_id %d", &tmp))
3001 outer_vlan_id = tmp;
3002 else if (unformat (i, "inner_vlan_id %d", &tmp))
3003 inner_vlan_id = tmp;
3005 #define _(a) else if (unformat (i, #a)) a = 1 ;
3006 foreach_create_subif_bit
3010 clib_warning ("parse error '%U'", format_unformat_error, i);
3015 if (sw_if_index_set == 0)
3017 errmsg ("missing interface name or sw_if_index");
3021 if (sub_id_set == 0)
3023 errmsg ("missing sub_id");
3026 M (CREATE_SUBIF, mp);
3028 mp->sw_if_index = ntohl (sw_if_index);
3029 mp->sub_id = ntohl (sub_id);
3031 #define _(a,b) mp->sub_if_flags |= (1 << a);
3032 foreach_create_subif_flag;
3035 mp->outer_vlan_id = ntohs (outer_vlan_id);
3036 mp->inner_vlan_id = ntohs (inner_vlan_id);
3044 api_ip_table_replace_begin (vat_main_t * vam)
3046 unformat_input_t *i = vam->input;
3047 vl_api_ip_table_replace_begin_t *mp;
3052 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3054 if (unformat (i, "table %d", &table_id))
3056 else if (unformat (i, "ipv6"))
3060 clib_warning ("parse error '%U'", format_unformat_error, i);
3065 M (IP_TABLE_REPLACE_BEGIN, mp);
3067 mp->table.table_id = ntohl (table_id);
3068 mp->table.is_ip6 = is_ipv6;
3076 api_ip_table_flush (vat_main_t * vam)
3078 unformat_input_t *i = vam->input;
3079 vl_api_ip_table_flush_t *mp;
3084 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3086 if (unformat (i, "table %d", &table_id))
3088 else if (unformat (i, "ipv6"))
3092 clib_warning ("parse error '%U'", format_unformat_error, i);
3097 M (IP_TABLE_FLUSH, mp);
3099 mp->table.table_id = ntohl (table_id);
3100 mp->table.is_ip6 = is_ipv6;
3108 api_ip_table_replace_end (vat_main_t * vam)
3110 unformat_input_t *i = vam->input;
3111 vl_api_ip_table_replace_end_t *mp;
3116 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3118 if (unformat (i, "table %d", &table_id))
3120 else if (unformat (i, "ipv6"))
3124 clib_warning ("parse error '%U'", format_unformat_error, i);
3129 M (IP_TABLE_REPLACE_END, mp);
3131 mp->table.table_id = ntohl (table_id);
3132 mp->table.is_ip6 = is_ipv6;
3140 api_set_ip_flow_hash (vat_main_t * vam)
3142 unformat_input_t *i = vam->input;
3143 vl_api_set_ip_flow_hash_t *mp;
3155 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3157 if (unformat (i, "vrf %d", &vrf_id))
3159 else if (unformat (i, "ipv6"))
3161 else if (unformat (i, "src"))
3163 else if (unformat (i, "dst"))
3165 else if (unformat (i, "sport"))
3167 else if (unformat (i, "dport"))
3169 else if (unformat (i, "proto"))
3171 else if (unformat (i, "reverse"))
3176 clib_warning ("parse error '%U'", format_unformat_error, i);
3181 if (vrf_id_set == 0)
3183 errmsg ("missing vrf id");
3187 M (SET_IP_FLOW_HASH, mp);
3193 mp->reverse = reverse;
3194 mp->vrf_id = ntohl (vrf_id);
3195 mp->is_ipv6 = is_ipv6;
3203 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
3205 unformat_input_t *i = vam->input;
3206 vl_api_sw_interface_ip6_enable_disable_t *mp;
3208 u8 sw_if_index_set = 0;
3212 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3214 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3215 sw_if_index_set = 1;
3216 else if (unformat (i, "sw_if_index %d", &sw_if_index))
3217 sw_if_index_set = 1;
3218 else if (unformat (i, "enable"))
3220 else if (unformat (i, "disable"))
3224 clib_warning ("parse error '%U'", format_unformat_error, i);
3229 if (sw_if_index_set == 0)
3231 errmsg ("missing interface name or sw_if_index");
3235 M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
3237 mp->sw_if_index = ntohl (sw_if_index);
3238 mp->enable = enable;
3246 u8 localsid_addr[16];
3255 api_ioam_enable (vat_main_t * vam)
3257 unformat_input_t *input = vam->input;
3258 vl_api_ioam_enable_t *mp;
3260 int has_trace_option = 0;
3261 int has_pot_option = 0;
3262 int has_seqno_option = 0;
3263 int has_analyse_option = 0;
3266 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3268 if (unformat (input, "trace"))
3269 has_trace_option = 1;
3270 else if (unformat (input, "pot"))
3272 else if (unformat (input, "seqno"))
3273 has_seqno_option = 1;
3274 else if (unformat (input, "analyse"))
3275 has_analyse_option = 1;
3279 M (IOAM_ENABLE, mp);
3280 mp->id = htons (id);
3281 mp->seqno = has_seqno_option;
3282 mp->analyse = has_analyse_option;
3283 mp->pot_enable = has_pot_option;
3284 mp->trace_enable = has_trace_option;
3293 api_ioam_disable (vat_main_t * vam)
3295 vl_api_ioam_disable_t *mp;
3298 M (IOAM_DISABLE, mp);
3304 #define foreach_tcp_proto_field \
3308 #define foreach_udp_proto_field \
3312 #define foreach_ip4_proto_field \
3324 u16 src_port, dst_port;
3327 #if VPP_API_TEST_BUILTIN == 0
3329 unformat_tcp_mask (unformat_input_t * input, va_list * args)
3331 u8 **maskp = va_arg (*args, u8 **);
3333 u8 found_something = 0;
3336 #define _(a) u8 a=0;
3337 foreach_tcp_proto_field;
3340 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3343 #define _(a) else if (unformat (input, #a)) a=1;
3344 foreach_tcp_proto_field
3350 #define _(a) found_something += a;
3351 foreach_tcp_proto_field;
3354 if (found_something == 0)
3357 vec_validate (mask, sizeof (*tcp) - 1);
3359 tcp = (tcp_header_t *) mask;
3361 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
3362 foreach_tcp_proto_field;
3370 unformat_udp_mask (unformat_input_t * input, va_list * args)
3372 u8 **maskp = va_arg (*args, u8 **);
3374 u8 found_something = 0;
3377 #define _(a) u8 a=0;
3378 foreach_udp_proto_field;
3381 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3384 #define _(a) else if (unformat (input, #a)) a=1;
3385 foreach_udp_proto_field
3391 #define _(a) found_something += a;
3392 foreach_udp_proto_field;
3395 if (found_something == 0)
3398 vec_validate (mask, sizeof (*udp) - 1);
3400 udp = (udp_header_t *) mask;
3402 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
3403 foreach_udp_proto_field;
3411 unformat_l4_mask (unformat_input_t * input, va_list * args)
3413 u8 **maskp = va_arg (*args, u8 **);
3414 u16 src_port = 0, dst_port = 0;
3415 tcpudp_header_t *tcpudp;
3417 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3419 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
3421 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
3423 else if (unformat (input, "src_port"))
3425 else if (unformat (input, "dst_port"))
3431 if (!src_port && !dst_port)
3435 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
3437 tcpudp = (tcpudp_header_t *) mask;
3438 tcpudp->src_port = src_port;
3439 tcpudp->dst_port = dst_port;
3447 unformat_ip4_mask (unformat_input_t * input, va_list * args)
3449 u8 **maskp = va_arg (*args, u8 **);
3451 u8 found_something = 0;
3454 #define _(a) u8 a=0;
3455 foreach_ip4_proto_field;
3461 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3463 if (unformat (input, "version"))
3465 else if (unformat (input, "hdr_length"))
3467 else if (unformat (input, "src"))
3469 else if (unformat (input, "dst"))
3471 else if (unformat (input, "proto"))
3474 #define _(a) else if (unformat (input, #a)) a=1;
3475 foreach_ip4_proto_field
3481 #define _(a) found_something += a;
3482 foreach_ip4_proto_field;
3485 if (found_something == 0)
3488 vec_validate (mask, sizeof (*ip) - 1);
3490 ip = (ip4_header_t *) mask;
3492 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
3493 foreach_ip4_proto_field;
3496 ip->ip_version_and_header_length = 0;
3499 ip->ip_version_and_header_length |= 0xF0;
3502 ip->ip_version_and_header_length |= 0x0F;
3508 #define foreach_ip6_proto_field \
3516 unformat_ip6_mask (unformat_input_t * input, va_list * args)
3518 u8 **maskp = va_arg (*args, u8 **);
3520 u8 found_something = 0;
3522 u32 ip_version_traffic_class_and_flow_label;
3524 #define _(a) u8 a=0;
3525 foreach_ip6_proto_field;
3528 u8 traffic_class = 0;
3531 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3533 if (unformat (input, "version"))
3535 else if (unformat (input, "traffic-class"))
3537 else if (unformat (input, "flow-label"))
3539 else if (unformat (input, "src"))
3541 else if (unformat (input, "dst"))
3543 else if (unformat (input, "proto"))
3546 #define _(a) else if (unformat (input, #a)) a=1;
3547 foreach_ip6_proto_field
3553 #define _(a) found_something += a;
3554 foreach_ip6_proto_field;
3557 if (found_something == 0)
3560 vec_validate (mask, sizeof (*ip) - 1);
3562 ip = (ip6_header_t *) mask;
3564 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
3565 foreach_ip6_proto_field;
3568 ip_version_traffic_class_and_flow_label = 0;
3571 ip_version_traffic_class_and_flow_label |= 0xF0000000;
3574 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
3577 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
3579 ip->ip_version_traffic_class_and_flow_label =
3580 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
3587 unformat_l3_mask (unformat_input_t * input, va_list * args)
3589 u8 **maskp = va_arg (*args, u8 **);
3591 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3593 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
3595 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
3604 unformat_l2_mask (unformat_input_t * input, va_list * args)
3606 u8 **maskp = va_arg (*args, u8 **);
3621 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3623 if (unformat (input, "src"))
3625 else if (unformat (input, "dst"))
3627 else if (unformat (input, "proto"))
3629 else if (unformat (input, "tag1"))
3631 else if (unformat (input, "tag2"))
3633 else if (unformat (input, "ignore-tag1"))
3635 else if (unformat (input, "ignore-tag2"))
3637 else if (unformat (input, "cos1"))
3639 else if (unformat (input, "cos2"))
3641 else if (unformat (input, "dot1q"))
3643 else if (unformat (input, "dot1ad"))
3648 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
3649 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
3652 if (tag1 || ignore_tag1 || cos1 || dot1q)
3654 if (tag2 || ignore_tag2 || cos2 || dot1ad)
3657 vec_validate (mask, len - 1);
3660 clib_memset (mask, 0xff, 6);
3663 clib_memset (mask + 6, 0xff, 6);
3667 /* inner vlan tag */
3676 mask[21] = mask[20] = 0xff;
3697 mask[16] = mask[17] = 0xff;
3707 mask[12] = mask[13] = 0xff;
3714 unformat_classify_mask (unformat_input_t * input, va_list * args)
3716 u8 **maskp = va_arg (*args, u8 **);
3717 u32 *skipp = va_arg (*args, u32 *);
3718 u32 *matchp = va_arg (*args, u32 *);
3726 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3728 if (unformat (input, "hex %U", unformat_hex_string, &mask))
3730 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
3732 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
3734 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
3748 if (mask || l2 || l3 || l4)
3752 /* "With a free Ethernet header in every package" */
3754 vec_validate (l2, 13);
3758 vec_append (mask, l3);
3763 vec_append (mask, l4);
3768 /* Scan forward looking for the first significant mask octet */
3769 for (i = 0; i < vec_len (mask); i++)
3773 /* compute (skip, match) params */
3774 *skipp = i / sizeof (u32x4);
3775 vec_delete (mask, *skipp * sizeof (u32x4), 0);
3777 /* Pad mask to an even multiple of the vector size */
3778 while (vec_len (mask) % sizeof (u32x4))
3781 match = vec_len (mask) / sizeof (u32x4);
3783 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
3785 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
3786 if (*tmp || *(tmp + 1))
3791 clib_warning ("BUG: match 0");
3793 _vec_len (mask) = match * sizeof (u32x4);
3803 #endif /* VPP_API_TEST_BUILTIN */
3805 #define foreach_l2_next \
3807 _(ethernet, ETHERNET_INPUT) \
3812 unformat_l2_next_index (unformat_input_t * input, va_list * args)
3814 u32 *miss_next_indexp = va_arg (*args, u32 *);
3819 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
3823 if (unformat (input, "%d", &tmp))
3832 *miss_next_indexp = next_index;
3836 #define foreach_ip_next \
3842 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
3844 u32 *miss_next_indexp = va_arg (*args, u32 *);
3849 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
3853 if (unformat (input, "%d", &tmp))
3862 *miss_next_indexp = next_index;
3866 #define foreach_acl_next \
3870 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
3872 u32 *miss_next_indexp = va_arg (*args, u32 *);
3877 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
3881 if (unformat (input, "permit"))
3886 else if (unformat (input, "%d", &tmp))
3895 *miss_next_indexp = next_index;
3900 unformat_policer_precolor (unformat_input_t * input, va_list * args)
3902 u32 *r = va_arg (*args, u32 *);
3904 if (unformat (input, "conform-color"))
3905 *r = POLICE_CONFORM;
3906 else if (unformat (input, "exceed-color"))
3914 #if VPP_API_TEST_BUILTIN == 0
3916 unformat_l4_match (unformat_input_t * input, va_list * args)
3918 u8 **matchp = va_arg (*args, u8 **);
3920 u8 *proto_header = 0;
3926 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3928 if (unformat (input, "src_port %d", &src_port))
3930 else if (unformat (input, "dst_port %d", &dst_port))
3936 h.src_port = clib_host_to_net_u16 (src_port);
3937 h.dst_port = clib_host_to_net_u16 (dst_port);
3938 vec_validate (proto_header, sizeof (h) - 1);
3939 memcpy (proto_header, &h, sizeof (h));
3941 *matchp = proto_header;
3947 unformat_ip4_match (unformat_input_t * input, va_list * args)
3949 u8 **matchp = va_arg (*args, u8 **);
3956 int src = 0, dst = 0;
3957 ip4_address_t src_val, dst_val;
3964 int fragment_id = 0;
3965 u32 fragment_id_val;
3971 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
3973 if (unformat (input, "version %d", &version_val))
3975 else if (unformat (input, "hdr_length %d", &hdr_length_val))
3977 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
3979 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
3981 else if (unformat (input, "proto %d", &proto_val))
3983 else if (unformat (input, "tos %d", &tos_val))
3985 else if (unformat (input, "length %d", &length_val))
3987 else if (unformat (input, "fragment_id %d", &fragment_id_val))
3989 else if (unformat (input, "ttl %d", &ttl_val))
3991 else if (unformat (input, "checksum %d", &checksum_val))
3997 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
3998 + ttl + checksum == 0)
4002 * Aligned because we use the real comparison functions
4004 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
4006 ip = (ip4_header_t *) match;
4008 /* These are realistically matched in practice */
4010 ip->src_address.as_u32 = src_val.as_u32;
4013 ip->dst_address.as_u32 = dst_val.as_u32;
4016 ip->protocol = proto_val;
4019 /* These are not, but they're included for completeness */
4021 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
4024 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
4030 ip->length = clib_host_to_net_u16 (length_val);
4036 ip->checksum = clib_host_to_net_u16 (checksum_val);
4043 unformat_ip6_match (unformat_input_t * input, va_list * args)
4045 u8 **matchp = va_arg (*args, u8 **);
4050 u8 traffic_class = 0;
4051 u32 traffic_class_val = 0;
4054 int src = 0, dst = 0;
4055 ip6_address_t src_val, dst_val;
4058 int payload_length = 0;
4059 u32 payload_length_val;
4062 u32 ip_version_traffic_class_and_flow_label;
4064 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
4066 if (unformat (input, "version %d", &version_val))
4068 else if (unformat (input, "traffic_class %d", &traffic_class_val))
4070 else if (unformat (input, "flow_label %d", &flow_label_val))
4072 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
4074 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
4076 else if (unformat (input, "proto %d", &proto_val))
4078 else if (unformat (input, "payload_length %d", &payload_length_val))
4080 else if (unformat (input, "hop_limit %d", &hop_limit_val))
4086 if (version + traffic_class + flow_label + src + dst + proto +
4087 payload_length + hop_limit == 0)
4091 * Aligned because we use the real comparison functions
4093 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
4095 ip = (ip6_header_t *) match;
4098 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
4101 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
4104 ip->protocol = proto_val;
4106 ip_version_traffic_class_and_flow_label = 0;
4109 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
4112 ip_version_traffic_class_and_flow_label |=
4113 (traffic_class_val & 0xFF) << 20;
4116 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
4118 ip->ip_version_traffic_class_and_flow_label =
4119 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
4122 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
4125 ip->hop_limit = hop_limit_val;
4132 unformat_l3_match (unformat_input_t * input, va_list * args)
4134 u8 **matchp = va_arg (*args, u8 **);
4136 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
4138 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
4140 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
4149 unformat_vlan_tag (unformat_input_t * input, va_list * args)
4151 u8 *tagp = va_arg (*args, u8 *);
4154 if (unformat (input, "%d", &tag))
4156 tagp[0] = (tag >> 8) & 0x0F;
4157 tagp[1] = tag & 0xFF;
4165 unformat_l2_match (unformat_input_t * input, va_list * args)
4167 u8 **matchp = va_arg (*args, u8 **);
4187 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
4189 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
4192 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
4194 else if (unformat (input, "proto %U",
4195 unformat_ethernet_type_host_byte_order, &proto_val))
4197 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
4199 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
4201 else if (unformat (input, "ignore-tag1"))
4203 else if (unformat (input, "ignore-tag2"))
4205 else if (unformat (input, "cos1 %d", &cos1_val))
4207 else if (unformat (input, "cos2 %d", &cos2_val))
4212 if ((src + dst + proto + tag1 + tag2 +
4213 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
4216 if (tag1 || ignore_tag1 || cos1)
4218 if (tag2 || ignore_tag2 || cos2)
4221 vec_validate_aligned (match, len - 1, sizeof (u32x4));
4224 clib_memcpy (match, dst_val, 6);
4227 clib_memcpy (match + 6, src_val, 6);
4231 /* inner vlan tag */
4232 match[19] = tag2_val[1];
4233 match[18] = tag2_val[0];
4235 match[18] |= (cos2_val & 0x7) << 5;
4238 match[21] = proto_val & 0xff;
4239 match[20] = proto_val >> 8;
4243 match[15] = tag1_val[1];
4244 match[14] = tag1_val[0];
4247 match[14] |= (cos1_val & 0x7) << 5;
4253 match[15] = tag1_val[1];
4254 match[14] = tag1_val[0];
4257 match[17] = proto_val & 0xff;
4258 match[16] = proto_val >> 8;
4261 match[14] |= (cos1_val & 0x7) << 5;
4267 match[18] |= (cos2_val & 0x7) << 5;
4269 match[14] |= (cos1_val & 0x7) << 5;
4272 match[13] = proto_val & 0xff;
4273 match[12] = proto_val >> 8;
4281 unformat_qos_source (unformat_input_t * input, va_list * args)
4283 int *qs = va_arg (*args, int *);
4285 if (unformat (input, "ip"))
4286 *qs = QOS_SOURCE_IP;
4287 else if (unformat (input, "mpls"))
4288 *qs = QOS_SOURCE_MPLS;
4289 else if (unformat (input, "ext"))
4290 *qs = QOS_SOURCE_EXT;
4291 else if (unformat (input, "vlan"))
4292 *qs = QOS_SOURCE_VLAN;
4301 api_unformat_classify_match (unformat_input_t * input, va_list * args)
4303 u8 **matchp = va_arg (*args, u8 **);
4304 u32 skip_n_vectors = va_arg (*args, u32);
4305 u32 match_n_vectors = va_arg (*args, u32);
4312 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
4314 if (unformat (input, "hex %U", unformat_hex_string, &match))
4316 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
4318 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
4320 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
4334 if (match || l2 || l3 || l4)
4338 /* "Win a free Ethernet header in every packet" */
4340 vec_validate_aligned (l2, 13, sizeof (u32x4));
4344 vec_append_aligned (match, l3, sizeof (u32x4));
4349 vec_append_aligned (match, l4, sizeof (u32x4));
4354 /* Make sure the vector is big enough even if key is all 0's */
4355 vec_validate_aligned
4356 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
4359 /* Set size, include skipped vectors */
4360 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
4371 api_get_node_index (vat_main_t * vam)
4373 unformat_input_t *i = vam->input;
4374 vl_api_get_node_index_t *mp;
4378 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4380 if (unformat (i, "node %s", &name))
4387 errmsg ("node name required");
4390 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
4392 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
4396 M (GET_NODE_INDEX, mp);
4397 clib_memcpy (mp->node_name, name, vec_len (name));
4406 api_get_next_index (vat_main_t * vam)
4408 unformat_input_t *i = vam->input;
4409 vl_api_get_next_index_t *mp;
4410 u8 *node_name = 0, *next_node_name = 0;
4413 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4415 if (unformat (i, "node-name %s", &node_name))
4417 else if (unformat (i, "next-node-name %s", &next_node_name))
4423 errmsg ("node name required");
4426 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
4428 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
4432 if (next_node_name == 0)
4434 errmsg ("next node name required");
4437 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
4439 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
4443 M (GET_NEXT_INDEX, mp);
4444 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
4445 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
4446 vec_free (node_name);
4447 vec_free (next_node_name);
4455 api_add_node_next (vat_main_t * vam)
4457 unformat_input_t *i = vam->input;
4458 vl_api_add_node_next_t *mp;
4463 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4465 if (unformat (i, "node %s", &name))
4467 else if (unformat (i, "next %s", &next))
4474 errmsg ("node name required");
4477 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
4479 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
4484 errmsg ("next node required");
4487 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
4489 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
4493 M (ADD_NODE_NEXT, mp);
4494 clib_memcpy (mp->node_name, name, vec_len (name));
4495 clib_memcpy (mp->next_name, next, vec_len (next));
4504 #define foreach_vtr_op \
4505 _("disable", L2_VTR_DISABLED) \
4506 _("push-1", L2_VTR_PUSH_1) \
4507 _("push-2", L2_VTR_PUSH_2) \
4508 _("pop-1", L2_VTR_POP_1) \
4509 _("pop-2", L2_VTR_POP_2) \
4510 _("translate-1-1", L2_VTR_TRANSLATE_1_1) \
4511 _("translate-1-2", L2_VTR_TRANSLATE_1_2) \
4512 _("translate-2-1", L2_VTR_TRANSLATE_2_1) \
4513 _("translate-2-2", L2_VTR_TRANSLATE_2_2)
4516 api_show_version (vat_main_t *vam)
4518 vl_api_show_version_t *mp;
4521 M (SHOW_VERSION, mp);
4529 api_interface_name_renumber (vat_main_t *vam)
4531 unformat_input_t *line_input = vam->input;
4532 vl_api_interface_name_renumber_t *mp;
4533 u32 sw_if_index = ~0;
4534 u32 new_show_dev_instance = ~0;
4537 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
4539 if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
4542 else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
4544 else if (unformat (line_input, "new_show_dev_instance %d",
4545 &new_show_dev_instance))
4551 if (sw_if_index == ~0)
4553 errmsg ("missing interface name or sw_if_index");
4557 if (new_show_dev_instance == ~0)
4559 errmsg ("missing new_show_dev_instance");
4563 M (INTERFACE_NAME_RENUMBER, mp);
4565 mp->sw_if_index = ntohl (sw_if_index);
4566 mp->new_show_dev_instance = ntohl (new_show_dev_instance);
4574 api_ip_address_dump (vat_main_t *vam)
4576 unformat_input_t *i = vam->input;
4577 vl_api_ip_address_dump_t *mp;
4578 vl_api_control_ping_t *mp_ping;
4579 u32 sw_if_index = ~0;
4580 u8 sw_if_index_set = 0;
4585 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4587 if (unformat (i, "sw_if_index %d", &sw_if_index))
4588 sw_if_index_set = 1;
4589 else if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4590 sw_if_index_set = 1;
4591 else if (unformat (i, "ipv4"))
4593 else if (unformat (i, "ipv6"))
4599 if (ipv4_set && ipv6_set)
4601 errmsg ("ipv4 and ipv6 flags cannot be both set");
4605 if ((!ipv4_set) && (!ipv6_set))
4607 errmsg ("no ipv4 nor ipv6 flag set");
4611 if (sw_if_index_set == 0)
4613 errmsg ("missing interface name or sw_if_index");
4617 vam->current_sw_if_index = sw_if_index;
4618 vam->is_ipv6 = ipv6_set;
4620 M (IP_ADDRESS_DUMP, mp);
4621 mp->sw_if_index = ntohl (sw_if_index);
4622 mp->is_ipv6 = ipv6_set;
4625 /* Use a control ping for synchronization */
4626 MPING (CONTROL_PING, mp_ping);
4634 api_ip_dump (vat_main_t * vam)
4636 vl_api_ip_dump_t *mp;
4637 vl_api_control_ping_t *mp_ping;
4638 unformat_input_t *in = vam->input;
4645 while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
4647 if (unformat (in, "ipv4"))
4649 else if (unformat (in, "ipv6"))
4655 if (ipv4_set && ipv6_set)
4657 errmsg ("ipv4 and ipv6 flags cannot be both set");
4661 if ((!ipv4_set) && (!ipv6_set))
4663 errmsg ("no ipv4 nor ipv6 flag set");
4668 vam->is_ipv6 = is_ipv6;
4671 for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
4673 vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
4675 vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
4678 mp->is_ipv6 = ipv6_set;
4681 /* Use a control ping for synchronization */
4682 MPING (CONTROL_PING, mp_ping);
4690 api_get_first_msg_id (vat_main_t * vam)
4692 vl_api_get_first_msg_id_t *mp;
4693 unformat_input_t *i = vam->input;
4698 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4700 if (unformat (i, "client %s", &name))
4708 errmsg ("missing client name");
4713 if (vec_len (name) > 63)
4715 errmsg ("client name too long");
4719 M (GET_FIRST_MSG_ID, mp);
4720 clib_memcpy (mp->name, name, vec_len (name));
4727 api_get_node_graph (vat_main_t * vam)
4729 vl_api_get_node_graph_t *mp;
4732 M (GET_NODE_GRAPH, mp);
4736 /* Wait for the reply */
4742 format_fib_api_path_nh_proto (u8 * s, va_list * args)
4744 vl_api_fib_path_nh_proto_t proto =
4745 va_arg (*args, vl_api_fib_path_nh_proto_t);
4749 case FIB_API_PATH_NH_PROTO_IP4:
4750 s = format (s, "ip4");
4752 case FIB_API_PATH_NH_PROTO_IP6:
4753 s = format (s, "ip6");
4755 case FIB_API_PATH_NH_PROTO_MPLS:
4756 s = format (s, "mpls");
4758 case FIB_API_PATH_NH_PROTO_BIER:
4759 s = format (s, "bier");
4761 case FIB_API_PATH_NH_PROTO_ETHERNET:
4762 s = format (s, "ethernet");
4770 format_vl_api_ip_address_union (u8 * s, va_list * args)
4772 vl_api_address_family_t af = va_arg (*args, int);
4773 const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
4778 s = format (s, "%U", format_ip4_address, u->ip4);
4781 s = format (s, "%U", format_ip6_address, u->ip6);
4788 format_vl_api_fib_path_type (u8 * s, va_list * args)
4790 vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
4794 case FIB_API_PATH_TYPE_NORMAL:
4795 s = format (s, "normal");
4797 case FIB_API_PATH_TYPE_LOCAL:
4798 s = format (s, "local");
4800 case FIB_API_PATH_TYPE_DROP:
4801 s = format (s, "drop");
4803 case FIB_API_PATH_TYPE_UDP_ENCAP:
4804 s = format (s, "udp-encap");
4806 case FIB_API_PATH_TYPE_BIER_IMP:
4807 s = format (s, "bier-imp");
4809 case FIB_API_PATH_TYPE_ICMP_UNREACH:
4810 s = format (s, "unreach");
4812 case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
4813 s = format (s, "prohibit");
4815 case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
4816 s = format (s, "src-lookup");
4818 case FIB_API_PATH_TYPE_DVR:
4819 s = format (s, "dvr");
4821 case FIB_API_PATH_TYPE_INTERFACE_RX:
4822 s = format (s, "interface-rx");
4824 case FIB_API_PATH_TYPE_CLASSIFY:
4825 s = format (s, "classify");
4833 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
4836 " weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
4837 ntohl (fp->weight), ntohl (fp->sw_if_index),
4838 format_vl_api_fib_path_type, fp->type,
4839 format_fib_api_path_nh_proto, fp->proto,
4840 format_vl_api_ip_address_union, &fp->nh.address);
4844 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
4845 vl_api_fib_path_t * fp)
4848 struct in6_addr ip6;
4850 vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
4851 vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
4852 vat_json_object_add_uint (node, "type", fp->type);
4853 vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
4854 if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
4856 clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
4857 vat_json_object_add_ip4 (node, "next_hop", ip4);
4859 else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
4861 clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
4862 vat_json_object_add_ip6 (node, "next_hop", ip6);
4866 #define vl_api_ip_table_details_t_endian vl_noop_handler
4867 #define vl_api_ip_table_details_t_print vl_noop_handler
4870 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
4872 vat_main_t *vam = &vat_main;
4875 "%s; table-id %d, prefix %U/%d",
4876 mp->table.name, ntohl (mp->table.table_id));
4880 static void vl_api_ip_table_details_t_handler_json
4881 (vl_api_ip_table_details_t * mp)
4883 vat_main_t *vam = &vat_main;
4884 vat_json_node_t *node = NULL;
4886 if (VAT_JSON_ARRAY != vam->json_tree.type)
4888 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4889 vat_json_init_array (&vam->json_tree);
4891 node = vat_json_array_add (&vam->json_tree);
4893 vat_json_init_object (node);
4894 vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
4898 api_ip_table_dump (vat_main_t * vam)
4900 vl_api_ip_table_dump_t *mp;
4901 vl_api_control_ping_t *mp_ping;
4904 M (IP_TABLE_DUMP, mp);
4907 /* Use a control ping for synchronization */
4908 MPING (CONTROL_PING, mp_ping);
4916 api_ip_mtable_dump (vat_main_t * vam)
4918 vl_api_ip_mtable_dump_t *mp;
4919 vl_api_control_ping_t *mp_ping;
4922 M (IP_MTABLE_DUMP, mp);
4925 /* Use a control ping for synchronization */
4926 MPING (CONTROL_PING, mp_ping);
4934 api_ip_mroute_dump (vat_main_t * vam)
4936 unformat_input_t *input = vam->input;
4937 vl_api_control_ping_t *mp_ping;
4938 vl_api_ip_mroute_dump_t *mp;
4943 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
4945 if (unformat (input, "table_id %d", &table_id))
4947 else if (unformat (input, "ip6"))
4949 else if (unformat (input, "ip4"))
4956 errmsg ("missing table id");
4960 M (IP_MROUTE_DUMP, mp);
4961 mp->table.table_id = table_id;
4962 mp->table.is_ip6 = is_ip6;
4965 /* Use a control ping for synchronization */
4966 MPING (CONTROL_PING, mp_ping);
4973 #define vl_api_ip_route_details_t_endian vl_noop_handler
4974 #define vl_api_ip_route_details_t_print vl_noop_handler
4977 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
4979 vat_main_t *vam = &vat_main;
4980 u8 count = mp->route.n_paths;
4981 vl_api_fib_path_t *fp;
4985 "table-id %d, prefix %U/%d",
4986 ntohl (mp->route.table_id),
4987 format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
4988 for (i = 0; i < count; i++)
4990 fp = &mp->route.paths[i];
4992 vl_api_fib_path_print (vam, fp);
4997 static void vl_api_ip_route_details_t_handler_json
4998 (vl_api_ip_route_details_t * mp)
5000 vat_main_t *vam = &vat_main;
5001 u8 count = mp->route.n_paths;
5002 vat_json_node_t *node = NULL;
5004 struct in6_addr ip6;
5005 vl_api_fib_path_t *fp;
5008 if (VAT_JSON_ARRAY != vam->json_tree.type)
5010 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5011 vat_json_init_array (&vam->json_tree);
5013 node = vat_json_array_add (&vam->json_tree);
5015 vat_json_init_object (node);
5016 vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
5017 if (ADDRESS_IP6 == mp->route.prefix.address.af)
5019 clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
5020 vat_json_object_add_ip6 (node, "prefix", ip6);
5024 clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
5025 vat_json_object_add_ip4 (node, "prefix", ip4);
5027 vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
5028 vat_json_object_add_uint (node, "path_count", count);
5029 for (i = 0; i < count; i++)
5031 fp = &mp->route.paths[i];
5032 vl_api_mpls_fib_path_json_print (node, fp);
5037 api_ip_route_dump (vat_main_t * vam)
5039 unformat_input_t *input = vam->input;
5040 vl_api_ip_route_dump_t *mp;
5041 vl_api_control_ping_t *mp_ping;
5047 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5049 if (unformat (input, "table_id %d", &table_id))
5051 else if (unformat (input, "ip6"))
5053 else if (unformat (input, "ip4"))
5060 errmsg ("missing table id");
5064 M (IP_ROUTE_DUMP, mp);
5066 mp->table.table_id = table_id;
5067 mp->table.is_ip6 = is_ip6;
5071 /* Use a control ping for synchronization */
5072 MPING (CONTROL_PING, mp_ping);
5080 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
5082 unformat_input_t *input = vam->input;
5083 vl_api_ip_source_and_port_range_check_add_del_t *mp;
5086 u16 *high_ports = 0;
5089 vl_api_prefix_t prefix;
5096 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5098 if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
5100 else if (unformat (input, "vrf %d", &vrf_id))
5102 else if (unformat (input, "del"))
5104 else if (unformat (input, "port %d", &tmp))
5106 if (tmp == 0 || tmp > 65535)
5108 errmsg ("port %d out of range", tmp);
5112 this_hi = this_low + 1;
5113 vec_add1 (low_ports, this_low);
5114 vec_add1 (high_ports, this_hi);
5116 else if (unformat (input, "range %d - %d", &tmp, &tmp2))
5118 if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
5120 errmsg ("incorrect range parameters");
5124 /* Note: in debug CLI +1 is added to high before
5125 passing to real fn that does "the work"
5126 (ip_source_and_port_range_check_add_del).
5127 This fn is a wrapper around the binary API fn a
5128 control plane will call, which expects this increment
5129 to have occurred. Hence letting the binary API control
5130 plane fn do the increment for consistency between VAT
5131 and other control planes.
5134 vec_add1 (low_ports, this_low);
5135 vec_add1 (high_ports, this_hi);
5141 if (prefix_set == 0)
5143 errmsg ("<address>/<mask> not specified");
5149 errmsg ("VRF ID required, not specified");
5156 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
5160 if (vec_len (low_ports) == 0)
5162 errmsg ("At least one port or port range required");
5166 M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
5168 mp->is_add = is_add;
5170 clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
5172 mp->number_of_ranges = vec_len (low_ports);
5174 clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
5175 vec_free (low_ports);
5177 clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
5178 vec_free (high_ports);
5180 mp->vrf_id = ntohl (vrf_id);
5188 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
5190 unformat_input_t *input = vam->input;
5191 vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
5192 u32 sw_if_index = ~0;
5194 u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
5195 u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
5199 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5201 if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5203 else if (unformat (input, "sw_if_index %d", &sw_if_index))
5205 else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
5207 else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
5209 else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
5211 else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
5213 else if (unformat (input, "del"))
5219 if (sw_if_index == ~0)
5221 errmsg ("Interface required but not specified");
5227 errmsg ("VRF ID required but not specified");
5231 if (tcp_out_vrf_id == 0
5232 || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
5235 ("VRF ID should not be default. Should be distinct VRF for this purpose.");
5239 /* Construct the API message */
5240 M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
5242 mp->sw_if_index = ntohl (sw_if_index);
5243 mp->is_add = is_add;
5244 mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
5245 mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
5246 mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
5247 mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
5252 /* Wait for a reply... */
5258 api_delete_subif (vat_main_t * vam)
5260 unformat_input_t *i = vam->input;
5261 vl_api_delete_subif_t *mp;
5262 u32 sw_if_index = ~0;
5265 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5267 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5269 if (unformat (i, "sw_if_index %d", &sw_if_index))
5275 if (sw_if_index == ~0)
5277 errmsg ("missing sw_if_index");
5281 /* Construct the API message */
5282 M (DELETE_SUBIF, mp);
5283 mp->sw_if_index = ntohl (sw_if_index);
5290 #define foreach_pbb_vtr_op \
5291 _("disable", L2_VTR_DISABLED) \
5292 _("pop", L2_VTR_POP_2) \
5293 _("push", L2_VTR_PUSH_2)
5297 api_sw_interface_tag_add_del (vat_main_t * vam)
5299 unformat_input_t *i = vam->input;
5300 vl_api_sw_interface_tag_add_del_t *mp;
5301 u32 sw_if_index = ~0;
5306 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5308 if (unformat (i, "tag %s", &tag))
5310 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5312 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5314 else if (unformat (i, "del"))
5320 if (sw_if_index == ~0)
5322 errmsg ("missing interface name or sw_if_index");
5326 if (enable && (tag == 0))
5328 errmsg ("no tag specified");
5332 /* Construct the API message */
5333 M (SW_INTERFACE_TAG_ADD_DEL, mp);
5334 mp->sw_if_index = ntohl (sw_if_index);
5335 mp->is_add = enable;
5337 strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
5346 api_sw_interface_add_del_mac_address (vat_main_t * vam)
5348 unformat_input_t *i = vam->input;
5349 vl_api_mac_address_t mac = { 0 };
5350 vl_api_sw_interface_add_del_mac_address_t *mp;
5351 u32 sw_if_index = ~0;
5356 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5358 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5360 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5362 else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
5364 else if (unformat (i, "del"))
5370 if (sw_if_index == ~0)
5372 errmsg ("missing interface name or sw_if_index");
5378 errmsg ("missing MAC address");
5382 /* Construct the API message */
5383 M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
5384 mp->sw_if_index = ntohl (sw_if_index);
5385 mp->is_add = is_add;
5386 clib_memcpy (&mp->addr, &mac, sizeof (mac));
5394 api_hw_interface_set_mtu (vat_main_t * vam)
5396 unformat_input_t *i = vam->input;
5397 vl_api_hw_interface_set_mtu_t *mp;
5398 u32 sw_if_index = ~0;
5402 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5404 if (unformat (i, "mtu %d", &mtu))
5406 if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5408 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5414 if (sw_if_index == ~0)
5416 errmsg ("missing interface name or sw_if_index");
5422 errmsg ("no mtu specified");
5426 /* Construct the API message */
5427 M (HW_INTERFACE_SET_MTU, mp);
5428 mp->sw_if_index = ntohl (sw_if_index);
5429 mp->mtu = ntohs ((u16) mtu);
5436 static void vl_api_app_namespace_add_del_reply_t_handler
5437 (vl_api_app_namespace_add_del_reply_t * mp)
5439 vat_main_t *vam = &vat_main;
5440 i32 retval = ntohl (mp->retval);
5441 if (vam->async_mode)
5443 vam->async_errors += (retval < 0);
5447 vam->retval = retval;
5449 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
5450 vam->result_ready = 1;
5454 static void vl_api_app_namespace_add_del_reply_t_handler_json
5455 (vl_api_app_namespace_add_del_reply_t * mp)
5457 vat_main_t *vam = &vat_main;
5458 vat_json_node_t node;
5460 vat_json_init_object (&node);
5461 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5462 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
5464 vat_json_print (vam->ofp, &node);
5465 vat_json_free (&node);
5467 vam->retval = ntohl (mp->retval);
5468 vam->result_ready = 1;
5472 api_app_namespace_add_del (vat_main_t * vam)
5474 vl_api_app_namespace_add_del_t *mp;
5475 unformat_input_t *i = vam->input;
5476 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
5477 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
5481 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5483 if (unformat (i, "id %_%v%_", &ns_id))
5485 else if (unformat (i, "secret %lu", &secret))
5487 else if (unformat (i, "sw_if_index %d", &sw_if_index))
5488 sw_if_index_set = 1;
5489 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
5491 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
5496 if (!ns_id || !secret_set || !sw_if_index_set)
5498 errmsg ("namespace id, secret and sw_if_index must be set");
5501 if (vec_len (ns_id) > 64)
5503 errmsg ("namespace id too long");
5506 M (APP_NAMESPACE_ADD_DEL, mp);
5508 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
5509 mp->secret = clib_host_to_net_u64 (secret);
5510 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
5511 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
5512 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
5520 api_sock_init_shm (vat_main_t * vam)
5522 #if VPP_API_TEST_BUILTIN == 0
5523 unformat_input_t *i = vam->input;
5524 vl_api_shm_elem_config_t *config = 0;
5525 u64 size = 64 << 20;
5528 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5530 if (unformat (i, "size %U", unformat_memory_size, &size))
5537 * Canned custom ring allocator config.
5538 * Should probably parse all of this
5540 vec_validate (config, 6);
5541 config[0].type = VL_API_VLIB_RING;
5542 config[0].size = 256;
5543 config[0].count = 32;
5545 config[1].type = VL_API_VLIB_RING;
5546 config[1].size = 1024;
5547 config[1].count = 16;
5549 config[2].type = VL_API_VLIB_RING;
5550 config[2].size = 4096;
5551 config[2].count = 2;
5553 config[3].type = VL_API_CLIENT_RING;
5554 config[3].size = 256;
5555 config[3].count = 32;
5557 config[4].type = VL_API_CLIENT_RING;
5558 config[4].size = 1024;
5559 config[4].count = 16;
5561 config[5].type = VL_API_CLIENT_RING;
5562 config[5].size = 4096;
5563 config[5].count = 2;
5565 config[6].type = VL_API_QUEUE;
5566 config[6].count = 128;
5567 config[6].size = sizeof (uword);
5569 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
5571 vam->client_index_invalid = 1;
5579 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
5581 vat_main_t *vam = &vat_main;
5582 fib_prefix_t lcl, rmt;
5584 ip_prefix_decode (&mp->lcl, &lcl);
5585 ip_prefix_decode (&mp->rmt, &rmt);
5587 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
5590 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
5591 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
5592 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
5593 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
5594 &rmt.fp_addr.ip4, rmt.fp_len,
5595 clib_net_to_host_u16 (mp->rmt_port),
5596 clib_net_to_host_u32 (mp->action_index), mp->tag);
5601 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
5602 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
5603 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
5604 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
5605 &rmt.fp_addr.ip6, rmt.fp_len,
5606 clib_net_to_host_u16 (mp->rmt_port),
5607 clib_net_to_host_u32 (mp->action_index), mp->tag);
5612 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
5615 vat_main_t *vam = &vat_main;
5616 vat_json_node_t *node = NULL;
5617 struct in6_addr ip6;
5620 fib_prefix_t lcl, rmt;
5622 ip_prefix_decode (&mp->lcl, &lcl);
5623 ip_prefix_decode (&mp->rmt, &rmt);
5625 if (VAT_JSON_ARRAY != vam->json_tree.type)
5627 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5628 vat_json_init_array (&vam->json_tree);
5630 node = vat_json_array_add (&vam->json_tree);
5631 vat_json_init_object (node);
5633 vat_json_object_add_uint (node, "appns_index",
5634 clib_net_to_host_u32 (mp->appns_index));
5635 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
5636 vat_json_object_add_uint (node, "scope", mp->scope);
5637 vat_json_object_add_uint (node, "action_index",
5638 clib_net_to_host_u32 (mp->action_index));
5639 vat_json_object_add_uint (node, "lcl_port",
5640 clib_net_to_host_u16 (mp->lcl_port));
5641 vat_json_object_add_uint (node, "rmt_port",
5642 clib_net_to_host_u16 (mp->rmt_port));
5643 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
5644 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
5645 vat_json_object_add_string_copy (node, "tag", mp->tag);
5646 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
5648 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
5649 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
5650 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
5651 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
5655 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
5656 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
5657 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
5658 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
5663 api_session_rule_add_del (vat_main_t * vam)
5665 vl_api_session_rule_add_del_t *mp;
5666 unformat_input_t *i = vam->input;
5667 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
5668 u32 appns_index = 0, scope = 0;
5669 ip4_address_t lcl_ip4, rmt_ip4;
5670 ip6_address_t lcl_ip6, rmt_ip6;
5671 u8 is_ip4 = 1, conn_set = 0;
5672 u8 is_add = 1, *tag = 0;
5674 fib_prefix_t lcl, rmt;
5676 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678 if (unformat (i, "del"))
5680 else if (unformat (i, "add"))
5682 else if (unformat (i, "proto tcp"))
5684 else if (unformat (i, "proto udp"))
5686 else if (unformat (i, "appns %d", &appns_index))
5688 else if (unformat (i, "scope %d", &scope))
5690 else if (unformat (i, "tag %_%v%_", &tag))
5694 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
5695 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
5703 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
5704 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
5710 else if (unformat (i, "action %d", &action))
5715 if (proto == ~0 || !conn_set || action == ~0)
5717 errmsg ("transport proto, connection and action must be set");
5723 errmsg ("scope should be 0-3");
5727 M (SESSION_RULE_ADD_DEL, mp);
5729 clib_memset (&lcl, 0, sizeof (lcl));
5730 clib_memset (&rmt, 0, sizeof (rmt));
5733 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
5734 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
5735 lcl.fp_len = lcl_plen;
5736 rmt.fp_len = rmt_plen;
5740 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
5741 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
5742 lcl.fp_len = lcl_plen;
5743 rmt.fp_len = rmt_plen;
5747 ip_prefix_encode (&lcl, &mp->lcl);
5748 ip_prefix_encode (&rmt, &mp->rmt);
5749 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
5750 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
5751 mp->transport_proto =
5752 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
5753 mp->action_index = clib_host_to_net_u32 (action);
5754 mp->appns_index = clib_host_to_net_u32 (appns_index);
5756 mp->is_add = is_add;
5759 clib_memcpy (mp->tag, tag, vec_len (tag));
5769 api_session_rules_dump (vat_main_t * vam)
5771 vl_api_session_rules_dump_t *mp;
5772 vl_api_control_ping_t *mp_ping;
5775 if (!vam->json_output)
5777 print (vam->ofp, "%=20s", "Session Rules");
5780 M (SESSION_RULES_DUMP, mp);
5784 /* Use a control ping for synchronization */
5785 MPING (CONTROL_PING, mp_ping);
5788 /* Wait for a reply... */
5794 api_ip_container_proxy_add_del (vat_main_t * vam)
5796 vl_api_ip_container_proxy_add_del_t *mp;
5797 unformat_input_t *i = vam->input;
5798 u32 sw_if_index = ~0;
5799 vl_api_prefix_t pfx = { };
5803 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5805 if (unformat (i, "del"))
5807 else if (unformat (i, "add"))
5809 if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
5811 else if (unformat (i, "sw_if_index %u", &sw_if_index))
5816 if (sw_if_index == ~0 || pfx.len == 0)
5818 errmsg ("address and sw_if_index must be set");
5822 M (IP_CONTAINER_PROXY_ADD_DEL, mp);
5824 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
5825 mp->is_add = is_add;
5826 clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
5834 q_or_quit (vat_main_t * vam)
5836 #if VPP_API_TEST_BUILTIN == 0
5837 longjmp (vam->jump_buf, 1);
5839 return 0; /* not so much */
5843 q (vat_main_t * vam)
5845 return q_or_quit (vam);
5849 quit (vat_main_t * vam)
5851 return q_or_quit (vam);
5855 comment (vat_main_t * vam)
5861 elog_save (vat_main_t * vam)
5863 #if VPP_API_TEST_BUILTIN == 0
5864 elog_main_t *em = &vam->elog_main;
5865 unformat_input_t *i = vam->input;
5866 char *file, *chroot_file;
5867 clib_error_t *error;
5869 if (!unformat (i, "%s", &file))
5871 errmsg ("expected file name, got `%U'", format_unformat_error, i);
5875 /* It's fairly hard to get "../oopsie" through unformat; just in case */
5876 if (strstr (file, "..") || index (file, '/'))
5878 errmsg ("illegal characters in filename '%s'", file);
5882 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
5886 errmsg ("Saving %wd of %wd events to %s",
5887 elog_n_events_in_buffer (em),
5888 elog_buffer_capacity (em), chroot_file);
5890 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
5891 vec_free (chroot_file);
5894 clib_error_report (error);
5896 errmsg ("Use the vpp event loger...");
5903 elog_setup (vat_main_t * vam)
5905 #if VPP_API_TEST_BUILTIN == 0
5906 elog_main_t *em = &vam->elog_main;
5907 unformat_input_t *i = vam->input;
5908 u32 nevents = 128 << 10;
5910 (void) unformat (i, "nevents %d", &nevents);
5912 elog_init (em, nevents);
5913 vl_api_set_elog_main (em);
5914 vl_api_set_elog_trace_api_messages (1);
5915 errmsg ("Event logger initialized with %u events", nevents);
5917 errmsg ("Use the vpp event loger...");
5923 elog_enable (vat_main_t * vam)
5925 #if VPP_API_TEST_BUILTIN == 0
5926 elog_main_t *em = &vam->elog_main;
5928 elog_enable_disable (em, 1 /* enable */ );
5929 vl_api_set_elog_trace_api_messages (1);
5930 errmsg ("Event logger enabled...");
5932 errmsg ("Use the vpp event loger...");
5938 elog_disable (vat_main_t * vam)
5940 #if VPP_API_TEST_BUILTIN == 0
5941 elog_main_t *em = &vam->elog_main;
5943 elog_enable_disable (em, 0 /* enable */ );
5944 vl_api_set_elog_trace_api_messages (1);
5945 errmsg ("Event logger disabled...");
5947 errmsg ("Use the vpp event loger...");
5953 statseg (vat_main_t * vam)
5955 ssvm_private_t *ssvmp = &vam->stat_segment;
5956 ssvm_shared_header_t *shared_header = ssvmp->sh;
5957 vlib_counter_t **counters;
5958 u64 thread0_index1_packets;
5959 u64 thread0_index1_bytes;
5960 f64 vector_rate, input_rate;
5963 uword *counter_vector_by_name;
5964 if (vam->stat_segment_lockp == 0)
5966 errmsg ("Stat segment not mapped...");
5970 /* look up "/if/rx for sw_if_index 1 as a test */
5972 clib_spinlock_lock (vam->stat_segment_lockp);
5974 counter_vector_by_name = (uword *) shared_header->opaque[1];
5976 p = hash_get_mem (counter_vector_by_name, "/if/rx");
5979 clib_spinlock_unlock (vam->stat_segment_lockp);
5980 errmsg ("/if/tx not found?");
5984 /* Fish per-thread vector of combined counters from shared memory */
5985 counters = (vlib_counter_t **) p[0];
5987 if (vec_len (counters[0]) < 2)
5989 clib_spinlock_unlock (vam->stat_segment_lockp);
5990 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
5994 /* Read thread 0 sw_if_index 1 counter */
5995 thread0_index1_packets = counters[0][1].packets;
5996 thread0_index1_bytes = counters[0][1].bytes;
5998 p = hash_get_mem (counter_vector_by_name, "vector_rate");
6001 clib_spinlock_unlock (vam->stat_segment_lockp);
6002 errmsg ("vector_rate not found?");
6006 vector_rate = *(f64 *) (p[0]);
6007 p = hash_get_mem (counter_vector_by_name, "input_rate");
6010 clib_spinlock_unlock (vam->stat_segment_lockp);
6011 errmsg ("input_rate not found?");
6014 input_rate = *(f64 *) (p[0]);
6016 clib_spinlock_unlock (vam->stat_segment_lockp);
6018 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
6019 vector_rate, input_rate);
6020 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
6021 thread0_index1_packets, thread0_index1_bytes);
6027 cmd_cmp (void *a1, void *a2)
6032 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
6036 help (vat_main_t * vam)
6041 unformat_input_t *i = vam->input;
6044 if (unformat (i, "%s", &name))
6050 hs = hash_get_mem (vam->help_by_name, name);
6052 print (vam->ofp, "usage: %s %s", name, hs[0]);
6054 print (vam->ofp, "No such msg / command '%s'", name);
6059 print (vam->ofp, "Help is available for the following:");
6062 hash_foreach_pair (p, vam->function_by_name,
6064 vec_add1 (cmds, (u8 *)(p->key));
6068 vec_sort_with_function (cmds, cmd_cmp);
6070 for (j = 0; j < vec_len (cmds); j++)
6071 print (vam->ofp, "%s", cmds[j]);
6078 set (vat_main_t * vam)
6080 u8 *name = 0, *value = 0;
6081 unformat_input_t *i = vam->input;
6083 if (unformat (i, "%s", &name))
6085 /* The input buffer is a vector, not a string. */
6086 value = vec_dup (i->buffer);
6087 vec_delete (value, i->index, 0);
6088 /* Almost certainly has a trailing newline */
6089 if (value[vec_len (value) - 1] == '\n')
6090 value[vec_len (value) - 1] = 0;
6091 /* Make sure it's a proper string, one way or the other */
6092 vec_add1 (value, 0);
6093 (void) clib_macro_set_value (&vam->macro_main,
6094 (char *) name, (char *) value);
6097 errmsg ("usage: set <name> <value>");
6105 unset (vat_main_t * vam)
6109 if (unformat (vam->input, "%s", &name))
6110 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
6111 errmsg ("unset: %s wasn't set", name);
6124 macro_sort_cmp (void *a1, void *a2)
6126 macro_sort_t *s1 = a1;
6127 macro_sort_t *s2 = a2;
6129 return strcmp ((char *) (s1->name), (char *) (s2->name));
6133 dump_macro_table (vat_main_t * vam)
6135 macro_sort_t *sort_me = 0, *sm;
6140 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
6142 vec_add2 (sort_me, sm, 1);
6143 sm->name = (u8 *)(p->key);
6144 sm->value = (u8 *) (p->value[0]);
6148 vec_sort_with_function (sort_me, macro_sort_cmp);
6150 if (vec_len (sort_me))
6151 print (vam->ofp, "%-15s%s", "Name", "Value");
6153 print (vam->ofp, "The macro table is empty...");
6155 for (i = 0; i < vec_len (sort_me); i++)
6156 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
6161 dump_node_table (vat_main_t * vam)
6164 vlib_node_t *node, *next_node;
6166 if (vec_len (vam->graph_nodes) == 0)
6168 print (vam->ofp, "Node table empty, issue get_node_graph...");
6172 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
6174 node = vam->graph_nodes[0][i];
6175 print (vam->ofp, "[%d] %s", i, node->name);
6176 for (j = 0; j < vec_len (node->next_nodes); j++)
6178 if (node->next_nodes[j] != ~0)
6180 next_node = vam->graph_nodes[0][node->next_nodes[j]];
6181 print (vam->ofp, " [%d] %s", j, next_node->name);
6189 value_sort_cmp (void *a1, void *a2)
6191 name_sort_t *n1 = a1;
6192 name_sort_t *n2 = a2;
6194 if (n1->value < n2->value)
6196 if (n1->value > n2->value)
6203 dump_msg_api_table (vat_main_t * vam)
6205 api_main_t *am = vlibapi_get_main ();
6206 name_sort_t *nses = 0, *ns;
6211 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
6213 vec_add2 (nses, ns, 1);
6214 ns->name = (u8 *)(hp->key);
6215 ns->value = (u32) hp->value[0];
6219 vec_sort_with_function (nses, value_sort_cmp);
6221 for (i = 0; i < vec_len (nses); i++)
6222 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
6228 get_msg_id (vat_main_t * vam)
6233 if (unformat (vam->input, "%s", &name_and_crc))
6235 message_index = vl_msg_api_get_msg_index (name_and_crc);
6236 if (message_index == ~0)
6238 print (vam->ofp, " '%s' not found", name_and_crc);
6241 print (vam->ofp, " '%s' has message index %d",
6242 name_and_crc, message_index);
6245 errmsg ("name_and_crc required...");
6250 search_node_table (vat_main_t * vam)
6252 unformat_input_t *line_input = vam->input;
6255 vlib_node_t *node, *next_node;
6258 if (vam->graph_node_index_by_name == 0)
6260 print (vam->ofp, "Node table empty, issue get_node_graph...");
6264 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
6266 if (unformat (line_input, "%s", &node_to_find))
6268 vec_add1 (node_to_find, 0);
6269 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
6272 print (vam->ofp, "%s not found...", node_to_find);
6275 node = vam->graph_nodes[0][p[0]];
6276 print (vam->ofp, "[%d] %s", p[0], node->name);
6277 for (j = 0; j < vec_len (node->next_nodes); j++)
6279 if (node->next_nodes[j] != ~0)
6281 next_node = vam->graph_nodes[0][node->next_nodes[j]];
6282 print (vam->ofp, " [%d] %s", j, next_node->name);
6289 clib_warning ("parse error '%U'", format_unformat_error,
6295 vec_free (node_to_find);
6304 script (vat_main_t * vam)
6306 #if (VPP_API_TEST_BUILTIN==0)
6308 char *save_current_file;
6309 unformat_input_t save_input;
6310 jmp_buf save_jump_buf;
6311 u32 save_line_number;
6313 FILE *new_fp, *save_ifp;
6315 if (unformat (vam->input, "%s", &s))
6317 new_fp = fopen ((char *) s, "r");
6320 errmsg ("Couldn't open script file %s", s);
6327 errmsg ("Missing script name");
6331 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
6332 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
6333 save_ifp = vam->ifp;
6334 save_line_number = vam->input_line_number;
6335 save_current_file = (char *) vam->current_file;
6337 vam->input_line_number = 0;
6339 vam->current_file = s;
6342 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
6343 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
6344 vam->ifp = save_ifp;
6345 vam->input_line_number = save_line_number;
6346 vam->current_file = (u8 *) save_current_file;
6351 clib_warning ("use the exec command...");
6357 echo (vat_main_t * vam)
6359 print (vam->ofp, "%v", vam->input->buffer);
6363 /* List of API message constructors, CLI names map to api_xxx */
6364 #define foreach_vpe_api_msg \
6365 _(create_loopback,"[mac <mac-addr>] [instance <instance>]") \
6366 _(sw_interface_dump,"") \
6367 _(sw_interface_set_flags, \
6368 "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
6369 _(sw_interface_add_del_address, \
6370 "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
6371 _(sw_interface_set_rx_placement, \
6372 "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]") \
6373 _(sw_interface_rx_placement_dump, \
6374 "[<intfc> | sw_if_index <id>]") \
6375 _(sw_interface_set_table, \
6376 "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]") \
6377 _(ip_table_add_del, \
6378 "table <n> [ipv6] [add | del]\n") \
6379 _(ip_route_add_del, \
6380 "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
6381 "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
6382 "[weight <n>] [drop] [local] [classify <n>] [out-label <n>]\n" \
6383 "[multipath] [count <n>] [del]") \
6384 _(ip_mroute_add_del, \
6385 "<src> <grp>/<mask> [table-id <n>]\n" \
6386 "[<intfc> | sw_if_index <id>] [local] [del]") \
6387 _(sw_interface_set_unnumbered, \
6388 "<intfc> | sw_if_index <id> unnum_if_index <id> [del]") \
6389 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>") \
6390 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n" \
6391 "[outer_vlan_id <n>][inner_vlan_id <n>]\n" \
6392 "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n" \
6393 "[outer_vlan_id_any][inner_vlan_id_any]") \
6394 _(ip_table_replace_begin, "table <n> [ipv6]") \
6395 _(ip_table_flush, "table <n> [ipv6]") \
6396 _(ip_table_replace_end, "table <n> [ipv6]") \
6397 _(set_ip_flow_hash, \
6398 "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]") \
6399 _(sw_interface_ip6_enable_disable, \
6400 "<intfc> | sw_if_index <id> enable | disable") \
6401 _(get_node_index, "node <node-name") \
6402 _(add_node_next, "node <node-name> next <next-node-name>") \
6403 _(show_version, "") \
6404 _(show_threads, "") \
6405 _(interface_name_renumber, \
6406 "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>") \
6407 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)") \
6408 _(ip_dump, "ipv4 | ipv6") \
6409 _(delete_loopback,"sw_if_index <nn>") \
6410 _(want_interface_events, "enable|disable") \
6411 _(get_first_msg_id, "client <name>") \
6412 _(get_node_graph, " ") \
6413 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>") \
6414 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]") \
6415 _(ioam_disable, "") \
6416 _(get_next_index, "node-name <node-name> next-node-name <node-name>") \
6417 _(ip_source_and_port_range_check_add_del, \
6418 "<ip-addr>/<mask> range <nn>-<nn> vrf <id>") \
6419 _(ip_source_and_port_range_check_interface_add_del, \
6420 "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]" \
6421 "[udp-in-vrf <id>] [udp-out-vrf <id>]") \
6422 _(delete_subif,"<intfc> | sw_if_index <nn>") \
6423 _(ip_table_dump, "") \
6424 _(ip_route_dump, "table-id [ip4|ip6]") \
6425 _(ip_mtable_dump, "") \
6426 _(ip_mroute_dump, "table-id [ip4|ip6]") \
6427 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>" \
6429 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> " \
6430 "mac <mac-address> [del]") \
6431 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>") \
6432 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]") \
6433 _(sock_init_shm, "size <nnn>") \
6434 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
6435 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
6436 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
6437 _(session_rules_dump, "") \
6438 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>") \
6440 /* List of command functions, CLI names map directly to functions */
6441 #define foreach_cli_function \
6442 _(comment, "usage: comment <ignore-rest-of-line>") \
6443 _(dump_interface_table, "usage: dump_interface_table") \
6444 _(dump_sub_interface_table, "usage: dump_sub_interface_table") \
6445 _(dump_ipv4_table, "usage: dump_ipv4_table") \
6446 _(dump_ipv6_table, "usage: dump_ipv6_table") \
6447 _(dump_macro_table, "usage: dump_macro_table ") \
6448 _(dump_node_table, "usage: dump_node_table") \
6449 _(dump_msg_api_table, "usage: dump_msg_api_table") \
6450 _(elog_setup, "usage: elog_setup [nevents, default 128K]") \
6451 _(elog_disable, "usage: elog_disable") \
6452 _(elog_enable, "usage: elog_enable") \
6453 _(elog_save, "usage: elog_save <filename>") \
6454 _(get_msg_id, "usage: get_msg_id name_and_crc") \
6455 _(echo, "usage: echo <message>") \
6456 _(exec, "usage: exec <vpe-debug-CLI-command>") \
6457 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
6458 _(help, "usage: help") \
6459 _(q, "usage: quit") \
6460 _(quit, "usage: quit") \
6461 _(search_node_table, "usage: search_node_table <name>...") \
6462 _(set, "usage: set <variable-name> <value>") \
6463 _(script, "usage: script <file-name>") \
6464 _(statseg, "usage: statseg") \
6465 _(unset, "usage: unset <variable-name>")
6468 static void vl_api_##n##_t_handler_uni \
6469 (vl_api_##n##_t * mp) \
6471 vat_main_t * vam = &vat_main; \
6472 if (vam->json_output) { \
6473 vl_api_##n##_t_handler_json(mp); \
6475 vl_api_##n##_t_handler(mp); \
6478 foreach_vpe_api_reply_msg;
6479 #if VPP_API_TEST_BUILTIN == 0
6480 foreach_standalone_reply_msg;
6485 vat_api_hookup (vat_main_t * vam)
6488 vl_msg_api_set_handlers(VL_API_##N, #n, \
6489 vl_api_##n##_t_handler_uni, \
6491 vl_api_##n##_t_endian, \
6492 vl_api_##n##_t_print, \
6493 sizeof(vl_api_##n##_t), 1);
6494 foreach_vpe_api_reply_msg;
6495 #if VPP_API_TEST_BUILTIN == 0
6496 foreach_standalone_reply_msg;
6500 #if (VPP_API_TEST_BUILTIN==0)
6501 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
6503 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6505 vam->function_by_name = hash_create_string (0, sizeof (uword));
6507 vam->help_by_name = hash_create_string (0, sizeof (uword));
6510 /* API messages we can send */
6511 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
6512 foreach_vpe_api_msg;
6516 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
6517 foreach_vpe_api_msg;
6521 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
6522 foreach_cli_function;
6526 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
6527 foreach_cli_function;
6531 #if VPP_API_TEST_BUILTIN
6532 static clib_error_t *
6533 vat_api_hookup_shim (vlib_main_t * vm)
6535 vat_api_hookup (&vat_main);
6539 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
6543 * fd.io coding-style-patch-verification: ON
6546 * eval: (c-set-style "gnu")