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 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
575 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
577 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
578 sizeof (ip6_address_t));
583 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
585 vat_main_t *vam = &vat_main;
586 i32 retval = ntohl (mp->retval);
588 vam->retval = retval;
589 vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
590 vam->result_ready = 1;
594 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
596 vat_main_t *vam = &vat_main;
597 vat_json_node_t node;
601 vat_json_init_object (&node);
602 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
603 vat_json_object_add_uint (&node, "reply_in_shmem",
604 ntohl (mp->reply_in_shmem));
605 /* Toss the shared-memory original... */
606 oldheap = vl_msg_push_heap ();
608 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
611 vl_msg_pop_heap (oldheap);
613 vat_json_print (vam->ofp, &node);
614 vat_json_free (&node);
616 vam->retval = ntohl (mp->retval);
617 vam->result_ready = 1;
621 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
623 vat_main_t *vam = &vat_main;
624 i32 retval = ntohl (mp->retval);
626 vec_reset_length (vam->cmd_reply);
628 vam->retval = retval;
630 vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
631 vam->result_ready = 1;
635 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
637 vat_main_t *vam = &vat_main;
638 vat_json_node_t node;
639 u8 *reply = 0; /* reply vector */
641 reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
642 vec_reset_length (vam->cmd_reply);
644 vat_json_init_object (&node);
645 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
646 vat_json_object_add_string_copy (&node, "reply", reply);
648 vat_json_print (vam->ofp, &node);
649 vat_json_free (&node);
652 vam->retval = ntohl (mp->retval);
653 vam->result_ready = 1;
656 static void vl_api_get_node_index_reply_t_handler
657 (vl_api_get_node_index_reply_t * mp)
659 vat_main_t *vam = &vat_main;
660 i32 retval = ntohl (mp->retval);
663 vam->async_errors += (retval < 0);
667 vam->retval = retval;
669 errmsg ("node index %d", ntohl (mp->node_index));
670 vam->result_ready = 1;
674 static void vl_api_get_node_index_reply_t_handler_json
675 (vl_api_get_node_index_reply_t * mp)
677 vat_main_t *vam = &vat_main;
678 vat_json_node_t node;
680 vat_json_init_object (&node);
681 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
682 vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
684 vat_json_print (vam->ofp, &node);
685 vat_json_free (&node);
687 vam->retval = ntohl (mp->retval);
688 vam->result_ready = 1;
691 static void vl_api_get_next_index_reply_t_handler
692 (vl_api_get_next_index_reply_t * mp)
694 vat_main_t *vam = &vat_main;
695 i32 retval = ntohl (mp->retval);
698 vam->async_errors += (retval < 0);
702 vam->retval = retval;
704 errmsg ("next node index %d", ntohl (mp->next_index));
705 vam->result_ready = 1;
709 static void vl_api_get_next_index_reply_t_handler_json
710 (vl_api_get_next_index_reply_t * mp)
712 vat_main_t *vam = &vat_main;
713 vat_json_node_t node;
715 vat_json_init_object (&node);
716 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
717 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
719 vat_json_print (vam->ofp, &node);
720 vat_json_free (&node);
722 vam->retval = ntohl (mp->retval);
723 vam->result_ready = 1;
726 static void vl_api_add_node_next_reply_t_handler
727 (vl_api_add_node_next_reply_t * mp)
729 vat_main_t *vam = &vat_main;
730 i32 retval = ntohl (mp->retval);
733 vam->async_errors += (retval < 0);
737 vam->retval = retval;
739 errmsg ("next index %d", ntohl (mp->next_index));
740 vam->result_ready = 1;
744 static void vl_api_add_node_next_reply_t_handler_json
745 (vl_api_add_node_next_reply_t * mp)
747 vat_main_t *vam = &vat_main;
748 vat_json_node_t node;
750 vat_json_init_object (&node);
751 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
752 vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
754 vat_json_print (vam->ofp, &node);
755 vat_json_free (&node);
757 vam->retval = ntohl (mp->retval);
758 vam->result_ready = 1;
761 static void vl_api_show_version_reply_t_handler
762 (vl_api_show_version_reply_t * mp)
764 vat_main_t *vam = &vat_main;
765 i32 retval = ntohl (mp->retval);
769 errmsg (" program: %s", mp->program);
770 errmsg (" version: %s", mp->version);
771 errmsg (" build date: %s", mp->build_date);
772 errmsg ("build directory: %s", mp->build_directory);
774 vam->retval = retval;
775 vam->result_ready = 1;
778 static void vl_api_show_version_reply_t_handler_json
779 (vl_api_show_version_reply_t * mp)
781 vat_main_t *vam = &vat_main;
782 vat_json_node_t node;
784 vat_json_init_object (&node);
785 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
786 vat_json_object_add_string_copy (&node, "program", mp->program);
787 vat_json_object_add_string_copy (&node, "version", mp->version);
788 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
789 vat_json_object_add_string_copy (&node, "build_directory",
790 mp->build_directory);
792 vat_json_print (vam->ofp, &node);
793 vat_json_free (&node);
795 vam->retval = ntohl (mp->retval);
796 vam->result_ready = 1;
799 static void vl_api_show_threads_reply_t_handler
800 (vl_api_show_threads_reply_t * mp)
802 vat_main_t *vam = &vat_main;
803 i32 retval = ntohl (mp->retval);
807 count = ntohl (mp->count);
809 for (i = 0; i < count; i++)
811 "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
812 ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
813 mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
814 ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
815 ntohl (mp->thread_data[i].cpu_socket));
817 vam->retval = retval;
818 vam->result_ready = 1;
821 static void vl_api_show_threads_reply_t_handler_json
822 (vl_api_show_threads_reply_t * mp)
824 vat_main_t *vam = &vat_main;
825 vat_json_node_t node;
826 vl_api_thread_data_t *td;
827 i32 retval = ntohl (mp->retval);
831 count = ntohl (mp->count);
833 vat_json_init_object (&node);
834 vat_json_object_add_int (&node, "retval", retval);
835 vat_json_object_add_uint (&node, "count", count);
837 for (i = 0; i < count; i++)
839 td = &mp->thread_data[i];
840 vat_json_object_add_uint (&node, "id", ntohl (td->id));
841 vat_json_object_add_string_copy (&node, "name", td->name);
842 vat_json_object_add_string_copy (&node, "type", td->type);
843 vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
844 vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
845 vat_json_object_add_int (&node, "core", ntohl (td->id));
846 vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
849 vat_json_print (vam->ofp, &node);
850 vat_json_free (&node);
852 vam->retval = retval;
853 vam->result_ready = 1;
857 api_show_threads (vat_main_t * vam)
859 vl_api_show_threads_t *mp;
863 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
864 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
866 M (SHOW_THREADS, mp);
873 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
874 #define vl_api_bridge_domain_details_t_print vl_noop_handler
876 static void vl_api_control_ping_reply_t_handler
877 (vl_api_control_ping_reply_t * mp)
879 vat_main_t *vam = &vat_main;
880 i32 retval = ntohl (mp->retval);
883 vam->async_errors += (retval < 0);
887 vam->retval = retval;
888 vam->result_ready = 1;
890 if (vam->socket_client_main)
891 vam->socket_client_main->control_pings_outstanding--;
894 static void vl_api_control_ping_reply_t_handler_json
895 (vl_api_control_ping_reply_t * mp)
897 vat_main_t *vam = &vat_main;
898 i32 retval = ntohl (mp->retval);
900 if (VAT_JSON_NONE != vam->json_tree.type)
902 vat_json_print (vam->ofp, &vam->json_tree);
903 vat_json_free (&vam->json_tree);
904 vam->json_tree.type = VAT_JSON_NONE;
909 vat_json_init_array (&vam->json_tree);
910 vat_json_print (vam->ofp, &vam->json_tree);
911 vam->json_tree.type = VAT_JSON_NONE;
914 vam->retval = retval;
915 vam->result_ready = 1;
919 static void vl_api_get_first_msg_id_reply_t_handler
920 (vl_api_get_first_msg_id_reply_t * mp)
922 vat_main_t *vam = &vat_main;
923 i32 retval = ntohl (mp->retval);
927 vam->async_errors += (retval < 0);
931 vam->retval = retval;
932 vam->result_ready = 1;
936 errmsg ("first message id %d", ntohs (mp->first_msg_id));
940 static void vl_api_get_first_msg_id_reply_t_handler_json
941 (vl_api_get_first_msg_id_reply_t * mp)
943 vat_main_t *vam = &vat_main;
944 vat_json_node_t node;
946 vat_json_init_object (&node);
947 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948 vat_json_object_add_uint (&node, "first_msg_id",
949 (uint) ntohs (mp->first_msg_id));
951 vat_json_print (vam->ofp, &node);
952 vat_json_free (&node);
954 vam->retval = ntohl (mp->retval);
955 vam->result_ready = 1;
958 static void vl_api_get_node_graph_reply_t_handler
959 (vl_api_get_node_graph_reply_t * mp)
961 vat_main_t *vam = &vat_main;
962 i32 retval = ntohl (mp->retval);
963 u8 *pvt_copy, *reply;
970 vam->async_errors += (retval < 0);
974 vam->retval = retval;
975 vam->result_ready = 1;
978 /* "Should never happen..." */
982 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
983 pvt_copy = vec_dup (reply);
985 /* Toss the shared-memory original... */
986 oldheap = vl_msg_push_heap ();
990 vl_msg_pop_heap (oldheap);
992 if (vam->graph_nodes)
994 hash_free (vam->graph_node_index_by_name);
996 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
998 node = vam->graph_nodes[0][i];
999 vec_free (node->name);
1000 vec_free (node->next_nodes);
1003 vec_free (vam->graph_nodes[0]);
1004 vec_free (vam->graph_nodes);
1007 vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
1008 vam->graph_nodes = vlib_node_unserialize (pvt_copy);
1009 vec_free (pvt_copy);
1011 for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
1013 node = vam->graph_nodes[0][i];
1014 hash_set_mem (vam->graph_node_index_by_name, node->name, i);
1018 static void vl_api_get_node_graph_reply_t_handler_json
1019 (vl_api_get_node_graph_reply_t * mp)
1021 vat_main_t *vam = &vat_main;
1023 vat_json_node_t node;
1026 /* $$$$ make this real? */
1027 vat_json_init_object (&node);
1028 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1029 vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
1031 reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1033 /* Toss the shared-memory original... */
1034 oldheap = vl_msg_push_heap ();
1038 vl_msg_pop_heap (oldheap);
1040 vat_json_print (vam->ofp, &node);
1041 vat_json_free (&node);
1043 vam->retval = ntohl (mp->retval);
1044 vam->result_ready = 1;
1047 /* Format hex dump. */
1049 format_hex_bytes (u8 * s, va_list * va)
1051 u8 *bytes = va_arg (*va, u8 *);
1052 int n_bytes = va_arg (*va, int);
1055 /* Print short or long form depending on byte count. */
1056 uword short_form = n_bytes <= 32;
1057 u32 indent = format_get_indent (s);
1062 for (i = 0; i < n_bytes; i++)
1064 if (!short_form && (i % 32) == 0)
1065 s = format (s, "%08x: ", i);
1066 s = format (s, "%02x", bytes[i]);
1067 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
1068 s = format (s, "\n%U", format_white_space, indent);
1075 * Generate boilerplate reply handlers, which
1076 * dig the return value out of the xxx_reply_t API message,
1077 * stick it into vam->retval, and set vam->result_ready
1079 * Could also do this by pointing N message decode slots at
1080 * a single function, but that could break in subtle ways.
1083 #define foreach_standard_reply_retval_handler
1086 static void vl_api_##n##_t_handler \
1087 (vl_api_##n##_t * mp) \
1089 vat_main_t * vam = &vat_main; \
1090 i32 retval = ntohl(mp->retval); \
1091 if (vam->async_mode) { \
1092 vam->async_errors += (retval < 0); \
1094 vam->retval = retval; \
1095 vam->result_ready = 1; \
1098 foreach_standard_reply_retval_handler;
1102 static void vl_api_##n##_t_handler_json \
1103 (vl_api_##n##_t * mp) \
1105 vat_main_t * vam = &vat_main; \
1106 vat_json_node_t node; \
1107 vat_json_init_object(&node); \
1108 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
1109 vat_json_print(vam->ofp, &node); \
1110 vam->retval = ntohl(mp->retval); \
1111 vam->result_ready = 1; \
1113 foreach_standard_reply_retval_handler;
1117 * Table of message reply handlers, must include boilerplate handlers
1121 #define foreach_vpe_api_reply_msg \
1122 _ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
1123 _ (GET_NODE_GRAPH_REPLY, get_node_graph_reply) \
1124 _ (CONTROL_PING_REPLY, control_ping_reply) \
1125 _ (CLI_REPLY, cli_reply) \
1126 _ (CLI_INBAND_REPLY, cli_inband_reply) \
1127 _ (GET_NODE_INDEX_REPLY, get_node_index_reply) \
1128 _ (GET_NEXT_INDEX_REPLY, get_next_index_reply) \
1129 _ (ADD_NODE_NEXT_REPLY, add_node_next_reply) \
1130 _ (SHOW_VERSION_REPLY, show_version_reply) \
1131 _ (SHOW_THREADS_REPLY, show_threads_reply) \
1133 #define foreach_standalone_reply_msg \
1141 #define STR_VTR_OP_CASE(op) \
1142 case L2_VTR_ ## op: \
1146 * Pass CLI buffers directly in the CLI_INBAND API message,
1147 * instead of an additional shared memory area.
1150 exec_inband (vat_main_t * vam)
1152 vl_api_cli_inband_t *mp;
1153 unformat_input_t *i = vam->input;
1156 if (vec_len (i->buffer) == 0)
1159 if (vam->exec_mode == 0 && unformat (i, "mode"))
1164 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
1171 * In order for the CLI command to work, it
1172 * must be a vector ending in \n, not a C-string ending
1175 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
1176 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
1180 /* json responses may or may not include a useful reply... */
1181 if (vec_len (vam->cmd_reply))
1182 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
1187 exec (vat_main_t *vam)
1189 return exec_inband (vam);
1193 api_sw_interface_dump (vat_main_t *vam)
1199 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
1201 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
1204 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
1207 addr->domain = x[0];
1210 addr->function = x[3];
1216 unformat_fib_path (unformat_input_t *input, va_list *args)
1218 vat_main_t *vam = va_arg (*args, vat_main_t *);
1219 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
1220 u32 weight, preference;
1221 mpls_label_t out_label;
1223 clib_memset (path, 0, sizeof (*path));
1225 path->sw_if_index = ~0;
1229 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1231 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
1232 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
1233 &path->sw_if_index))
1235 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1237 else if (unformat (input, "%U %U",
1238 unformat_vl_api_ip6_address,
1239 &path->nh.address.ip6,
1240 api_unformat_sw_if_index, vam, &path->sw_if_index))
1242 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1244 else if (unformat (input, "weight %u", &weight))
1246 path->weight = weight;
1248 else if (unformat (input, "preference %u", &preference))
1250 path->preference = preference;
1252 else if (unformat (input, "%U next-hop-table %d",
1253 unformat_vl_api_ip4_address,
1254 &path->nh.address.ip4, &path->table_id))
1256 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1258 else if (unformat (input, "%U next-hop-table %d",
1259 unformat_vl_api_ip6_address,
1260 &path->nh.address.ip6, &path->table_id))
1262 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1264 else if (unformat (input, "%U",
1265 unformat_vl_api_ip4_address, &path->nh.address.ip4))
1268 * the recursive next-hops are by default in the default table
1271 path->sw_if_index = ~0;
1272 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1274 else if (unformat (input, "%U",
1275 unformat_vl_api_ip6_address, &path->nh.address.ip6))
1278 * the recursive next-hops are by default in the default table
1281 path->sw_if_index = ~0;
1282 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1284 else if (unformat (input, "resolve-via-host"))
1286 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
1288 else if (unformat (input, "resolve-via-attached"))
1290 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
1292 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
1294 path->type = FIB_API_PATH_TYPE_LOCAL;
1295 path->sw_if_index = ~0;
1296 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1298 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
1300 path->type = FIB_API_PATH_TYPE_LOCAL;
1301 path->sw_if_index = ~0;
1302 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1304 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
1306 else if (unformat (input, "via-label %d", &path->nh.via_label))
1308 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
1309 path->sw_if_index = ~0;
1311 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
1313 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
1314 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
1316 else if (unformat (input, "local"))
1318 path->type = FIB_API_PATH_TYPE_LOCAL;
1320 else if (unformat (input, "out-labels"))
1322 while (unformat (input, "%d", &out_label))
1324 path->label_stack[path->n_labels].label = out_label;
1325 path->label_stack[path->n_labels].is_uniform = 0;
1326 path->label_stack[path->n_labels].ttl = 64;
1330 else if (unformat (input, "via"))
1332 /* new path, back up and return */
1333 unformat_put_input (input);
1334 unformat_put_input (input);
1335 unformat_put_input (input);
1336 unformat_put_input (input);
1345 path->proto = ntohl (path->proto);
1346 path->type = ntohl (path->type);
1347 path->flags = ntohl (path->flags);
1348 path->table_id = ntohl (path->table_id);
1349 path->sw_if_index = ntohl (path->sw_if_index);
1354 #define foreach_create_subif_bit \
1361 _(outer_vlan_id_any) \
1362 _(inner_vlan_id_any)
1364 #define foreach_create_subif_flag \
1369 _(4, "exact_match") \
1370 _(5, "default_sub") \
1371 _(6, "outer_vlan_id_any") \
1372 _(7, "inner_vlan_id_any")
1375 #define foreach_tcp_proto_field \
1379 #define foreach_udp_proto_field \
1383 #define foreach_ip4_proto_field \
1395 u16 src_port, dst_port;
1398 #if VPP_API_TEST_BUILTIN == 0
1400 unformat_tcp_mask (unformat_input_t *input, va_list *args)
1402 u8 **maskp = va_arg (*args, u8 **);
1404 u8 found_something = 0;
1407 #define _(a) u8 a = 0;
1408 foreach_tcp_proto_field;
1411 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1415 #define _(a) else if (unformat (input, #a)) a = 1;
1416 foreach_tcp_proto_field
1421 #define _(a) found_something += a;
1422 foreach_tcp_proto_field;
1425 if (found_something == 0)
1428 vec_validate (mask, sizeof (*tcp) - 1);
1430 tcp = (tcp_header_t *) mask;
1434 clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
1435 foreach_tcp_proto_field;
1443 unformat_udp_mask (unformat_input_t *input, va_list *args)
1445 u8 **maskp = va_arg (*args, u8 **);
1447 u8 found_something = 0;
1450 #define _(a) u8 a = 0;
1451 foreach_udp_proto_field;
1454 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1458 #define _(a) else if (unformat (input, #a)) a = 1;
1459 foreach_udp_proto_field
1464 #define _(a) found_something += a;
1465 foreach_udp_proto_field;
1468 if (found_something == 0)
1471 vec_validate (mask, sizeof (*udp) - 1);
1473 udp = (udp_header_t *) mask;
1477 clib_memset (&udp->a, 0xff, sizeof (udp->a));
1478 foreach_udp_proto_field;
1486 unformat_l4_mask (unformat_input_t *input, va_list *args)
1488 u8 **maskp = va_arg (*args, u8 **);
1489 u16 src_port = 0, dst_port = 0;
1490 tcpudp_header_t *tcpudp;
1492 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1494 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
1496 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
1498 else if (unformat (input, "src_port"))
1500 else if (unformat (input, "dst_port"))
1506 if (!src_port && !dst_port)
1510 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
1512 tcpudp = (tcpudp_header_t *) mask;
1513 tcpudp->src_port = src_port;
1514 tcpudp->dst_port = dst_port;
1522 unformat_ip4_mask (unformat_input_t * input, va_list * args)
1524 u8 **maskp = va_arg (*args, u8 **);
1526 u8 found_something = 0;
1529 #define _(a) u8 a=0;
1530 foreach_ip4_proto_field;
1536 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1538 if (unformat (input, "version"))
1540 else if (unformat (input, "hdr_length"))
1542 else if (unformat (input, "src"))
1544 else if (unformat (input, "dst"))
1546 else if (unformat (input, "proto"))
1549 #define _(a) else if (unformat (input, #a)) a=1;
1550 foreach_ip4_proto_field
1556 #define _(a) found_something += a;
1557 foreach_ip4_proto_field;
1560 if (found_something == 0)
1563 vec_validate (mask, sizeof (*ip) - 1);
1565 ip = (ip4_header_t *) mask;
1567 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1568 foreach_ip4_proto_field;
1571 ip->ip_version_and_header_length = 0;
1574 ip->ip_version_and_header_length |= 0xF0;
1577 ip->ip_version_and_header_length |= 0x0F;
1583 #define foreach_ip6_proto_field \
1591 unformat_ip6_mask (unformat_input_t * input, va_list * args)
1593 u8 **maskp = va_arg (*args, u8 **);
1595 u8 found_something = 0;
1597 u32 ip_version_traffic_class_and_flow_label;
1599 #define _(a) u8 a=0;
1600 foreach_ip6_proto_field;
1603 u8 traffic_class = 0;
1606 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1608 if (unformat (input, "version"))
1610 else if (unformat (input, "traffic-class"))
1612 else if (unformat (input, "flow-label"))
1614 else if (unformat (input, "src"))
1616 else if (unformat (input, "dst"))
1618 else if (unformat (input, "proto"))
1621 #define _(a) else if (unformat (input, #a)) a=1;
1622 foreach_ip6_proto_field
1628 #define _(a) found_something += a;
1629 foreach_ip6_proto_field;
1632 if (found_something == 0)
1635 vec_validate (mask, sizeof (*ip) - 1);
1637 ip = (ip6_header_t *) mask;
1639 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1640 foreach_ip6_proto_field;
1643 ip_version_traffic_class_and_flow_label = 0;
1646 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1649 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1652 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1654 ip->ip_version_traffic_class_and_flow_label =
1655 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1662 unformat_l3_mask (unformat_input_t * input, va_list * args)
1664 u8 **maskp = va_arg (*args, u8 **);
1666 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1668 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
1670 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
1679 unformat_l2_mask (unformat_input_t * input, va_list * args)
1681 u8 **maskp = va_arg (*args, u8 **);
1696 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1698 if (unformat (input, "src"))
1700 else if (unformat (input, "dst"))
1702 else if (unformat (input, "proto"))
1704 else if (unformat (input, "tag1"))
1706 else if (unformat (input, "tag2"))
1708 else if (unformat (input, "ignore-tag1"))
1710 else if (unformat (input, "ignore-tag2"))
1712 else if (unformat (input, "cos1"))
1714 else if (unformat (input, "cos2"))
1716 else if (unformat (input, "dot1q"))
1718 else if (unformat (input, "dot1ad"))
1723 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1724 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1727 if (tag1 || ignore_tag1 || cos1 || dot1q)
1729 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1732 vec_validate (mask, len - 1);
1735 clib_memset (mask, 0xff, 6);
1738 clib_memset (mask + 6, 0xff, 6);
1742 /* inner vlan tag */
1751 mask[21] = mask[20] = 0xff;
1772 mask[16] = mask[17] = 0xff;
1782 mask[12] = mask[13] = 0xff;
1789 unformat_classify_mask (unformat_input_t * input, va_list * args)
1791 u8 **maskp = va_arg (*args, u8 **);
1792 u32 *skipp = va_arg (*args, u32 *);
1793 u32 *matchp = va_arg (*args, u32 *);
1801 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1803 if (unformat (input, "hex %U", unformat_hex_string, &mask))
1805 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
1807 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
1809 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
1823 if (mask || l2 || l3 || l4)
1827 /* "With a free Ethernet header in every package" */
1829 vec_validate (l2, 13);
1833 vec_append (mask, l3);
1838 vec_append (mask, l4);
1843 /* Scan forward looking for the first significant mask octet */
1844 for (i = 0; i < vec_len (mask); i++)
1848 /* compute (skip, match) params */
1849 *skipp = i / sizeof (u32x4);
1850 vec_delete (mask, *skipp * sizeof (u32x4), 0);
1852 /* Pad mask to an even multiple of the vector size */
1853 while (vec_len (mask) % sizeof (u32x4))
1856 match = vec_len (mask) / sizeof (u32x4);
1858 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
1860 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
1861 if (*tmp || *(tmp + 1))
1866 clib_warning ("BUG: match 0");
1868 _vec_len (mask) = match * sizeof (u32x4);
1878 #endif /* VPP_API_TEST_BUILTIN */
1880 #define foreach_l2_next \
1882 _(ethernet, ETHERNET_INPUT) \
1887 unformat_l2_next_index (unformat_input_t * input, va_list * args)
1889 u32 *miss_next_indexp = va_arg (*args, u32 *);
1894 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
1898 if (unformat (input, "%d", &tmp))
1907 *miss_next_indexp = next_index;
1911 #define foreach_ip_next \
1917 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
1919 u32 *miss_next_indexp = va_arg (*args, u32 *);
1924 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
1928 if (unformat (input, "%d", &tmp))
1937 *miss_next_indexp = next_index;
1941 #define foreach_acl_next \
1945 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
1947 u32 *miss_next_indexp = va_arg (*args, u32 *);
1952 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
1956 if (unformat (input, "permit"))
1961 else if (unformat (input, "%d", &tmp))
1970 *miss_next_indexp = next_index;
1975 unformat_policer_precolor (unformat_input_t * input, va_list * args)
1977 u32 *r = va_arg (*args, u32 *);
1979 if (unformat (input, "conform-color"))
1980 *r = POLICE_CONFORM;
1981 else if (unformat (input, "exceed-color"))
1989 #if VPP_API_TEST_BUILTIN == 0
1991 unformat_l4_match (unformat_input_t * input, va_list * args)
1993 u8 **matchp = va_arg (*args, u8 **);
1995 u8 *proto_header = 0;
2001 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2003 if (unformat (input, "src_port %d", &src_port))
2005 else if (unformat (input, "dst_port %d", &dst_port))
2011 h.src_port = clib_host_to_net_u16 (src_port);
2012 h.dst_port = clib_host_to_net_u16 (dst_port);
2013 vec_validate (proto_header, sizeof (h) - 1);
2014 memcpy (proto_header, &h, sizeof (h));
2016 *matchp = proto_header;
2022 unformat_ip4_match (unformat_input_t * input, va_list * args)
2024 u8 **matchp = va_arg (*args, u8 **);
2031 int src = 0, dst = 0;
2032 ip4_address_t src_val, dst_val;
2039 int fragment_id = 0;
2040 u32 fragment_id_val;
2046 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2048 if (unformat (input, "version %d", &version_val))
2050 else if (unformat (input, "hdr_length %d", &hdr_length_val))
2052 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
2054 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
2056 else if (unformat (input, "proto %d", &proto_val))
2058 else if (unformat (input, "tos %d", &tos_val))
2060 else if (unformat (input, "length %d", &length_val))
2062 else if (unformat (input, "fragment_id %d", &fragment_id_val))
2064 else if (unformat (input, "ttl %d", &ttl_val))
2066 else if (unformat (input, "checksum %d", &checksum_val))
2072 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
2073 + ttl + checksum == 0)
2077 * Aligned because we use the real comparison functions
2079 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
2081 ip = (ip4_header_t *) match;
2083 /* These are realistically matched in practice */
2085 ip->src_address.as_u32 = src_val.as_u32;
2088 ip->dst_address.as_u32 = dst_val.as_u32;
2091 ip->protocol = proto_val;
2094 /* These are not, but they're included for completeness */
2096 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
2099 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
2105 ip->length = clib_host_to_net_u16 (length_val);
2111 ip->checksum = clib_host_to_net_u16 (checksum_val);
2118 unformat_ip6_match (unformat_input_t * input, va_list * args)
2120 u8 **matchp = va_arg (*args, u8 **);
2125 u8 traffic_class = 0;
2126 u32 traffic_class_val = 0;
2129 int src = 0, dst = 0;
2130 ip6_address_t src_val, dst_val;
2133 int payload_length = 0;
2134 u32 payload_length_val;
2137 u32 ip_version_traffic_class_and_flow_label;
2139 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2141 if (unformat (input, "version %d", &version_val))
2143 else if (unformat (input, "traffic_class %d", &traffic_class_val))
2145 else if (unformat (input, "flow_label %d", &flow_label_val))
2147 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
2149 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
2151 else if (unformat (input, "proto %d", &proto_val))
2153 else if (unformat (input, "payload_length %d", &payload_length_val))
2155 else if (unformat (input, "hop_limit %d", &hop_limit_val))
2161 if (version + traffic_class + flow_label + src + dst + proto +
2162 payload_length + hop_limit == 0)
2166 * Aligned because we use the real comparison functions
2168 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
2170 ip = (ip6_header_t *) match;
2173 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
2176 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
2179 ip->protocol = proto_val;
2181 ip_version_traffic_class_and_flow_label = 0;
2184 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
2187 ip_version_traffic_class_and_flow_label |=
2188 (traffic_class_val & 0xFF) << 20;
2191 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
2193 ip->ip_version_traffic_class_and_flow_label =
2194 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
2197 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
2200 ip->hop_limit = hop_limit_val;
2207 unformat_l3_match (unformat_input_t * input, va_list * args)
2209 u8 **matchp = va_arg (*args, u8 **);
2211 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2213 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
2215 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
2224 unformat_vlan_tag (unformat_input_t * input, va_list * args)
2226 u8 *tagp = va_arg (*args, u8 *);
2229 if (unformat (input, "%d", &tag))
2231 tagp[0] = (tag >> 8) & 0x0F;
2232 tagp[1] = tag & 0xFF;
2240 unformat_l2_match (unformat_input_t * input, va_list * args)
2242 u8 **matchp = va_arg (*args, u8 **);
2262 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2264 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
2267 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
2269 else if (unformat (input, "proto %U",
2270 unformat_ethernet_type_host_byte_order, &proto_val))
2272 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
2274 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
2276 else if (unformat (input, "ignore-tag1"))
2278 else if (unformat (input, "ignore-tag2"))
2280 else if (unformat (input, "cos1 %d", &cos1_val))
2282 else if (unformat (input, "cos2 %d", &cos2_val))
2287 if ((src + dst + proto + tag1 + tag2 +
2288 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
2291 if (tag1 || ignore_tag1 || cos1)
2293 if (tag2 || ignore_tag2 || cos2)
2296 vec_validate_aligned (match, len - 1, sizeof (u32x4));
2299 clib_memcpy (match, dst_val, 6);
2302 clib_memcpy (match + 6, src_val, 6);
2306 /* inner vlan tag */
2307 match[19] = tag2_val[1];
2308 match[18] = tag2_val[0];
2310 match[18] |= (cos2_val & 0x7) << 5;
2313 match[21] = proto_val & 0xff;
2314 match[20] = proto_val >> 8;
2318 match[15] = tag1_val[1];
2319 match[14] = tag1_val[0];
2322 match[14] |= (cos1_val & 0x7) << 5;
2328 match[15] = tag1_val[1];
2329 match[14] = tag1_val[0];
2332 match[17] = proto_val & 0xff;
2333 match[16] = proto_val >> 8;
2336 match[14] |= (cos1_val & 0x7) << 5;
2342 match[18] |= (cos2_val & 0x7) << 5;
2344 match[14] |= (cos1_val & 0x7) << 5;
2347 match[13] = proto_val & 0xff;
2348 match[12] = proto_val >> 8;
2356 unformat_qos_source (unformat_input_t * input, va_list * args)
2358 int *qs = va_arg (*args, int *);
2360 if (unformat (input, "ip"))
2361 *qs = QOS_SOURCE_IP;
2362 else if (unformat (input, "mpls"))
2363 *qs = QOS_SOURCE_MPLS;
2364 else if (unformat (input, "ext"))
2365 *qs = QOS_SOURCE_EXT;
2366 else if (unformat (input, "vlan"))
2367 *qs = QOS_SOURCE_VLAN;
2376 api_unformat_classify_match (unformat_input_t * input, va_list * args)
2378 u8 **matchp = va_arg (*args, u8 **);
2379 u32 skip_n_vectors = va_arg (*args, u32);
2380 u32 match_n_vectors = va_arg (*args, u32);
2387 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2389 if (unformat (input, "hex %U", unformat_hex_string, &match))
2391 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
2393 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
2395 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
2409 if (match || l2 || l3 || l4)
2413 /* "Win a free Ethernet header in every packet" */
2415 vec_validate_aligned (l2, 13, sizeof (u32x4));
2419 vec_append_aligned (match, l3, sizeof (u32x4));
2424 vec_append_aligned (match, l4, sizeof (u32x4));
2429 /* Make sure the vector is big enough even if key is all 0's */
2430 vec_validate_aligned
2431 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
2434 /* Set size, include skipped vectors */
2435 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
2446 api_get_node_index (vat_main_t *vam)
2448 unformat_input_t *i = vam->input;
2449 vl_api_get_node_index_t *mp;
2453 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2455 if (unformat (i, "node %s", &name))
2462 errmsg ("node name required");
2465 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
2467 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
2471 M (GET_NODE_INDEX, mp);
2472 clib_memcpy (mp->node_name, name, vec_len (name));
2481 api_get_next_index (vat_main_t *vam)
2483 unformat_input_t *i = vam->input;
2484 vl_api_get_next_index_t *mp;
2485 u8 *node_name = 0, *next_node_name = 0;
2488 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2490 if (unformat (i, "node-name %s", &node_name))
2492 else if (unformat (i, "next-node-name %s", &next_node_name))
2498 errmsg ("node name required");
2501 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
2503 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
2507 if (next_node_name == 0)
2509 errmsg ("next node name required");
2512 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
2514 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
2518 M (GET_NEXT_INDEX, mp);
2519 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
2520 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
2521 vec_free (node_name);
2522 vec_free (next_node_name);
2530 api_add_node_next (vat_main_t *vam)
2532 unformat_input_t *i = vam->input;
2533 vl_api_add_node_next_t *mp;
2538 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2540 if (unformat (i, "node %s", &name))
2542 else if (unformat (i, "next %s", &next))
2549 errmsg ("node name required");
2552 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
2554 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
2559 errmsg ("next node required");
2562 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
2564 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
2568 M (ADD_NODE_NEXT, mp);
2569 clib_memcpy (mp->node_name, name, vec_len (name));
2570 clib_memcpy (mp->next_name, next, vec_len (next));
2579 #define foreach_vtr_op \
2580 _ ("disable", L2_VTR_DISABLED) \
2581 _ ("push-1", L2_VTR_PUSH_1) \
2582 _ ("push-2", L2_VTR_PUSH_2) \
2583 _ ("pop-1", L2_VTR_POP_1) \
2584 _ ("pop-2", L2_VTR_POP_2) \
2585 _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
2586 _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
2587 _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
2588 _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
2591 api_show_version (vat_main_t *vam)
2593 vl_api_show_version_t *mp;
2596 M (SHOW_VERSION, mp);
2604 api_get_first_msg_id (vat_main_t *vam)
2606 vl_api_get_first_msg_id_t *mp;
2607 unformat_input_t *i = vam->input;
2612 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2614 if (unformat (i, "client %s", &name))
2622 errmsg ("missing client name");
2627 if (vec_len (name) > 63)
2629 errmsg ("client name too long");
2633 M (GET_FIRST_MSG_ID, mp);
2634 clib_memcpy (mp->name, name, vec_len (name));
2641 api_get_node_graph (vat_main_t *vam)
2643 vl_api_get_node_graph_t *mp;
2646 M (GET_NODE_GRAPH, mp);
2650 /* Wait for the reply */
2655 #define foreach_pbb_vtr_op \
2656 _("disable", L2_VTR_DISABLED) \
2657 _("pop", L2_VTR_POP_2) \
2658 _("push", L2_VTR_PUSH_2)
2661 api_sock_init_shm (vat_main_t * vam)
2663 #if VPP_API_TEST_BUILTIN == 0
2664 unformat_input_t *i = vam->input;
2665 vl_api_shm_elem_config_t *config = 0;
2666 u64 size = 64 << 20;
2669 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2671 if (unformat (i, "size %U", unformat_memory_size, &size))
2678 * Canned custom ring allocator config.
2679 * Should probably parse all of this
2681 vec_validate (config, 6);
2682 config[0].type = VL_API_VLIB_RING;
2683 config[0].size = 256;
2684 config[0].count = 32;
2686 config[1].type = VL_API_VLIB_RING;
2687 config[1].size = 1024;
2688 config[1].count = 16;
2690 config[2].type = VL_API_VLIB_RING;
2691 config[2].size = 4096;
2692 config[2].count = 2;
2694 config[3].type = VL_API_CLIENT_RING;
2695 config[3].size = 256;
2696 config[3].count = 32;
2698 config[4].type = VL_API_CLIENT_RING;
2699 config[4].size = 1024;
2700 config[4].count = 16;
2702 config[5].type = VL_API_CLIENT_RING;
2703 config[5].size = 4096;
2704 config[5].count = 2;
2706 config[6].type = VL_API_QUEUE;
2707 config[6].count = 128;
2708 config[6].size = sizeof (uword);
2710 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
2712 vam->client_index_invalid = 1;
2720 q_or_quit (vat_main_t * vam)
2722 #if VPP_API_TEST_BUILTIN == 0
2723 longjmp (vam->jump_buf, 1);
2725 return 0; /* not so much */
2729 q (vat_main_t * vam)
2731 return q_or_quit (vam);
2735 quit (vat_main_t * vam)
2737 return q_or_quit (vam);
2741 comment (vat_main_t * vam)
2747 elog_save (vat_main_t * vam)
2749 #if VPP_API_TEST_BUILTIN == 0
2750 elog_main_t *em = &vam->elog_main;
2751 unformat_input_t *i = vam->input;
2752 char *file, *chroot_file;
2753 clib_error_t *error;
2755 if (!unformat (i, "%s", &file))
2757 errmsg ("expected file name, got `%U'", format_unformat_error, i);
2761 /* It's fairly hard to get "../oopsie" through unformat; just in case */
2762 if (strstr (file, "..") || index (file, '/'))
2764 errmsg ("illegal characters in filename '%s'", file);
2768 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
2772 errmsg ("Saving %wd of %wd events to %s",
2773 elog_n_events_in_buffer (em),
2774 elog_buffer_capacity (em), chroot_file);
2776 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
2777 vec_free (chroot_file);
2780 clib_error_report (error);
2782 errmsg ("Use the vpp event loger...");
2789 elog_setup (vat_main_t * vam)
2791 #if VPP_API_TEST_BUILTIN == 0
2792 elog_main_t *em = &vam->elog_main;
2793 unformat_input_t *i = vam->input;
2794 u32 nevents = 128 << 10;
2796 (void) unformat (i, "nevents %d", &nevents);
2798 elog_init (em, nevents);
2799 vl_api_set_elog_main (em);
2800 vl_api_set_elog_trace_api_messages (1);
2801 errmsg ("Event logger initialized with %u events", nevents);
2803 errmsg ("Use the vpp event loger...");
2809 elog_enable (vat_main_t * vam)
2811 #if VPP_API_TEST_BUILTIN == 0
2812 elog_main_t *em = &vam->elog_main;
2814 elog_enable_disable (em, 1 /* enable */ );
2815 vl_api_set_elog_trace_api_messages (1);
2816 errmsg ("Event logger enabled...");
2818 errmsg ("Use the vpp event loger...");
2824 elog_disable (vat_main_t * vam)
2826 #if VPP_API_TEST_BUILTIN == 0
2827 elog_main_t *em = &vam->elog_main;
2829 elog_enable_disable (em, 0 /* enable */ );
2830 vl_api_set_elog_trace_api_messages (1);
2831 errmsg ("Event logger disabled...");
2833 errmsg ("Use the vpp event loger...");
2839 statseg (vat_main_t * vam)
2841 ssvm_private_t *ssvmp = &vam->stat_segment;
2842 ssvm_shared_header_t *shared_header = ssvmp->sh;
2843 vlib_counter_t **counters;
2844 u64 thread0_index1_packets;
2845 u64 thread0_index1_bytes;
2846 f64 vector_rate, input_rate;
2849 uword *counter_vector_by_name;
2850 if (vam->stat_segment_lockp == 0)
2852 errmsg ("Stat segment not mapped...");
2856 /* look up "/if/rx for sw_if_index 1 as a test */
2858 clib_spinlock_lock (vam->stat_segment_lockp);
2860 counter_vector_by_name = (uword *) shared_header->opaque[1];
2862 p = hash_get_mem (counter_vector_by_name, "/if/rx");
2865 clib_spinlock_unlock (vam->stat_segment_lockp);
2866 errmsg ("/if/tx not found?");
2870 /* Fish per-thread vector of combined counters from shared memory */
2871 counters = (vlib_counter_t **) p[0];
2873 if (vec_len (counters[0]) < 2)
2875 clib_spinlock_unlock (vam->stat_segment_lockp);
2876 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
2880 /* Read thread 0 sw_if_index 1 counter */
2881 thread0_index1_packets = counters[0][1].packets;
2882 thread0_index1_bytes = counters[0][1].bytes;
2884 p = hash_get_mem (counter_vector_by_name, "vector_rate");
2887 clib_spinlock_unlock (vam->stat_segment_lockp);
2888 errmsg ("vector_rate not found?");
2892 vector_rate = *(f64 *) (p[0]);
2893 p = hash_get_mem (counter_vector_by_name, "input_rate");
2896 clib_spinlock_unlock (vam->stat_segment_lockp);
2897 errmsg ("input_rate not found?");
2900 input_rate = *(f64 *) (p[0]);
2902 clib_spinlock_unlock (vam->stat_segment_lockp);
2904 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
2905 vector_rate, input_rate);
2906 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
2907 thread0_index1_packets, thread0_index1_bytes);
2913 cmd_cmp (void *a1, void *a2)
2918 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
2922 help (vat_main_t * vam)
2927 unformat_input_t *i = vam->input;
2930 if (unformat (i, "%s", &name))
2936 hs = hash_get_mem (vam->help_by_name, name);
2938 print (vam->ofp, "usage: %s %s", name, hs[0]);
2940 print (vam->ofp, "No such msg / command '%s'", name);
2945 print (vam->ofp, "Help is available for the following:");
2948 hash_foreach_pair (p, vam->function_by_name,
2950 vec_add1 (cmds, (u8 *)(p->key));
2954 vec_sort_with_function (cmds, cmd_cmp);
2956 for (j = 0; j < vec_len (cmds); j++)
2957 print (vam->ofp, "%s", cmds[j]);
2964 set (vat_main_t * vam)
2966 u8 *name = 0, *value = 0;
2967 unformat_input_t *i = vam->input;
2969 if (unformat (i, "%s", &name))
2971 /* The input buffer is a vector, not a string. */
2972 value = vec_dup (i->buffer);
2973 vec_delete (value, i->index, 0);
2974 /* Almost certainly has a trailing newline */
2975 if (value[vec_len (value) - 1] == '\n')
2976 value[vec_len (value) - 1] = 0;
2977 /* Make sure it's a proper string, one way or the other */
2978 vec_add1 (value, 0);
2979 (void) clib_macro_set_value (&vam->macro_main,
2980 (char *) name, (char *) value);
2983 errmsg ("usage: set <name> <value>");
2991 unset (vat_main_t * vam)
2995 if (unformat (vam->input, "%s", &name))
2996 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
2997 errmsg ("unset: %s wasn't set", name);
3010 macro_sort_cmp (void *a1, void *a2)
3012 macro_sort_t *s1 = a1;
3013 macro_sort_t *s2 = a2;
3015 return strcmp ((char *) (s1->name), (char *) (s2->name));
3019 dump_macro_table (vat_main_t * vam)
3021 macro_sort_t *sort_me = 0, *sm;
3026 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
3028 vec_add2 (sort_me, sm, 1);
3029 sm->name = (u8 *)(p->key);
3030 sm->value = (u8 *) (p->value[0]);
3034 vec_sort_with_function (sort_me, macro_sort_cmp);
3036 if (vec_len (sort_me))
3037 print (vam->ofp, "%-15s%s", "Name", "Value");
3039 print (vam->ofp, "The macro table is empty...");
3041 for (i = 0; i < vec_len (sort_me); i++)
3042 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
3047 value_sort_cmp (void *a1, void *a2)
3049 name_sort_t *n1 = a1;
3050 name_sort_t *n2 = a2;
3052 if (n1->value < n2->value)
3054 if (n1->value > n2->value)
3061 dump_msg_api_table (vat_main_t * vam)
3063 api_main_t *am = vlibapi_get_main ();
3064 name_sort_t *nses = 0, *ns;
3069 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
3071 vec_add2 (nses, ns, 1);
3072 ns->name = (u8 *)(hp->key);
3073 ns->value = (u32) hp->value[0];
3077 vec_sort_with_function (nses, value_sort_cmp);
3079 for (i = 0; i < vec_len (nses); i++)
3080 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
3086 get_msg_id (vat_main_t * vam)
3091 if (unformat (vam->input, "%s", &name_and_crc))
3093 message_index = vl_msg_api_get_msg_index (name_and_crc);
3094 if (message_index == ~0)
3096 print (vam->ofp, " '%s' not found", name_and_crc);
3099 print (vam->ofp, " '%s' has message index %d",
3100 name_and_crc, message_index);
3103 errmsg ("name_and_crc required...");
3108 search_node_table (vat_main_t * vam)
3110 unformat_input_t *line_input = vam->input;
3113 vlib_node_t *node, *next_node;
3116 if (vam->graph_node_index_by_name == 0)
3118 print (vam->ofp, "Node table empty, issue get_node_graph...");
3122 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
3124 if (unformat (line_input, "%s", &node_to_find))
3126 vec_add1 (node_to_find, 0);
3127 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
3130 print (vam->ofp, "%s not found...", node_to_find);
3133 node = vam->graph_nodes[0][p[0]];
3134 print (vam->ofp, "[%d] %s", p[0], node->name);
3135 for (j = 0; j < vec_len (node->next_nodes); j++)
3137 if (node->next_nodes[j] != ~0)
3139 next_node = vam->graph_nodes[0][node->next_nodes[j]];
3140 print (vam->ofp, " [%d] %s", j, next_node->name);
3147 clib_warning ("parse error '%U'", format_unformat_error,
3153 vec_free (node_to_find);
3162 script (vat_main_t * vam)
3164 #if (VPP_API_TEST_BUILTIN==0)
3166 char *save_current_file;
3167 unformat_input_t save_input;
3168 jmp_buf save_jump_buf;
3169 u32 save_line_number;
3171 FILE *new_fp, *save_ifp;
3173 if (unformat (vam->input, "%s", &s))
3175 new_fp = fopen ((char *) s, "r");
3178 errmsg ("Couldn't open script file %s", s);
3185 errmsg ("Missing script name");
3189 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
3190 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
3191 save_ifp = vam->ifp;
3192 save_line_number = vam->input_line_number;
3193 save_current_file = (char *) vam->current_file;
3195 vam->input_line_number = 0;
3197 vam->current_file = s;
3200 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
3201 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
3202 vam->ifp = save_ifp;
3203 vam->input_line_number = save_line_number;
3204 vam->current_file = (u8 *) save_current_file;
3209 clib_warning ("use the exec command...");
3215 echo (vat_main_t * vam)
3217 print (vam->ofp, "%v", vam->input->buffer);
3221 /* List of API message constructors, CLI names map to api_xxx */
3222 #define foreach_vpe_api_msg \
3223 _(get_node_index, "node <node-name") \
3224 _(add_node_next, "node <node-name> next <next-node-name>") \
3225 _(show_version, "") \
3226 _(show_threads, "") \
3227 _(get_first_msg_id, "client <name>") \
3228 _(get_node_graph, " ") \
3229 _(get_next_index, "node-name <node-name> next-node-name <node-name>") \
3230 _(sock_init_shm, "size <nnn>") \
3231 /* List of command functions, CLI names map directly to functions */
3232 #define foreach_cli_function \
3233 _(comment, "usage: comment <ignore-rest-of-line>") \
3234 _(dump_macro_table, "usage: dump_macro_table ") \
3235 _(dump_msg_api_table, "usage: dump_msg_api_table") \
3236 _(elog_setup, "usage: elog_setup [nevents, default 128K]") \
3237 _(elog_disable, "usage: elog_disable") \
3238 _(elog_enable, "usage: elog_enable") \
3239 _(elog_save, "usage: elog_save <filename>") \
3240 _(get_msg_id, "usage: get_msg_id name_and_crc") \
3241 _(echo, "usage: echo <message>") \
3242 _(exec, "usage: exec <vpe-debug-CLI-command>") \
3243 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
3244 _(help, "usage: help") \
3245 _(q, "usage: quit") \
3246 _(quit, "usage: quit") \
3247 _(search_node_table, "usage: search_node_table <name>...") \
3248 _(set, "usage: set <variable-name> <value>") \
3249 _(script, "usage: script <file-name>") \
3250 _(statseg, "usage: statseg") \
3251 _(unset, "usage: unset <variable-name>")
3254 static void vl_api_##n##_t_handler_uni \
3255 (vl_api_##n##_t * mp) \
3257 vat_main_t * vam = &vat_main; \
3258 if (vam->json_output) { \
3259 vl_api_##n##_t_handler_json(mp); \
3261 vl_api_##n##_t_handler(mp); \
3264 foreach_vpe_api_reply_msg;
3265 #if VPP_API_TEST_BUILTIN == 0
3266 foreach_standalone_reply_msg;
3271 vat_api_hookup (vat_main_t * vam)
3274 vl_msg_api_set_handlers(VL_API_##N, #n, \
3275 vl_api_##n##_t_handler_uni, \
3277 vl_api_##n##_t_endian, \
3278 vl_api_##n##_t_print, \
3279 sizeof(vl_api_##n##_t), 1);
3280 foreach_vpe_api_reply_msg;
3281 #if VPP_API_TEST_BUILTIN == 0
3282 foreach_standalone_reply_msg;
3286 #if (VPP_API_TEST_BUILTIN==0)
3287 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
3289 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3291 vam->function_by_name = hash_create_string (0, sizeof (uword));
3293 vam->help_by_name = hash_create_string (0, sizeof (uword));
3296 /* API messages we can send */
3297 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
3298 foreach_vpe_api_msg;
3302 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
3303 foreach_vpe_api_msg;
3307 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
3308 foreach_cli_function;
3312 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
3313 foreach_cli_function;
3317 #if VPP_API_TEST_BUILTIN
3318 static clib_error_t *
3319 vat_api_hookup_shim (vlib_main_t * vm)
3321 vat_api_hookup (&vat_main);
3325 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
3329 * fd.io coding-style-patch-verification: ON
3332 * eval: (c-set-style "gnu")