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 _ (session_rule_add_del_reply)
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) \
1132 _ (APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply) \
1133 _ (SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply) \
1134 _ (SESSION_RULES_DETAILS, session_rules_details)
1136 #define foreach_standalone_reply_msg \
1144 #define STR_VTR_OP_CASE(op) \
1145 case L2_VTR_ ## op: \
1149 * Pass CLI buffers directly in the CLI_INBAND API message,
1150 * instead of an additional shared memory area.
1153 exec_inband (vat_main_t * vam)
1155 vl_api_cli_inband_t *mp;
1156 unformat_input_t *i = vam->input;
1159 if (vec_len (i->buffer) == 0)
1162 if (vam->exec_mode == 0 && unformat (i, "mode"))
1167 if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
1174 * In order for the CLI command to work, it
1175 * must be a vector ending in \n, not a C-string ending
1178 M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
1179 vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
1183 /* json responses may or may not include a useful reply... */
1184 if (vec_len (vam->cmd_reply))
1185 print (vam->ofp, "%v", (char *) (vam->cmd_reply));
1190 exec (vat_main_t *vam)
1192 return exec_inband (vam);
1196 api_sw_interface_dump (vat_main_t *vam)
1202 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
1204 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
1207 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
1210 addr->domain = x[0];
1213 addr->function = x[3];
1219 unformat_fib_path (unformat_input_t *input, va_list *args)
1221 vat_main_t *vam = va_arg (*args, vat_main_t *);
1222 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
1223 u32 weight, preference;
1224 mpls_label_t out_label;
1226 clib_memset (path, 0, sizeof (*path));
1228 path->sw_if_index = ~0;
1232 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1234 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
1235 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
1236 &path->sw_if_index))
1238 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1240 else if (unformat (input, "%U %U",
1241 unformat_vl_api_ip6_address,
1242 &path->nh.address.ip6,
1243 api_unformat_sw_if_index, vam, &path->sw_if_index))
1245 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1247 else if (unformat (input, "weight %u", &weight))
1249 path->weight = weight;
1251 else if (unformat (input, "preference %u", &preference))
1253 path->preference = preference;
1255 else if (unformat (input, "%U next-hop-table %d",
1256 unformat_vl_api_ip4_address,
1257 &path->nh.address.ip4, &path->table_id))
1259 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1261 else if (unformat (input, "%U next-hop-table %d",
1262 unformat_vl_api_ip6_address,
1263 &path->nh.address.ip6, &path->table_id))
1265 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1267 else if (unformat (input, "%U",
1268 unformat_vl_api_ip4_address, &path->nh.address.ip4))
1271 * the recursive next-hops are by default in the default table
1274 path->sw_if_index = ~0;
1275 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1277 else if (unformat (input, "%U",
1278 unformat_vl_api_ip6_address, &path->nh.address.ip6))
1281 * the recursive next-hops are by default in the default table
1284 path->sw_if_index = ~0;
1285 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1287 else if (unformat (input, "resolve-via-host"))
1289 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
1291 else if (unformat (input, "resolve-via-attached"))
1293 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
1295 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
1297 path->type = FIB_API_PATH_TYPE_LOCAL;
1298 path->sw_if_index = ~0;
1299 path->proto = FIB_API_PATH_NH_PROTO_IP4;
1301 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
1303 path->type = FIB_API_PATH_TYPE_LOCAL;
1304 path->sw_if_index = ~0;
1305 path->proto = FIB_API_PATH_NH_PROTO_IP6;
1307 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
1309 else if (unformat (input, "via-label %d", &path->nh.via_label))
1311 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
1312 path->sw_if_index = ~0;
1314 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
1316 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
1317 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
1319 else if (unformat (input, "local"))
1321 path->type = FIB_API_PATH_TYPE_LOCAL;
1323 else if (unformat (input, "out-labels"))
1325 while (unformat (input, "%d", &out_label))
1327 path->label_stack[path->n_labels].label = out_label;
1328 path->label_stack[path->n_labels].is_uniform = 0;
1329 path->label_stack[path->n_labels].ttl = 64;
1333 else if (unformat (input, "via"))
1335 /* new path, back up and return */
1336 unformat_put_input (input);
1337 unformat_put_input (input);
1338 unformat_put_input (input);
1339 unformat_put_input (input);
1348 path->proto = ntohl (path->proto);
1349 path->type = ntohl (path->type);
1350 path->flags = ntohl (path->flags);
1351 path->table_id = ntohl (path->table_id);
1352 path->sw_if_index = ntohl (path->sw_if_index);
1357 #define foreach_create_subif_bit \
1364 _(outer_vlan_id_any) \
1365 _(inner_vlan_id_any)
1367 #define foreach_create_subif_flag \
1372 _(4, "exact_match") \
1373 _(5, "default_sub") \
1374 _(6, "outer_vlan_id_any") \
1375 _(7, "inner_vlan_id_any")
1378 #define foreach_tcp_proto_field \
1382 #define foreach_udp_proto_field \
1386 #define foreach_ip4_proto_field \
1398 u16 src_port, dst_port;
1401 #if VPP_API_TEST_BUILTIN == 0
1403 unformat_tcp_mask (unformat_input_t *input, va_list *args)
1405 u8 **maskp = va_arg (*args, u8 **);
1407 u8 found_something = 0;
1410 #define _(a) u8 a = 0;
1411 foreach_tcp_proto_field;
1414 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1418 #define _(a) else if (unformat (input, #a)) a = 1;
1419 foreach_tcp_proto_field
1424 #define _(a) found_something += a;
1425 foreach_tcp_proto_field;
1428 if (found_something == 0)
1431 vec_validate (mask, sizeof (*tcp) - 1);
1433 tcp = (tcp_header_t *) mask;
1437 clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
1438 foreach_tcp_proto_field;
1446 unformat_udp_mask (unformat_input_t *input, va_list *args)
1448 u8 **maskp = va_arg (*args, u8 **);
1450 u8 found_something = 0;
1453 #define _(a) u8 a = 0;
1454 foreach_udp_proto_field;
1457 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1461 #define _(a) else if (unformat (input, #a)) a = 1;
1462 foreach_udp_proto_field
1467 #define _(a) found_something += a;
1468 foreach_udp_proto_field;
1471 if (found_something == 0)
1474 vec_validate (mask, sizeof (*udp) - 1);
1476 udp = (udp_header_t *) mask;
1480 clib_memset (&udp->a, 0xff, sizeof (udp->a));
1481 foreach_udp_proto_field;
1489 unformat_l4_mask (unformat_input_t *input, va_list *args)
1491 u8 **maskp = va_arg (*args, u8 **);
1492 u16 src_port = 0, dst_port = 0;
1493 tcpudp_header_t *tcpudp;
1495 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1497 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
1499 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
1501 else if (unformat (input, "src_port"))
1503 else if (unformat (input, "dst_port"))
1509 if (!src_port && !dst_port)
1513 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
1515 tcpudp = (tcpudp_header_t *) mask;
1516 tcpudp->src_port = src_port;
1517 tcpudp->dst_port = dst_port;
1525 unformat_ip4_mask (unformat_input_t * input, va_list * args)
1527 u8 **maskp = va_arg (*args, u8 **);
1529 u8 found_something = 0;
1532 #define _(a) u8 a=0;
1533 foreach_ip4_proto_field;
1539 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1541 if (unformat (input, "version"))
1543 else if (unformat (input, "hdr_length"))
1545 else if (unformat (input, "src"))
1547 else if (unformat (input, "dst"))
1549 else if (unformat (input, "proto"))
1552 #define _(a) else if (unformat (input, #a)) a=1;
1553 foreach_ip4_proto_field
1559 #define _(a) found_something += a;
1560 foreach_ip4_proto_field;
1563 if (found_something == 0)
1566 vec_validate (mask, sizeof (*ip) - 1);
1568 ip = (ip4_header_t *) mask;
1570 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1571 foreach_ip4_proto_field;
1574 ip->ip_version_and_header_length = 0;
1577 ip->ip_version_and_header_length |= 0xF0;
1580 ip->ip_version_and_header_length |= 0x0F;
1586 #define foreach_ip6_proto_field \
1594 unformat_ip6_mask (unformat_input_t * input, va_list * args)
1596 u8 **maskp = va_arg (*args, u8 **);
1598 u8 found_something = 0;
1600 u32 ip_version_traffic_class_and_flow_label;
1602 #define _(a) u8 a=0;
1603 foreach_ip6_proto_field;
1606 u8 traffic_class = 0;
1609 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1611 if (unformat (input, "version"))
1613 else if (unformat (input, "traffic-class"))
1615 else if (unformat (input, "flow-label"))
1617 else if (unformat (input, "src"))
1619 else if (unformat (input, "dst"))
1621 else if (unformat (input, "proto"))
1624 #define _(a) else if (unformat (input, #a)) a=1;
1625 foreach_ip6_proto_field
1631 #define _(a) found_something += a;
1632 foreach_ip6_proto_field;
1635 if (found_something == 0)
1638 vec_validate (mask, sizeof (*ip) - 1);
1640 ip = (ip6_header_t *) mask;
1642 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1643 foreach_ip6_proto_field;
1646 ip_version_traffic_class_and_flow_label = 0;
1649 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1652 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1655 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1657 ip->ip_version_traffic_class_and_flow_label =
1658 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1665 unformat_l3_mask (unformat_input_t * input, va_list * args)
1667 u8 **maskp = va_arg (*args, u8 **);
1669 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1671 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
1673 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
1682 unformat_l2_mask (unformat_input_t * input, va_list * args)
1684 u8 **maskp = va_arg (*args, u8 **);
1699 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1701 if (unformat (input, "src"))
1703 else if (unformat (input, "dst"))
1705 else if (unformat (input, "proto"))
1707 else if (unformat (input, "tag1"))
1709 else if (unformat (input, "tag2"))
1711 else if (unformat (input, "ignore-tag1"))
1713 else if (unformat (input, "ignore-tag2"))
1715 else if (unformat (input, "cos1"))
1717 else if (unformat (input, "cos2"))
1719 else if (unformat (input, "dot1q"))
1721 else if (unformat (input, "dot1ad"))
1726 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1727 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1730 if (tag1 || ignore_tag1 || cos1 || dot1q)
1732 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1735 vec_validate (mask, len - 1);
1738 clib_memset (mask, 0xff, 6);
1741 clib_memset (mask + 6, 0xff, 6);
1745 /* inner vlan tag */
1754 mask[21] = mask[20] = 0xff;
1775 mask[16] = mask[17] = 0xff;
1785 mask[12] = mask[13] = 0xff;
1792 unformat_classify_mask (unformat_input_t * input, va_list * args)
1794 u8 **maskp = va_arg (*args, u8 **);
1795 u32 *skipp = va_arg (*args, u32 *);
1796 u32 *matchp = va_arg (*args, u32 *);
1804 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1806 if (unformat (input, "hex %U", unformat_hex_string, &mask))
1808 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
1810 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
1812 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
1826 if (mask || l2 || l3 || l4)
1830 /* "With a free Ethernet header in every package" */
1832 vec_validate (l2, 13);
1836 vec_append (mask, l3);
1841 vec_append (mask, l4);
1846 /* Scan forward looking for the first significant mask octet */
1847 for (i = 0; i < vec_len (mask); i++)
1851 /* compute (skip, match) params */
1852 *skipp = i / sizeof (u32x4);
1853 vec_delete (mask, *skipp * sizeof (u32x4), 0);
1855 /* Pad mask to an even multiple of the vector size */
1856 while (vec_len (mask) % sizeof (u32x4))
1859 match = vec_len (mask) / sizeof (u32x4);
1861 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
1863 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
1864 if (*tmp || *(tmp + 1))
1869 clib_warning ("BUG: match 0");
1871 _vec_len (mask) = match * sizeof (u32x4);
1881 #endif /* VPP_API_TEST_BUILTIN */
1883 #define foreach_l2_next \
1885 _(ethernet, ETHERNET_INPUT) \
1890 unformat_l2_next_index (unformat_input_t * input, va_list * args)
1892 u32 *miss_next_indexp = va_arg (*args, u32 *);
1897 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
1901 if (unformat (input, "%d", &tmp))
1910 *miss_next_indexp = next_index;
1914 #define foreach_ip_next \
1920 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
1922 u32 *miss_next_indexp = va_arg (*args, u32 *);
1927 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
1931 if (unformat (input, "%d", &tmp))
1940 *miss_next_indexp = next_index;
1944 #define foreach_acl_next \
1948 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
1950 u32 *miss_next_indexp = va_arg (*args, u32 *);
1955 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
1959 if (unformat (input, "permit"))
1964 else if (unformat (input, "%d", &tmp))
1973 *miss_next_indexp = next_index;
1978 unformat_policer_precolor (unformat_input_t * input, va_list * args)
1980 u32 *r = va_arg (*args, u32 *);
1982 if (unformat (input, "conform-color"))
1983 *r = POLICE_CONFORM;
1984 else if (unformat (input, "exceed-color"))
1992 #if VPP_API_TEST_BUILTIN == 0
1994 unformat_l4_match (unformat_input_t * input, va_list * args)
1996 u8 **matchp = va_arg (*args, u8 **);
1998 u8 *proto_header = 0;
2004 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2006 if (unformat (input, "src_port %d", &src_port))
2008 else if (unformat (input, "dst_port %d", &dst_port))
2014 h.src_port = clib_host_to_net_u16 (src_port);
2015 h.dst_port = clib_host_to_net_u16 (dst_port);
2016 vec_validate (proto_header, sizeof (h) - 1);
2017 memcpy (proto_header, &h, sizeof (h));
2019 *matchp = proto_header;
2025 unformat_ip4_match (unformat_input_t * input, va_list * args)
2027 u8 **matchp = va_arg (*args, u8 **);
2034 int src = 0, dst = 0;
2035 ip4_address_t src_val, dst_val;
2042 int fragment_id = 0;
2043 u32 fragment_id_val;
2049 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2051 if (unformat (input, "version %d", &version_val))
2053 else if (unformat (input, "hdr_length %d", &hdr_length_val))
2055 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
2057 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
2059 else if (unformat (input, "proto %d", &proto_val))
2061 else if (unformat (input, "tos %d", &tos_val))
2063 else if (unformat (input, "length %d", &length_val))
2065 else if (unformat (input, "fragment_id %d", &fragment_id_val))
2067 else if (unformat (input, "ttl %d", &ttl_val))
2069 else if (unformat (input, "checksum %d", &checksum_val))
2075 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
2076 + ttl + checksum == 0)
2080 * Aligned because we use the real comparison functions
2082 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
2084 ip = (ip4_header_t *) match;
2086 /* These are realistically matched in practice */
2088 ip->src_address.as_u32 = src_val.as_u32;
2091 ip->dst_address.as_u32 = dst_val.as_u32;
2094 ip->protocol = proto_val;
2097 /* These are not, but they're included for completeness */
2099 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
2102 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
2108 ip->length = clib_host_to_net_u16 (length_val);
2114 ip->checksum = clib_host_to_net_u16 (checksum_val);
2121 unformat_ip6_match (unformat_input_t * input, va_list * args)
2123 u8 **matchp = va_arg (*args, u8 **);
2128 u8 traffic_class = 0;
2129 u32 traffic_class_val = 0;
2132 int src = 0, dst = 0;
2133 ip6_address_t src_val, dst_val;
2136 int payload_length = 0;
2137 u32 payload_length_val;
2140 u32 ip_version_traffic_class_and_flow_label;
2142 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2144 if (unformat (input, "version %d", &version_val))
2146 else if (unformat (input, "traffic_class %d", &traffic_class_val))
2148 else if (unformat (input, "flow_label %d", &flow_label_val))
2150 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
2152 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
2154 else if (unformat (input, "proto %d", &proto_val))
2156 else if (unformat (input, "payload_length %d", &payload_length_val))
2158 else if (unformat (input, "hop_limit %d", &hop_limit_val))
2164 if (version + traffic_class + flow_label + src + dst + proto +
2165 payload_length + hop_limit == 0)
2169 * Aligned because we use the real comparison functions
2171 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
2173 ip = (ip6_header_t *) match;
2176 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
2179 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
2182 ip->protocol = proto_val;
2184 ip_version_traffic_class_and_flow_label = 0;
2187 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
2190 ip_version_traffic_class_and_flow_label |=
2191 (traffic_class_val & 0xFF) << 20;
2194 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
2196 ip->ip_version_traffic_class_and_flow_label =
2197 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
2200 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
2203 ip->hop_limit = hop_limit_val;
2210 unformat_l3_match (unformat_input_t * input, va_list * args)
2212 u8 **matchp = va_arg (*args, u8 **);
2214 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2216 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
2218 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
2227 unformat_vlan_tag (unformat_input_t * input, va_list * args)
2229 u8 *tagp = va_arg (*args, u8 *);
2232 if (unformat (input, "%d", &tag))
2234 tagp[0] = (tag >> 8) & 0x0F;
2235 tagp[1] = tag & 0xFF;
2243 unformat_l2_match (unformat_input_t * input, va_list * args)
2245 u8 **matchp = va_arg (*args, u8 **);
2265 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2267 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
2270 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
2272 else if (unformat (input, "proto %U",
2273 unformat_ethernet_type_host_byte_order, &proto_val))
2275 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
2277 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
2279 else if (unformat (input, "ignore-tag1"))
2281 else if (unformat (input, "ignore-tag2"))
2283 else if (unformat (input, "cos1 %d", &cos1_val))
2285 else if (unformat (input, "cos2 %d", &cos2_val))
2290 if ((src + dst + proto + tag1 + tag2 +
2291 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
2294 if (tag1 || ignore_tag1 || cos1)
2296 if (tag2 || ignore_tag2 || cos2)
2299 vec_validate_aligned (match, len - 1, sizeof (u32x4));
2302 clib_memcpy (match, dst_val, 6);
2305 clib_memcpy (match + 6, src_val, 6);
2309 /* inner vlan tag */
2310 match[19] = tag2_val[1];
2311 match[18] = tag2_val[0];
2313 match[18] |= (cos2_val & 0x7) << 5;
2316 match[21] = proto_val & 0xff;
2317 match[20] = proto_val >> 8;
2321 match[15] = tag1_val[1];
2322 match[14] = tag1_val[0];
2325 match[14] |= (cos1_val & 0x7) << 5;
2331 match[15] = tag1_val[1];
2332 match[14] = tag1_val[0];
2335 match[17] = proto_val & 0xff;
2336 match[16] = proto_val >> 8;
2339 match[14] |= (cos1_val & 0x7) << 5;
2345 match[18] |= (cos2_val & 0x7) << 5;
2347 match[14] |= (cos1_val & 0x7) << 5;
2350 match[13] = proto_val & 0xff;
2351 match[12] = proto_val >> 8;
2359 unformat_qos_source (unformat_input_t * input, va_list * args)
2361 int *qs = va_arg (*args, int *);
2363 if (unformat (input, "ip"))
2364 *qs = QOS_SOURCE_IP;
2365 else if (unformat (input, "mpls"))
2366 *qs = QOS_SOURCE_MPLS;
2367 else if (unformat (input, "ext"))
2368 *qs = QOS_SOURCE_EXT;
2369 else if (unformat (input, "vlan"))
2370 *qs = QOS_SOURCE_VLAN;
2379 api_unformat_classify_match (unformat_input_t * input, va_list * args)
2381 u8 **matchp = va_arg (*args, u8 **);
2382 u32 skip_n_vectors = va_arg (*args, u32);
2383 u32 match_n_vectors = va_arg (*args, u32);
2390 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2392 if (unformat (input, "hex %U", unformat_hex_string, &match))
2394 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
2396 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
2398 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
2412 if (match || l2 || l3 || l4)
2416 /* "Win a free Ethernet header in every packet" */
2418 vec_validate_aligned (l2, 13, sizeof (u32x4));
2422 vec_append_aligned (match, l3, sizeof (u32x4));
2427 vec_append_aligned (match, l4, sizeof (u32x4));
2432 /* Make sure the vector is big enough even if key is all 0's */
2433 vec_validate_aligned
2434 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
2437 /* Set size, include skipped vectors */
2438 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
2449 api_get_node_index (vat_main_t *vam)
2451 unformat_input_t *i = vam->input;
2452 vl_api_get_node_index_t *mp;
2456 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2458 if (unformat (i, "node %s", &name))
2465 errmsg ("node name required");
2468 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
2470 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
2474 M (GET_NODE_INDEX, mp);
2475 clib_memcpy (mp->node_name, name, vec_len (name));
2484 api_get_next_index (vat_main_t *vam)
2486 unformat_input_t *i = vam->input;
2487 vl_api_get_next_index_t *mp;
2488 u8 *node_name = 0, *next_node_name = 0;
2491 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2493 if (unformat (i, "node-name %s", &node_name))
2495 else if (unformat (i, "next-node-name %s", &next_node_name))
2501 errmsg ("node name required");
2504 if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
2506 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
2510 if (next_node_name == 0)
2512 errmsg ("next node name required");
2515 if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
2517 errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
2521 M (GET_NEXT_INDEX, mp);
2522 clib_memcpy (mp->node_name, node_name, vec_len (node_name));
2523 clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
2524 vec_free (node_name);
2525 vec_free (next_node_name);
2533 api_add_node_next (vat_main_t *vam)
2535 unformat_input_t *i = vam->input;
2536 vl_api_add_node_next_t *mp;
2541 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2543 if (unformat (i, "node %s", &name))
2545 else if (unformat (i, "next %s", &next))
2552 errmsg ("node name required");
2555 if (vec_len (name) >= ARRAY_LEN (mp->node_name))
2557 errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
2562 errmsg ("next node required");
2565 if (vec_len (next) >= ARRAY_LEN (mp->next_name))
2567 errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
2571 M (ADD_NODE_NEXT, mp);
2572 clib_memcpy (mp->node_name, name, vec_len (name));
2573 clib_memcpy (mp->next_name, next, vec_len (next));
2582 #define foreach_vtr_op \
2583 _ ("disable", L2_VTR_DISABLED) \
2584 _ ("push-1", L2_VTR_PUSH_1) \
2585 _ ("push-2", L2_VTR_PUSH_2) \
2586 _ ("pop-1", L2_VTR_POP_1) \
2587 _ ("pop-2", L2_VTR_POP_2) \
2588 _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
2589 _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
2590 _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
2591 _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
2594 api_show_version (vat_main_t *vam)
2596 vl_api_show_version_t *mp;
2599 M (SHOW_VERSION, mp);
2607 api_get_first_msg_id (vat_main_t *vam)
2609 vl_api_get_first_msg_id_t *mp;
2610 unformat_input_t *i = vam->input;
2615 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2617 if (unformat (i, "client %s", &name))
2625 errmsg ("missing client name");
2630 if (vec_len (name) > 63)
2632 errmsg ("client name too long");
2636 M (GET_FIRST_MSG_ID, mp);
2637 clib_memcpy (mp->name, name, vec_len (name));
2644 api_get_node_graph (vat_main_t *vam)
2646 vl_api_get_node_graph_t *mp;
2649 M (GET_NODE_GRAPH, mp);
2653 /* Wait for the reply */
2658 #define foreach_pbb_vtr_op \
2659 _("disable", L2_VTR_DISABLED) \
2660 _("pop", L2_VTR_POP_2) \
2661 _("push", L2_VTR_PUSH_2)
2664 static void vl_api_app_namespace_add_del_reply_t_handler
2665 (vl_api_app_namespace_add_del_reply_t * mp)
2667 vat_main_t *vam = &vat_main;
2668 i32 retval = ntohl (mp->retval);
2669 if (vam->async_mode)
2671 vam->async_errors += (retval < 0);
2675 vam->retval = retval;
2677 errmsg ("app ns index %d\n", ntohl (mp->appns_index));
2678 vam->result_ready = 1;
2682 static void vl_api_app_namespace_add_del_reply_t_handler_json
2683 (vl_api_app_namespace_add_del_reply_t * mp)
2685 vat_main_t *vam = &vat_main;
2686 vat_json_node_t node;
2688 vat_json_init_object (&node);
2689 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2690 vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
2692 vat_json_print (vam->ofp, &node);
2693 vat_json_free (&node);
2695 vam->retval = ntohl (mp->retval);
2696 vam->result_ready = 1;
2700 api_app_namespace_add_del (vat_main_t * vam)
2702 vl_api_app_namespace_add_del_t *mp;
2703 unformat_input_t *i = vam->input;
2704 u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
2705 u32 sw_if_index, ip4_fib_id, ip6_fib_id;
2709 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2711 if (unformat (i, "id %_%v%_", &ns_id))
2713 else if (unformat (i, "secret %lu", &secret))
2715 else if (unformat (i, "sw_if_index %d", &sw_if_index))
2716 sw_if_index_set = 1;
2717 else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
2719 else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
2724 if (!ns_id || !secret_set || !sw_if_index_set)
2726 errmsg ("namespace id, secret and sw_if_index must be set");
2729 if (vec_len (ns_id) > 64)
2731 errmsg ("namespace id too long");
2734 M (APP_NAMESPACE_ADD_DEL, mp);
2736 vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
2737 mp->secret = clib_host_to_net_u64 (secret);
2738 mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
2739 mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
2740 mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
2748 api_sock_init_shm (vat_main_t * vam)
2750 #if VPP_API_TEST_BUILTIN == 0
2751 unformat_input_t *i = vam->input;
2752 vl_api_shm_elem_config_t *config = 0;
2753 u64 size = 64 << 20;
2756 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2758 if (unformat (i, "size %U", unformat_memory_size, &size))
2765 * Canned custom ring allocator config.
2766 * Should probably parse all of this
2768 vec_validate (config, 6);
2769 config[0].type = VL_API_VLIB_RING;
2770 config[0].size = 256;
2771 config[0].count = 32;
2773 config[1].type = VL_API_VLIB_RING;
2774 config[1].size = 1024;
2775 config[1].count = 16;
2777 config[2].type = VL_API_VLIB_RING;
2778 config[2].size = 4096;
2779 config[2].count = 2;
2781 config[3].type = VL_API_CLIENT_RING;
2782 config[3].size = 256;
2783 config[3].count = 32;
2785 config[4].type = VL_API_CLIENT_RING;
2786 config[4].size = 1024;
2787 config[4].count = 16;
2789 config[5].type = VL_API_CLIENT_RING;
2790 config[5].size = 4096;
2791 config[5].count = 2;
2793 config[6].type = VL_API_QUEUE;
2794 config[6].count = 128;
2795 config[6].size = sizeof (uword);
2797 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
2799 vam->client_index_invalid = 1;
2807 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
2809 vat_main_t *vam = &vat_main;
2810 fib_prefix_t lcl, rmt;
2812 ip_prefix_decode (&mp->lcl, &lcl);
2813 ip_prefix_decode (&mp->rmt, &rmt);
2815 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
2818 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
2819 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
2820 mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
2821 clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
2822 &rmt.fp_addr.ip4, rmt.fp_len,
2823 clib_net_to_host_u16 (mp->rmt_port),
2824 clib_net_to_host_u32 (mp->action_index), mp->tag);
2829 "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
2830 clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
2831 mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
2832 clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
2833 &rmt.fp_addr.ip6, rmt.fp_len,
2834 clib_net_to_host_u16 (mp->rmt_port),
2835 clib_net_to_host_u32 (mp->action_index), mp->tag);
2840 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
2843 vat_main_t *vam = &vat_main;
2844 vat_json_node_t *node = NULL;
2845 struct in6_addr ip6;
2848 fib_prefix_t lcl, rmt;
2850 ip_prefix_decode (&mp->lcl, &lcl);
2851 ip_prefix_decode (&mp->rmt, &rmt);
2853 if (VAT_JSON_ARRAY != vam->json_tree.type)
2855 ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2856 vat_json_init_array (&vam->json_tree);
2858 node = vat_json_array_add (&vam->json_tree);
2859 vat_json_init_object (node);
2861 vat_json_object_add_uint (node, "appns_index",
2862 clib_net_to_host_u32 (mp->appns_index));
2863 vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
2864 vat_json_object_add_uint (node, "scope", mp->scope);
2865 vat_json_object_add_uint (node, "action_index",
2866 clib_net_to_host_u32 (mp->action_index));
2867 vat_json_object_add_uint (node, "lcl_port",
2868 clib_net_to_host_u16 (mp->lcl_port));
2869 vat_json_object_add_uint (node, "rmt_port",
2870 clib_net_to_host_u16 (mp->rmt_port));
2871 vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
2872 vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
2873 vat_json_object_add_string_copy (node, "tag", mp->tag);
2874 if (lcl.fp_proto == FIB_PROTOCOL_IP4)
2876 clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
2877 vat_json_object_add_ip4 (node, "lcl_ip", ip4);
2878 clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
2879 vat_json_object_add_ip4 (node, "rmt_ip", ip4);
2883 clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
2884 vat_json_object_add_ip6 (node, "lcl_ip", ip6);
2885 clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
2886 vat_json_object_add_ip6 (node, "rmt_ip", ip6);
2891 api_session_rule_add_del (vat_main_t * vam)
2893 vl_api_session_rule_add_del_t *mp;
2894 unformat_input_t *i = vam->input;
2895 u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
2896 u32 appns_index = 0, scope = 0;
2897 ip4_address_t lcl_ip4, rmt_ip4;
2898 ip6_address_t lcl_ip6, rmt_ip6;
2899 u8 is_ip4 = 1, conn_set = 0;
2900 u8 is_add = 1, *tag = 0;
2902 fib_prefix_t lcl, rmt;
2904 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2906 if (unformat (i, "del"))
2908 else if (unformat (i, "add"))
2910 else if (unformat (i, "proto tcp"))
2912 else if (unformat (i, "proto udp"))
2914 else if (unformat (i, "appns %d", &appns_index))
2916 else if (unformat (i, "scope %d", &scope))
2918 else if (unformat (i, "tag %_%v%_", &tag))
2922 (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
2923 &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
2931 (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
2932 &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
2938 else if (unformat (i, "action %d", &action))
2943 if (proto == ~0 || !conn_set || action == ~0)
2945 errmsg ("transport proto, connection and action must be set");
2951 errmsg ("scope should be 0-3");
2955 M (SESSION_RULE_ADD_DEL, mp);
2957 clib_memset (&lcl, 0, sizeof (lcl));
2958 clib_memset (&rmt, 0, sizeof (rmt));
2961 ip_set (&lcl.fp_addr, &lcl_ip4, 1);
2962 ip_set (&rmt.fp_addr, &rmt_ip4, 1);
2963 lcl.fp_len = lcl_plen;
2964 rmt.fp_len = rmt_plen;
2968 ip_set (&lcl.fp_addr, &lcl_ip6, 0);
2969 ip_set (&rmt.fp_addr, &rmt_ip6, 0);
2970 lcl.fp_len = lcl_plen;
2971 rmt.fp_len = rmt_plen;
2975 ip_prefix_encode (&lcl, &mp->lcl);
2976 ip_prefix_encode (&rmt, &mp->rmt);
2977 mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
2978 mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
2979 mp->transport_proto =
2980 proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
2981 mp->action_index = clib_host_to_net_u32 (action);
2982 mp->appns_index = clib_host_to_net_u32 (appns_index);
2984 mp->is_add = is_add;
2987 clib_memcpy (mp->tag, tag, vec_len (tag));
2997 api_session_rules_dump (vat_main_t * vam)
2999 vl_api_session_rules_dump_t *mp;
3000 vl_api_control_ping_t *mp_ping;
3003 if (!vam->json_output)
3005 print (vam->ofp, "%=20s", "Session Rules");
3008 M (SESSION_RULES_DUMP, mp);
3012 /* Use a control ping for synchronization */
3013 MPING (CONTROL_PING, mp_ping);
3016 /* Wait for a reply... */
3022 q_or_quit (vat_main_t * vam)
3024 #if VPP_API_TEST_BUILTIN == 0
3025 longjmp (vam->jump_buf, 1);
3027 return 0; /* not so much */
3031 q (vat_main_t * vam)
3033 return q_or_quit (vam);
3037 quit (vat_main_t * vam)
3039 return q_or_quit (vam);
3043 comment (vat_main_t * vam)
3049 elog_save (vat_main_t * vam)
3051 #if VPP_API_TEST_BUILTIN == 0
3052 elog_main_t *em = &vam->elog_main;
3053 unformat_input_t *i = vam->input;
3054 char *file, *chroot_file;
3055 clib_error_t *error;
3057 if (!unformat (i, "%s", &file))
3059 errmsg ("expected file name, got `%U'", format_unformat_error, i);
3063 /* It's fairly hard to get "../oopsie" through unformat; just in case */
3064 if (strstr (file, "..") || index (file, '/'))
3066 errmsg ("illegal characters in filename '%s'", file);
3070 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
3074 errmsg ("Saving %wd of %wd events to %s",
3075 elog_n_events_in_buffer (em),
3076 elog_buffer_capacity (em), chroot_file);
3078 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
3079 vec_free (chroot_file);
3082 clib_error_report (error);
3084 errmsg ("Use the vpp event loger...");
3091 elog_setup (vat_main_t * vam)
3093 #if VPP_API_TEST_BUILTIN == 0
3094 elog_main_t *em = &vam->elog_main;
3095 unformat_input_t *i = vam->input;
3096 u32 nevents = 128 << 10;
3098 (void) unformat (i, "nevents %d", &nevents);
3100 elog_init (em, nevents);
3101 vl_api_set_elog_main (em);
3102 vl_api_set_elog_trace_api_messages (1);
3103 errmsg ("Event logger initialized with %u events", nevents);
3105 errmsg ("Use the vpp event loger...");
3111 elog_enable (vat_main_t * vam)
3113 #if VPP_API_TEST_BUILTIN == 0
3114 elog_main_t *em = &vam->elog_main;
3116 elog_enable_disable (em, 1 /* enable */ );
3117 vl_api_set_elog_trace_api_messages (1);
3118 errmsg ("Event logger enabled...");
3120 errmsg ("Use the vpp event loger...");
3126 elog_disable (vat_main_t * vam)
3128 #if VPP_API_TEST_BUILTIN == 0
3129 elog_main_t *em = &vam->elog_main;
3131 elog_enable_disable (em, 0 /* enable */ );
3132 vl_api_set_elog_trace_api_messages (1);
3133 errmsg ("Event logger disabled...");
3135 errmsg ("Use the vpp event loger...");
3141 statseg (vat_main_t * vam)
3143 ssvm_private_t *ssvmp = &vam->stat_segment;
3144 ssvm_shared_header_t *shared_header = ssvmp->sh;
3145 vlib_counter_t **counters;
3146 u64 thread0_index1_packets;
3147 u64 thread0_index1_bytes;
3148 f64 vector_rate, input_rate;
3151 uword *counter_vector_by_name;
3152 if (vam->stat_segment_lockp == 0)
3154 errmsg ("Stat segment not mapped...");
3158 /* look up "/if/rx for sw_if_index 1 as a test */
3160 clib_spinlock_lock (vam->stat_segment_lockp);
3162 counter_vector_by_name = (uword *) shared_header->opaque[1];
3164 p = hash_get_mem (counter_vector_by_name, "/if/rx");
3167 clib_spinlock_unlock (vam->stat_segment_lockp);
3168 errmsg ("/if/tx not found?");
3172 /* Fish per-thread vector of combined counters from shared memory */
3173 counters = (vlib_counter_t **) p[0];
3175 if (vec_len (counters[0]) < 2)
3177 clib_spinlock_unlock (vam->stat_segment_lockp);
3178 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
3182 /* Read thread 0 sw_if_index 1 counter */
3183 thread0_index1_packets = counters[0][1].packets;
3184 thread0_index1_bytes = counters[0][1].bytes;
3186 p = hash_get_mem (counter_vector_by_name, "vector_rate");
3189 clib_spinlock_unlock (vam->stat_segment_lockp);
3190 errmsg ("vector_rate not found?");
3194 vector_rate = *(f64 *) (p[0]);
3195 p = hash_get_mem (counter_vector_by_name, "input_rate");
3198 clib_spinlock_unlock (vam->stat_segment_lockp);
3199 errmsg ("input_rate not found?");
3202 input_rate = *(f64 *) (p[0]);
3204 clib_spinlock_unlock (vam->stat_segment_lockp);
3206 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
3207 vector_rate, input_rate);
3208 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
3209 thread0_index1_packets, thread0_index1_bytes);
3215 cmd_cmp (void *a1, void *a2)
3220 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
3224 help (vat_main_t * vam)
3229 unformat_input_t *i = vam->input;
3232 if (unformat (i, "%s", &name))
3238 hs = hash_get_mem (vam->help_by_name, name);
3240 print (vam->ofp, "usage: %s %s", name, hs[0]);
3242 print (vam->ofp, "No such msg / command '%s'", name);
3247 print (vam->ofp, "Help is available for the following:");
3250 hash_foreach_pair (p, vam->function_by_name,
3252 vec_add1 (cmds, (u8 *)(p->key));
3256 vec_sort_with_function (cmds, cmd_cmp);
3258 for (j = 0; j < vec_len (cmds); j++)
3259 print (vam->ofp, "%s", cmds[j]);
3266 set (vat_main_t * vam)
3268 u8 *name = 0, *value = 0;
3269 unformat_input_t *i = vam->input;
3271 if (unformat (i, "%s", &name))
3273 /* The input buffer is a vector, not a string. */
3274 value = vec_dup (i->buffer);
3275 vec_delete (value, i->index, 0);
3276 /* Almost certainly has a trailing newline */
3277 if (value[vec_len (value) - 1] == '\n')
3278 value[vec_len (value) - 1] = 0;
3279 /* Make sure it's a proper string, one way or the other */
3280 vec_add1 (value, 0);
3281 (void) clib_macro_set_value (&vam->macro_main,
3282 (char *) name, (char *) value);
3285 errmsg ("usage: set <name> <value>");
3293 unset (vat_main_t * vam)
3297 if (unformat (vam->input, "%s", &name))
3298 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
3299 errmsg ("unset: %s wasn't set", name);
3312 macro_sort_cmp (void *a1, void *a2)
3314 macro_sort_t *s1 = a1;
3315 macro_sort_t *s2 = a2;
3317 return strcmp ((char *) (s1->name), (char *) (s2->name));
3321 dump_macro_table (vat_main_t * vam)
3323 macro_sort_t *sort_me = 0, *sm;
3328 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
3330 vec_add2 (sort_me, sm, 1);
3331 sm->name = (u8 *)(p->key);
3332 sm->value = (u8 *) (p->value[0]);
3336 vec_sort_with_function (sort_me, macro_sort_cmp);
3338 if (vec_len (sort_me))
3339 print (vam->ofp, "%-15s%s", "Name", "Value");
3341 print (vam->ofp, "The macro table is empty...");
3343 for (i = 0; i < vec_len (sort_me); i++)
3344 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
3349 value_sort_cmp (void *a1, void *a2)
3351 name_sort_t *n1 = a1;
3352 name_sort_t *n2 = a2;
3354 if (n1->value < n2->value)
3356 if (n1->value > n2->value)
3363 dump_msg_api_table (vat_main_t * vam)
3365 api_main_t *am = vlibapi_get_main ();
3366 name_sort_t *nses = 0, *ns;
3371 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
3373 vec_add2 (nses, ns, 1);
3374 ns->name = (u8 *)(hp->key);
3375 ns->value = (u32) hp->value[0];
3379 vec_sort_with_function (nses, value_sort_cmp);
3381 for (i = 0; i < vec_len (nses); i++)
3382 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
3388 get_msg_id (vat_main_t * vam)
3393 if (unformat (vam->input, "%s", &name_and_crc))
3395 message_index = vl_msg_api_get_msg_index (name_and_crc);
3396 if (message_index == ~0)
3398 print (vam->ofp, " '%s' not found", name_and_crc);
3401 print (vam->ofp, " '%s' has message index %d",
3402 name_and_crc, message_index);
3405 errmsg ("name_and_crc required...");
3410 search_node_table (vat_main_t * vam)
3412 unformat_input_t *line_input = vam->input;
3415 vlib_node_t *node, *next_node;
3418 if (vam->graph_node_index_by_name == 0)
3420 print (vam->ofp, "Node table empty, issue get_node_graph...");
3424 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
3426 if (unformat (line_input, "%s", &node_to_find))
3428 vec_add1 (node_to_find, 0);
3429 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
3432 print (vam->ofp, "%s not found...", node_to_find);
3435 node = vam->graph_nodes[0][p[0]];
3436 print (vam->ofp, "[%d] %s", p[0], node->name);
3437 for (j = 0; j < vec_len (node->next_nodes); j++)
3439 if (node->next_nodes[j] != ~0)
3441 next_node = vam->graph_nodes[0][node->next_nodes[j]];
3442 print (vam->ofp, " [%d] %s", j, next_node->name);
3449 clib_warning ("parse error '%U'", format_unformat_error,
3455 vec_free (node_to_find);
3464 script (vat_main_t * vam)
3466 #if (VPP_API_TEST_BUILTIN==0)
3468 char *save_current_file;
3469 unformat_input_t save_input;
3470 jmp_buf save_jump_buf;
3471 u32 save_line_number;
3473 FILE *new_fp, *save_ifp;
3475 if (unformat (vam->input, "%s", &s))
3477 new_fp = fopen ((char *) s, "r");
3480 errmsg ("Couldn't open script file %s", s);
3487 errmsg ("Missing script name");
3491 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
3492 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
3493 save_ifp = vam->ifp;
3494 save_line_number = vam->input_line_number;
3495 save_current_file = (char *) vam->current_file;
3497 vam->input_line_number = 0;
3499 vam->current_file = s;
3502 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
3503 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
3504 vam->ifp = save_ifp;
3505 vam->input_line_number = save_line_number;
3506 vam->current_file = (u8 *) save_current_file;
3511 clib_warning ("use the exec command...");
3517 echo (vat_main_t * vam)
3519 print (vam->ofp, "%v", vam->input->buffer);
3523 /* List of API message constructors, CLI names map to api_xxx */
3524 #define foreach_vpe_api_msg \
3525 _(get_node_index, "node <node-name") \
3526 _(add_node_next, "node <node-name> next <next-node-name>") \
3527 _(show_version, "") \
3528 _(show_threads, "") \
3529 _(get_first_msg_id, "client <name>") \
3530 _(get_node_graph, " ") \
3531 _(get_next_index, "node-name <node-name> next-node-name <node-name>") \
3532 _(sock_init_shm, "size <nnn>") \
3533 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
3534 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> " \
3535 "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>") \
3536 _(session_rules_dump, "") \
3538 /* List of command functions, CLI names map directly to functions */
3539 #define foreach_cli_function \
3540 _(comment, "usage: comment <ignore-rest-of-line>") \
3541 _(dump_macro_table, "usage: dump_macro_table ") \
3542 _(dump_msg_api_table, "usage: dump_msg_api_table") \
3543 _(elog_setup, "usage: elog_setup [nevents, default 128K]") \
3544 _(elog_disable, "usage: elog_disable") \
3545 _(elog_enable, "usage: elog_enable") \
3546 _(elog_save, "usage: elog_save <filename>") \
3547 _(get_msg_id, "usage: get_msg_id name_and_crc") \
3548 _(echo, "usage: echo <message>") \
3549 _(exec, "usage: exec <vpe-debug-CLI-command>") \
3550 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>") \
3551 _(help, "usage: help") \
3552 _(q, "usage: quit") \
3553 _(quit, "usage: quit") \
3554 _(search_node_table, "usage: search_node_table <name>...") \
3555 _(set, "usage: set <variable-name> <value>") \
3556 _(script, "usage: script <file-name>") \
3557 _(statseg, "usage: statseg") \
3558 _(unset, "usage: unset <variable-name>")
3561 static void vl_api_##n##_t_handler_uni \
3562 (vl_api_##n##_t * mp) \
3564 vat_main_t * vam = &vat_main; \
3565 if (vam->json_output) { \
3566 vl_api_##n##_t_handler_json(mp); \
3568 vl_api_##n##_t_handler(mp); \
3571 foreach_vpe_api_reply_msg;
3572 #if VPP_API_TEST_BUILTIN == 0
3573 foreach_standalone_reply_msg;
3578 vat_api_hookup (vat_main_t * vam)
3581 vl_msg_api_set_handlers(VL_API_##N, #n, \
3582 vl_api_##n##_t_handler_uni, \
3584 vl_api_##n##_t_endian, \
3585 vl_api_##n##_t_print, \
3586 sizeof(vl_api_##n##_t), 1);
3587 foreach_vpe_api_reply_msg;
3588 #if VPP_API_TEST_BUILTIN == 0
3589 foreach_standalone_reply_msg;
3593 #if (VPP_API_TEST_BUILTIN==0)
3594 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
3596 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3598 vam->function_by_name = hash_create_string (0, sizeof (uword));
3600 vam->help_by_name = hash_create_string (0, sizeof (uword));
3603 /* API messages we can send */
3604 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
3605 foreach_vpe_api_msg;
3609 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
3610 foreach_vpe_api_msg;
3614 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
3615 foreach_cli_function;
3619 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
3620 foreach_cli_function;
3624 #if VPP_API_TEST_BUILTIN
3625 static clib_error_t *
3626 vat_api_hookup_shim (vlib_main_t * vm)
3628 vat_api_hookup (&vat_main);
3632 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
3636 * fd.io coding-style-patch-verification: ON
3639 * eval: (c-set-style "gnu")