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));
582 static void vl_api_show_version_reply_t_handler
583 (vl_api_show_version_reply_t * mp)
585 vat_main_t *vam = &vat_main;
586 i32 retval = ntohl (mp->retval);
590 errmsg (" program: %s", mp->program);
591 errmsg (" version: %s", mp->version);
592 errmsg (" build date: %s", mp->build_date);
593 errmsg ("build directory: %s", mp->build_directory);
595 vam->retval = retval;
596 vam->result_ready = 1;
599 static void vl_api_show_version_reply_t_handler_json
600 (vl_api_show_version_reply_t * mp)
602 vat_main_t *vam = &vat_main;
603 vat_json_node_t node;
605 vat_json_init_object (&node);
606 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
607 vat_json_object_add_string_copy (&node, "program", mp->program);
608 vat_json_object_add_string_copy (&node, "version", mp->version);
609 vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
610 vat_json_object_add_string_copy (&node, "build_directory",
611 mp->build_directory);
613 vat_json_print (vam->ofp, &node);
614 vat_json_free (&node);
616 vam->retval = ntohl (mp->retval);
617 vam->result_ready = 1;
620 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
621 #define vl_api_bridge_domain_details_t_print vl_noop_handler
623 static void vl_api_control_ping_reply_t_handler
624 (vl_api_control_ping_reply_t * mp)
626 vat_main_t *vam = &vat_main;
627 i32 retval = ntohl (mp->retval);
630 vam->async_errors += (retval < 0);
634 vam->retval = retval;
635 vam->result_ready = 1;
637 if (vam->socket_client_main)
638 vam->socket_client_main->control_pings_outstanding--;
641 static void vl_api_control_ping_reply_t_handler_json
642 (vl_api_control_ping_reply_t * mp)
644 vat_main_t *vam = &vat_main;
645 i32 retval = ntohl (mp->retval);
647 if (VAT_JSON_NONE != vam->json_tree.type)
649 vat_json_print (vam->ofp, &vam->json_tree);
650 vat_json_free (&vam->json_tree);
651 vam->json_tree.type = VAT_JSON_NONE;
656 vat_json_init_array (&vam->json_tree);
657 vat_json_print (vam->ofp, &vam->json_tree);
658 vam->json_tree.type = VAT_JSON_NONE;
661 vam->retval = retval;
662 vam->result_ready = 1;
666 static void vl_api_get_first_msg_id_reply_t_handler
667 (vl_api_get_first_msg_id_reply_t * mp)
669 vat_main_t *vam = &vat_main;
670 i32 retval = ntohl (mp->retval);
674 vam->async_errors += (retval < 0);
678 vam->retval = retval;
679 vam->result_ready = 1;
683 errmsg ("first message id %d", ntohs (mp->first_msg_id));
687 static void vl_api_get_first_msg_id_reply_t_handler_json
688 (vl_api_get_first_msg_id_reply_t * mp)
690 vat_main_t *vam = &vat_main;
691 vat_json_node_t node;
693 vat_json_init_object (&node);
694 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
695 vat_json_object_add_uint (&node, "first_msg_id",
696 (uint) ntohs (mp->first_msg_id));
698 vat_json_print (vam->ofp, &node);
699 vat_json_free (&node);
701 vam->retval = ntohl (mp->retval);
702 vam->result_ready = 1;
705 /* Format hex dump. */
707 format_hex_bytes (u8 * s, va_list * va)
709 u8 *bytes = va_arg (*va, u8 *);
710 int n_bytes = va_arg (*va, int);
713 /* Print short or long form depending on byte count. */
714 uword short_form = n_bytes <= 32;
715 u32 indent = format_get_indent (s);
720 for (i = 0; i < n_bytes; i++)
722 if (!short_form && (i % 32) == 0)
723 s = format (s, "%08x: ", i);
724 s = format (s, "%02x", bytes[i]);
725 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
726 s = format (s, "\n%U", format_white_space, indent);
733 * Generate boilerplate reply handlers, which
734 * dig the return value out of the xxx_reply_t API message,
735 * stick it into vam->retval, and set vam->result_ready
737 * Could also do this by pointing N message decode slots at
738 * a single function, but that could break in subtle ways.
741 #define foreach_standard_reply_retval_handler
744 static void vl_api_##n##_t_handler \
745 (vl_api_##n##_t * mp) \
747 vat_main_t * vam = &vat_main; \
748 i32 retval = ntohl(mp->retval); \
749 if (vam->async_mode) { \
750 vam->async_errors += (retval < 0); \
752 vam->retval = retval; \
753 vam->result_ready = 1; \
756 foreach_standard_reply_retval_handler;
760 static void vl_api_##n##_t_handler_json \
761 (vl_api_##n##_t * mp) \
763 vat_main_t * vam = &vat_main; \
764 vat_json_node_t node; \
765 vat_json_init_object(&node); \
766 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
767 vat_json_print(vam->ofp, &node); \
768 vam->retval = ntohl(mp->retval); \
769 vam->result_ready = 1; \
771 foreach_standard_reply_retval_handler;
775 * Table of message reply handlers, must include boilerplate handlers
779 #define foreach_vpe_api_reply_msg \
780 _ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
781 _ (CONTROL_PING_REPLY, control_ping_reply) \
782 _ (SHOW_VERSION_REPLY, show_version_reply) \
784 #define foreach_standalone_reply_msg \
792 #define STR_VTR_OP_CASE(op) \
793 case L2_VTR_ ## op: \
797 api_sw_interface_dump (vat_main_t *vam)
803 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
805 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
808 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
814 addr->function = x[3];
820 unformat_fib_path (unformat_input_t *input, va_list *args)
822 vat_main_t *vam = va_arg (*args, vat_main_t *);
823 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
824 u32 weight, preference;
825 mpls_label_t out_label;
827 clib_memset (path, 0, sizeof (*path));
829 path->sw_if_index = ~0;
833 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
835 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
836 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
839 path->proto = FIB_API_PATH_NH_PROTO_IP4;
841 else if (unformat (input, "%U %U",
842 unformat_vl_api_ip6_address,
843 &path->nh.address.ip6,
844 api_unformat_sw_if_index, vam, &path->sw_if_index))
846 path->proto = FIB_API_PATH_NH_PROTO_IP6;
848 else if (unformat (input, "weight %u", &weight))
850 path->weight = weight;
852 else if (unformat (input, "preference %u", &preference))
854 path->preference = preference;
856 else if (unformat (input, "%U next-hop-table %d",
857 unformat_vl_api_ip4_address,
858 &path->nh.address.ip4, &path->table_id))
860 path->proto = FIB_API_PATH_NH_PROTO_IP4;
862 else if (unformat (input, "%U next-hop-table %d",
863 unformat_vl_api_ip6_address,
864 &path->nh.address.ip6, &path->table_id))
866 path->proto = FIB_API_PATH_NH_PROTO_IP6;
868 else if (unformat (input, "%U",
869 unformat_vl_api_ip4_address, &path->nh.address.ip4))
872 * the recursive next-hops are by default in the default table
875 path->sw_if_index = ~0;
876 path->proto = FIB_API_PATH_NH_PROTO_IP4;
878 else if (unformat (input, "%U",
879 unformat_vl_api_ip6_address, &path->nh.address.ip6))
882 * the recursive next-hops are by default in the default table
885 path->sw_if_index = ~0;
886 path->proto = FIB_API_PATH_NH_PROTO_IP6;
888 else if (unformat (input, "resolve-via-host"))
890 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
892 else if (unformat (input, "resolve-via-attached"))
894 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
896 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
898 path->type = FIB_API_PATH_TYPE_LOCAL;
899 path->sw_if_index = ~0;
900 path->proto = FIB_API_PATH_NH_PROTO_IP4;
902 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
904 path->type = FIB_API_PATH_TYPE_LOCAL;
905 path->sw_if_index = ~0;
906 path->proto = FIB_API_PATH_NH_PROTO_IP6;
908 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
910 else if (unformat (input, "via-label %d", &path->nh.via_label))
912 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
913 path->sw_if_index = ~0;
915 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
917 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
918 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
920 else if (unformat (input, "local"))
922 path->type = FIB_API_PATH_TYPE_LOCAL;
924 else if (unformat (input, "out-labels"))
926 while (unformat (input, "%d", &out_label))
928 path->label_stack[path->n_labels].label = out_label;
929 path->label_stack[path->n_labels].is_uniform = 0;
930 path->label_stack[path->n_labels].ttl = 64;
934 else if (unformat (input, "via"))
936 /* new path, back up and return */
937 unformat_put_input (input);
938 unformat_put_input (input);
939 unformat_put_input (input);
940 unformat_put_input (input);
949 path->proto = ntohl (path->proto);
950 path->type = ntohl (path->type);
951 path->flags = ntohl (path->flags);
952 path->table_id = ntohl (path->table_id);
953 path->sw_if_index = ntohl (path->sw_if_index);
958 #define foreach_create_subif_bit \
965 _(outer_vlan_id_any) \
968 #define foreach_create_subif_flag \
973 _(4, "exact_match") \
974 _(5, "default_sub") \
975 _(6, "outer_vlan_id_any") \
976 _(7, "inner_vlan_id_any")
979 #define foreach_tcp_proto_field \
983 #define foreach_udp_proto_field \
987 #define foreach_ip4_proto_field \
999 u16 src_port, dst_port;
1002 #if VPP_API_TEST_BUILTIN == 0
1004 unformat_tcp_mask (unformat_input_t *input, va_list *args)
1006 u8 **maskp = va_arg (*args, u8 **);
1008 u8 found_something = 0;
1011 #define _(a) u8 a = 0;
1012 foreach_tcp_proto_field;
1015 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1019 #define _(a) else if (unformat (input, #a)) a = 1;
1020 foreach_tcp_proto_field
1025 #define _(a) found_something += a;
1026 foreach_tcp_proto_field;
1029 if (found_something == 0)
1032 vec_validate (mask, sizeof (*tcp) - 1);
1034 tcp = (tcp_header_t *) mask;
1038 clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
1039 foreach_tcp_proto_field;
1047 unformat_udp_mask (unformat_input_t *input, va_list *args)
1049 u8 **maskp = va_arg (*args, u8 **);
1051 u8 found_something = 0;
1054 #define _(a) u8 a = 0;
1055 foreach_udp_proto_field;
1058 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1062 #define _(a) else if (unformat (input, #a)) a = 1;
1063 foreach_udp_proto_field
1068 #define _(a) found_something += a;
1069 foreach_udp_proto_field;
1072 if (found_something == 0)
1075 vec_validate (mask, sizeof (*udp) - 1);
1077 udp = (udp_header_t *) mask;
1081 clib_memset (&udp->a, 0xff, sizeof (udp->a));
1082 foreach_udp_proto_field;
1090 unformat_l4_mask (unformat_input_t *input, va_list *args)
1092 u8 **maskp = va_arg (*args, u8 **);
1093 u16 src_port = 0, dst_port = 0;
1094 tcpudp_header_t *tcpudp;
1096 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1098 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
1100 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
1102 else if (unformat (input, "src_port"))
1104 else if (unformat (input, "dst_port"))
1110 if (!src_port && !dst_port)
1114 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
1116 tcpudp = (tcpudp_header_t *) mask;
1117 tcpudp->src_port = src_port;
1118 tcpudp->dst_port = dst_port;
1126 unformat_ip4_mask (unformat_input_t * input, va_list * args)
1128 u8 **maskp = va_arg (*args, u8 **);
1130 u8 found_something = 0;
1133 #define _(a) u8 a=0;
1134 foreach_ip4_proto_field;
1140 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1142 if (unformat (input, "version"))
1144 else if (unformat (input, "hdr_length"))
1146 else if (unformat (input, "src"))
1148 else if (unformat (input, "dst"))
1150 else if (unformat (input, "proto"))
1153 #define _(a) else if (unformat (input, #a)) a=1;
1154 foreach_ip4_proto_field
1160 #define _(a) found_something += a;
1161 foreach_ip4_proto_field;
1164 if (found_something == 0)
1167 vec_validate (mask, sizeof (*ip) - 1);
1169 ip = (ip4_header_t *) mask;
1171 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1172 foreach_ip4_proto_field;
1175 ip->ip_version_and_header_length = 0;
1178 ip->ip_version_and_header_length |= 0xF0;
1181 ip->ip_version_and_header_length |= 0x0F;
1187 #define foreach_ip6_proto_field \
1195 unformat_ip6_mask (unformat_input_t * input, va_list * args)
1197 u8 **maskp = va_arg (*args, u8 **);
1199 u8 found_something = 0;
1201 u32 ip_version_traffic_class_and_flow_label;
1203 #define _(a) u8 a=0;
1204 foreach_ip6_proto_field;
1207 u8 traffic_class = 0;
1210 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1212 if (unformat (input, "version"))
1214 else if (unformat (input, "traffic-class"))
1216 else if (unformat (input, "flow-label"))
1218 else if (unformat (input, "src"))
1220 else if (unformat (input, "dst"))
1222 else if (unformat (input, "proto"))
1225 #define _(a) else if (unformat (input, #a)) a=1;
1226 foreach_ip6_proto_field
1232 #define _(a) found_something += a;
1233 foreach_ip6_proto_field;
1236 if (found_something == 0)
1239 vec_validate (mask, sizeof (*ip) - 1);
1241 ip = (ip6_header_t *) mask;
1243 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1244 foreach_ip6_proto_field;
1247 ip_version_traffic_class_and_flow_label = 0;
1250 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1253 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1256 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1258 ip->ip_version_traffic_class_and_flow_label =
1259 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1266 unformat_l3_mask (unformat_input_t * input, va_list * args)
1268 u8 **maskp = va_arg (*args, u8 **);
1270 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1272 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
1274 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
1283 unformat_l2_mask (unformat_input_t * input, va_list * args)
1285 u8 **maskp = va_arg (*args, u8 **);
1300 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1302 if (unformat (input, "src"))
1304 else if (unformat (input, "dst"))
1306 else if (unformat (input, "proto"))
1308 else if (unformat (input, "tag1"))
1310 else if (unformat (input, "tag2"))
1312 else if (unformat (input, "ignore-tag1"))
1314 else if (unformat (input, "ignore-tag2"))
1316 else if (unformat (input, "cos1"))
1318 else if (unformat (input, "cos2"))
1320 else if (unformat (input, "dot1q"))
1322 else if (unformat (input, "dot1ad"))
1327 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1328 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1331 if (tag1 || ignore_tag1 || cos1 || dot1q)
1333 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1336 vec_validate (mask, len - 1);
1339 clib_memset (mask, 0xff, 6);
1342 clib_memset (mask + 6, 0xff, 6);
1346 /* inner vlan tag */
1355 mask[21] = mask[20] = 0xff;
1376 mask[16] = mask[17] = 0xff;
1386 mask[12] = mask[13] = 0xff;
1393 unformat_classify_mask (unformat_input_t * input, va_list * args)
1395 u8 **maskp = va_arg (*args, u8 **);
1396 u32 *skipp = va_arg (*args, u32 *);
1397 u32 *matchp = va_arg (*args, u32 *);
1405 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1407 if (unformat (input, "hex %U", unformat_hex_string, &mask))
1409 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
1411 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
1413 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
1427 if (mask || l2 || l3 || l4)
1431 /* "With a free Ethernet header in every package" */
1433 vec_validate (l2, 13);
1437 vec_append (mask, l3);
1442 vec_append (mask, l4);
1447 /* Scan forward looking for the first significant mask octet */
1448 for (i = 0; i < vec_len (mask); i++)
1452 /* compute (skip, match) params */
1453 *skipp = i / sizeof (u32x4);
1454 vec_delete (mask, *skipp * sizeof (u32x4), 0);
1456 /* Pad mask to an even multiple of the vector size */
1457 while (vec_len (mask) % sizeof (u32x4))
1460 match = vec_len (mask) / sizeof (u32x4);
1462 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
1464 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
1465 if (*tmp || *(tmp + 1))
1470 clib_warning ("BUG: match 0");
1472 _vec_len (mask) = match * sizeof (u32x4);
1482 #endif /* VPP_API_TEST_BUILTIN */
1484 #define foreach_l2_next \
1486 _(ethernet, ETHERNET_INPUT) \
1491 unformat_l2_next_index (unformat_input_t * input, va_list * args)
1493 u32 *miss_next_indexp = va_arg (*args, u32 *);
1498 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
1502 if (unformat (input, "%d", &tmp))
1511 *miss_next_indexp = next_index;
1515 #define foreach_ip_next \
1521 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
1523 u32 *miss_next_indexp = va_arg (*args, u32 *);
1528 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
1532 if (unformat (input, "%d", &tmp))
1541 *miss_next_indexp = next_index;
1545 #define foreach_acl_next \
1549 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
1551 u32 *miss_next_indexp = va_arg (*args, u32 *);
1556 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
1560 if (unformat (input, "permit"))
1565 else if (unformat (input, "%d", &tmp))
1574 *miss_next_indexp = next_index;
1579 unformat_policer_precolor (unformat_input_t * input, va_list * args)
1581 u32 *r = va_arg (*args, u32 *);
1583 if (unformat (input, "conform-color"))
1584 *r = POLICE_CONFORM;
1585 else if (unformat (input, "exceed-color"))
1593 #if VPP_API_TEST_BUILTIN == 0
1595 unformat_l4_match (unformat_input_t * input, va_list * args)
1597 u8 **matchp = va_arg (*args, u8 **);
1599 u8 *proto_header = 0;
1605 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1607 if (unformat (input, "src_port %d", &src_port))
1609 else if (unformat (input, "dst_port %d", &dst_port))
1615 h.src_port = clib_host_to_net_u16 (src_port);
1616 h.dst_port = clib_host_to_net_u16 (dst_port);
1617 vec_validate (proto_header, sizeof (h) - 1);
1618 memcpy (proto_header, &h, sizeof (h));
1620 *matchp = proto_header;
1626 unformat_ip4_match (unformat_input_t * input, va_list * args)
1628 u8 **matchp = va_arg (*args, u8 **);
1635 int src = 0, dst = 0;
1636 ip4_address_t src_val, dst_val;
1643 int fragment_id = 0;
1644 u32 fragment_id_val;
1650 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1652 if (unformat (input, "version %d", &version_val))
1654 else if (unformat (input, "hdr_length %d", &hdr_length_val))
1656 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
1658 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
1660 else if (unformat (input, "proto %d", &proto_val))
1662 else if (unformat (input, "tos %d", &tos_val))
1664 else if (unformat (input, "length %d", &length_val))
1666 else if (unformat (input, "fragment_id %d", &fragment_id_val))
1668 else if (unformat (input, "ttl %d", &ttl_val))
1670 else if (unformat (input, "checksum %d", &checksum_val))
1676 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
1677 + ttl + checksum == 0)
1681 * Aligned because we use the real comparison functions
1683 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1685 ip = (ip4_header_t *) match;
1687 /* These are realistically matched in practice */
1689 ip->src_address.as_u32 = src_val.as_u32;
1692 ip->dst_address.as_u32 = dst_val.as_u32;
1695 ip->protocol = proto_val;
1698 /* These are not, but they're included for completeness */
1700 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
1703 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
1709 ip->length = clib_host_to_net_u16 (length_val);
1715 ip->checksum = clib_host_to_net_u16 (checksum_val);
1722 unformat_ip6_match (unformat_input_t * input, va_list * args)
1724 u8 **matchp = va_arg (*args, u8 **);
1729 u8 traffic_class = 0;
1730 u32 traffic_class_val = 0;
1733 int src = 0, dst = 0;
1734 ip6_address_t src_val, dst_val;
1737 int payload_length = 0;
1738 u32 payload_length_val;
1741 u32 ip_version_traffic_class_and_flow_label;
1743 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1745 if (unformat (input, "version %d", &version_val))
1747 else if (unformat (input, "traffic_class %d", &traffic_class_val))
1749 else if (unformat (input, "flow_label %d", &flow_label_val))
1751 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
1753 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
1755 else if (unformat (input, "proto %d", &proto_val))
1757 else if (unformat (input, "payload_length %d", &payload_length_val))
1759 else if (unformat (input, "hop_limit %d", &hop_limit_val))
1765 if (version + traffic_class + flow_label + src + dst + proto +
1766 payload_length + hop_limit == 0)
1770 * Aligned because we use the real comparison functions
1772 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1774 ip = (ip6_header_t *) match;
1777 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
1780 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
1783 ip->protocol = proto_val;
1785 ip_version_traffic_class_and_flow_label = 0;
1788 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
1791 ip_version_traffic_class_and_flow_label |=
1792 (traffic_class_val & 0xFF) << 20;
1795 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
1797 ip->ip_version_traffic_class_and_flow_label =
1798 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1801 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
1804 ip->hop_limit = hop_limit_val;
1811 unformat_l3_match (unformat_input_t * input, va_list * args)
1813 u8 **matchp = va_arg (*args, u8 **);
1815 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1817 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
1819 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
1828 unformat_vlan_tag (unformat_input_t * input, va_list * args)
1830 u8 *tagp = va_arg (*args, u8 *);
1833 if (unformat (input, "%d", &tag))
1835 tagp[0] = (tag >> 8) & 0x0F;
1836 tagp[1] = tag & 0xFF;
1844 unformat_l2_match (unformat_input_t * input, va_list * args)
1846 u8 **matchp = va_arg (*args, u8 **);
1866 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1868 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
1871 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
1873 else if (unformat (input, "proto %U",
1874 unformat_ethernet_type_host_byte_order, &proto_val))
1876 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
1878 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
1880 else if (unformat (input, "ignore-tag1"))
1882 else if (unformat (input, "ignore-tag2"))
1884 else if (unformat (input, "cos1 %d", &cos1_val))
1886 else if (unformat (input, "cos2 %d", &cos2_val))
1891 if ((src + dst + proto + tag1 + tag2 +
1892 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1895 if (tag1 || ignore_tag1 || cos1)
1897 if (tag2 || ignore_tag2 || cos2)
1900 vec_validate_aligned (match, len - 1, sizeof (u32x4));
1903 clib_memcpy (match, dst_val, 6);
1906 clib_memcpy (match + 6, src_val, 6);
1910 /* inner vlan tag */
1911 match[19] = tag2_val[1];
1912 match[18] = tag2_val[0];
1914 match[18] |= (cos2_val & 0x7) << 5;
1917 match[21] = proto_val & 0xff;
1918 match[20] = proto_val >> 8;
1922 match[15] = tag1_val[1];
1923 match[14] = tag1_val[0];
1926 match[14] |= (cos1_val & 0x7) << 5;
1932 match[15] = tag1_val[1];
1933 match[14] = tag1_val[0];
1936 match[17] = proto_val & 0xff;
1937 match[16] = proto_val >> 8;
1940 match[14] |= (cos1_val & 0x7) << 5;
1946 match[18] |= (cos2_val & 0x7) << 5;
1948 match[14] |= (cos1_val & 0x7) << 5;
1951 match[13] = proto_val & 0xff;
1952 match[12] = proto_val >> 8;
1960 unformat_qos_source (unformat_input_t * input, va_list * args)
1962 int *qs = va_arg (*args, int *);
1964 if (unformat (input, "ip"))
1965 *qs = QOS_SOURCE_IP;
1966 else if (unformat (input, "mpls"))
1967 *qs = QOS_SOURCE_MPLS;
1968 else if (unformat (input, "ext"))
1969 *qs = QOS_SOURCE_EXT;
1970 else if (unformat (input, "vlan"))
1971 *qs = QOS_SOURCE_VLAN;
1980 api_unformat_classify_match (unformat_input_t * input, va_list * args)
1982 u8 **matchp = va_arg (*args, u8 **);
1983 u32 skip_n_vectors = va_arg (*args, u32);
1984 u32 match_n_vectors = va_arg (*args, u32);
1991 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1993 if (unformat (input, "hex %U", unformat_hex_string, &match))
1995 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
1997 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
1999 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
2013 if (match || l2 || l3 || l4)
2017 /* "Win a free Ethernet header in every packet" */
2019 vec_validate_aligned (l2, 13, sizeof (u32x4));
2023 vec_append_aligned (match, l3, sizeof (u32x4));
2028 vec_append_aligned (match, l4, sizeof (u32x4));
2033 /* Make sure the vector is big enough even if key is all 0's */
2034 vec_validate_aligned
2035 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
2038 /* Set size, include skipped vectors */
2039 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
2049 #define foreach_vtr_op \
2050 _ ("disable", L2_VTR_DISABLED) \
2051 _ ("push-1", L2_VTR_PUSH_1) \
2052 _ ("push-2", L2_VTR_PUSH_2) \
2053 _ ("pop-1", L2_VTR_POP_1) \
2054 _ ("pop-2", L2_VTR_POP_2) \
2055 _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
2056 _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
2057 _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
2058 _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
2061 api_show_version (vat_main_t *vam)
2063 vl_api_show_version_t *mp;
2066 M (SHOW_VERSION, mp);
2074 api_get_first_msg_id (vat_main_t *vam)
2076 vl_api_get_first_msg_id_t *mp;
2077 unformat_input_t *i = vam->input;
2082 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2084 if (unformat (i, "client %s", &name))
2092 errmsg ("missing client name");
2097 if (vec_len (name) > 63)
2099 errmsg ("client name too long");
2103 M (GET_FIRST_MSG_ID, mp);
2104 clib_memcpy (mp->name, name, vec_len (name));
2110 #define foreach_pbb_vtr_op \
2111 _("disable", L2_VTR_DISABLED) \
2112 _("pop", L2_VTR_POP_2) \
2113 _("push", L2_VTR_PUSH_2)
2116 api_sock_init_shm (vat_main_t * vam)
2118 #if VPP_API_TEST_BUILTIN == 0
2119 unformat_input_t *i = vam->input;
2120 vl_api_shm_elem_config_t *config = 0;
2121 u64 size = 64 << 20;
2124 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2126 if (unformat (i, "size %U", unformat_memory_size, &size))
2133 * Canned custom ring allocator config.
2134 * Should probably parse all of this
2136 vec_validate (config, 6);
2137 config[0].type = VL_API_VLIB_RING;
2138 config[0].size = 256;
2139 config[0].count = 32;
2141 config[1].type = VL_API_VLIB_RING;
2142 config[1].size = 1024;
2143 config[1].count = 16;
2145 config[2].type = VL_API_VLIB_RING;
2146 config[2].size = 4096;
2147 config[2].count = 2;
2149 config[3].type = VL_API_CLIENT_RING;
2150 config[3].size = 256;
2151 config[3].count = 32;
2153 config[4].type = VL_API_CLIENT_RING;
2154 config[4].size = 1024;
2155 config[4].count = 16;
2157 config[5].type = VL_API_CLIENT_RING;
2158 config[5].size = 4096;
2159 config[5].count = 2;
2161 config[6].type = VL_API_QUEUE;
2162 config[6].count = 128;
2163 config[6].size = sizeof (uword);
2165 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
2167 vam->client_index_invalid = 1;
2175 q_or_quit (vat_main_t * vam)
2177 #if VPP_API_TEST_BUILTIN == 0
2178 longjmp (vam->jump_buf, 1);
2180 return 0; /* not so much */
2184 q (vat_main_t * vam)
2186 return q_or_quit (vam);
2190 quit (vat_main_t * vam)
2192 return q_or_quit (vam);
2196 comment (vat_main_t * vam)
2202 elog_save (vat_main_t * vam)
2204 #if VPP_API_TEST_BUILTIN == 0
2205 elog_main_t *em = &vam->elog_main;
2206 unformat_input_t *i = vam->input;
2207 char *file, *chroot_file;
2208 clib_error_t *error;
2210 if (!unformat (i, "%s", &file))
2212 errmsg ("expected file name, got `%U'", format_unformat_error, i);
2216 /* It's fairly hard to get "../oopsie" through unformat; just in case */
2217 if (strstr (file, "..") || index (file, '/'))
2219 errmsg ("illegal characters in filename '%s'", file);
2223 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
2227 errmsg ("Saving %wd of %wd events to %s",
2228 elog_n_events_in_buffer (em),
2229 elog_buffer_capacity (em), chroot_file);
2231 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
2232 vec_free (chroot_file);
2235 clib_error_report (error);
2237 errmsg ("Use the vpp event loger...");
2244 elog_setup (vat_main_t * vam)
2246 #if VPP_API_TEST_BUILTIN == 0
2247 elog_main_t *em = &vam->elog_main;
2248 unformat_input_t *i = vam->input;
2249 u32 nevents = 128 << 10;
2251 (void) unformat (i, "nevents %d", &nevents);
2253 elog_init (em, nevents);
2254 vl_api_set_elog_main (em);
2255 vl_api_set_elog_trace_api_messages (1);
2256 errmsg ("Event logger initialized with %u events", nevents);
2258 errmsg ("Use the vpp event loger...");
2264 elog_enable (vat_main_t * vam)
2266 #if VPP_API_TEST_BUILTIN == 0
2267 elog_main_t *em = &vam->elog_main;
2269 elog_enable_disable (em, 1 /* enable */ );
2270 vl_api_set_elog_trace_api_messages (1);
2271 errmsg ("Event logger enabled...");
2273 errmsg ("Use the vpp event loger...");
2279 elog_disable (vat_main_t * vam)
2281 #if VPP_API_TEST_BUILTIN == 0
2282 elog_main_t *em = &vam->elog_main;
2284 elog_enable_disable (em, 0 /* enable */ );
2285 vl_api_set_elog_trace_api_messages (1);
2286 errmsg ("Event logger disabled...");
2288 errmsg ("Use the vpp event loger...");
2294 statseg (vat_main_t * vam)
2296 ssvm_private_t *ssvmp = &vam->stat_segment;
2297 ssvm_shared_header_t *shared_header = ssvmp->sh;
2298 vlib_counter_t **counters;
2299 u64 thread0_index1_packets;
2300 u64 thread0_index1_bytes;
2301 f64 vector_rate, input_rate;
2304 uword *counter_vector_by_name;
2305 if (vam->stat_segment_lockp == 0)
2307 errmsg ("Stat segment not mapped...");
2311 /* look up "/if/rx for sw_if_index 1 as a test */
2313 clib_spinlock_lock (vam->stat_segment_lockp);
2315 counter_vector_by_name = (uword *) shared_header->opaque[1];
2317 p = hash_get_mem (counter_vector_by_name, "/if/rx");
2320 clib_spinlock_unlock (vam->stat_segment_lockp);
2321 errmsg ("/if/tx not found?");
2325 /* Fish per-thread vector of combined counters from shared memory */
2326 counters = (vlib_counter_t **) p[0];
2328 if (vec_len (counters[0]) < 2)
2330 clib_spinlock_unlock (vam->stat_segment_lockp);
2331 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
2335 /* Read thread 0 sw_if_index 1 counter */
2336 thread0_index1_packets = counters[0][1].packets;
2337 thread0_index1_bytes = counters[0][1].bytes;
2339 p = hash_get_mem (counter_vector_by_name, "vector_rate");
2342 clib_spinlock_unlock (vam->stat_segment_lockp);
2343 errmsg ("vector_rate not found?");
2347 vector_rate = *(f64 *) (p[0]);
2348 p = hash_get_mem (counter_vector_by_name, "input_rate");
2351 clib_spinlock_unlock (vam->stat_segment_lockp);
2352 errmsg ("input_rate not found?");
2355 input_rate = *(f64 *) (p[0]);
2357 clib_spinlock_unlock (vam->stat_segment_lockp);
2359 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
2360 vector_rate, input_rate);
2361 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
2362 thread0_index1_packets, thread0_index1_bytes);
2368 cmd_cmp (void *a1, void *a2)
2373 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
2377 help (vat_main_t * vam)
2382 unformat_input_t *i = vam->input;
2385 if (unformat (i, "%s", &name))
2391 hs = hash_get_mem (vam->help_by_name, name);
2393 print (vam->ofp, "usage: %s %s", name, hs[0]);
2395 print (vam->ofp, "No such msg / command '%s'", name);
2400 print (vam->ofp, "Help is available for the following:");
2403 hash_foreach_pair (p, vam->function_by_name,
2405 vec_add1 (cmds, (u8 *)(p->key));
2409 vec_sort_with_function (cmds, cmd_cmp);
2411 for (j = 0; j < vec_len (cmds); j++)
2412 print (vam->ofp, "%s", cmds[j]);
2419 set (vat_main_t * vam)
2421 u8 *name = 0, *value = 0;
2422 unformat_input_t *i = vam->input;
2424 if (unformat (i, "%s", &name))
2426 /* The input buffer is a vector, not a string. */
2427 value = vec_dup (i->buffer);
2428 vec_delete (value, i->index, 0);
2429 /* Almost certainly has a trailing newline */
2430 if (value[vec_len (value) - 1] == '\n')
2431 value[vec_len (value) - 1] = 0;
2432 /* Make sure it's a proper string, one way or the other */
2433 vec_add1 (value, 0);
2434 (void) clib_macro_set_value (&vam->macro_main,
2435 (char *) name, (char *) value);
2438 errmsg ("usage: set <name> <value>");
2446 unset (vat_main_t * vam)
2450 if (unformat (vam->input, "%s", &name))
2451 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
2452 errmsg ("unset: %s wasn't set", name);
2465 macro_sort_cmp (void *a1, void *a2)
2467 macro_sort_t *s1 = a1;
2468 macro_sort_t *s2 = a2;
2470 return strcmp ((char *) (s1->name), (char *) (s2->name));
2474 dump_macro_table (vat_main_t * vam)
2476 macro_sort_t *sort_me = 0, *sm;
2481 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
2483 vec_add2 (sort_me, sm, 1);
2484 sm->name = (u8 *)(p->key);
2485 sm->value = (u8 *) (p->value[0]);
2489 vec_sort_with_function (sort_me, macro_sort_cmp);
2491 if (vec_len (sort_me))
2492 print (vam->ofp, "%-15s%s", "Name", "Value");
2494 print (vam->ofp, "The macro table is empty...");
2496 for (i = 0; i < vec_len (sort_me); i++)
2497 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
2502 value_sort_cmp (void *a1, void *a2)
2504 name_sort_t *n1 = a1;
2505 name_sort_t *n2 = a2;
2507 if (n1->value < n2->value)
2509 if (n1->value > n2->value)
2516 dump_msg_api_table (vat_main_t * vam)
2518 api_main_t *am = vlibapi_get_main ();
2519 name_sort_t *nses = 0, *ns;
2524 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
2526 vec_add2 (nses, ns, 1);
2527 ns->name = (u8 *)(hp->key);
2528 ns->value = (u32) hp->value[0];
2532 vec_sort_with_function (nses, value_sort_cmp);
2534 for (i = 0; i < vec_len (nses); i++)
2535 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
2541 get_msg_id (vat_main_t * vam)
2546 if (unformat (vam->input, "%s", &name_and_crc))
2548 message_index = vl_msg_api_get_msg_index (name_and_crc);
2549 if (message_index == ~0)
2551 print (vam->ofp, " '%s' not found", name_and_crc);
2554 print (vam->ofp, " '%s' has message index %d",
2555 name_and_crc, message_index);
2558 errmsg ("name_and_crc required...");
2563 search_node_table (vat_main_t * vam)
2565 unformat_input_t *line_input = vam->input;
2568 vlib_node_t *node, *next_node;
2571 if (vam->graph_node_index_by_name == 0)
2573 print (vam->ofp, "Node table empty, issue get_node_graph...");
2577 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2579 if (unformat (line_input, "%s", &node_to_find))
2581 vec_add1 (node_to_find, 0);
2582 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
2585 print (vam->ofp, "%s not found...", node_to_find);
2588 node = vam->graph_nodes[0][p[0]];
2589 print (vam->ofp, "[%d] %s", p[0], node->name);
2590 for (j = 0; j < vec_len (node->next_nodes); j++)
2592 if (node->next_nodes[j] != ~0)
2594 next_node = vam->graph_nodes[0][node->next_nodes[j]];
2595 print (vam->ofp, " [%d] %s", j, next_node->name);
2602 clib_warning ("parse error '%U'", format_unformat_error,
2608 vec_free (node_to_find);
2617 script (vat_main_t * vam)
2619 #if (VPP_API_TEST_BUILTIN==0)
2621 char *save_current_file;
2622 unformat_input_t save_input;
2623 jmp_buf save_jump_buf;
2624 u32 save_line_number;
2626 FILE *new_fp, *save_ifp;
2628 if (unformat (vam->input, "%s", &s))
2630 new_fp = fopen ((char *) s, "r");
2633 errmsg ("Couldn't open script file %s", s);
2640 errmsg ("Missing script name");
2644 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
2645 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
2646 save_ifp = vam->ifp;
2647 save_line_number = vam->input_line_number;
2648 save_current_file = (char *) vam->current_file;
2650 vam->input_line_number = 0;
2652 vam->current_file = s;
2655 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
2656 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
2657 vam->ifp = save_ifp;
2658 vam->input_line_number = save_line_number;
2659 vam->current_file = (u8 *) save_current_file;
2664 clib_warning ("use the exec command...");
2670 echo (vat_main_t * vam)
2672 print (vam->ofp, "%v", vam->input->buffer);
2676 int exec (vat_main_t *vam) __attribute__ ((weak));
2678 exec (vat_main_t *vam)
2683 /* List of API message constructors, CLI names map to api_xxx */
2684 #define foreach_vpe_api_msg \
2685 _(show_version, "") \
2686 _(get_first_msg_id, "client <name>") \
2687 _(sock_init_shm, "size <nnn>") \
2688 /* List of command functions, CLI names map directly to functions */
2689 #define foreach_cli_function \
2690 _(comment, "usage: comment <ignore-rest-of-line>") \
2691 _(dump_macro_table, "usage: dump_macro_table ") \
2692 _(dump_msg_api_table, "usage: dump_msg_api_table") \
2693 _(elog_setup, "usage: elog_setup [nevents, default 128K]") \
2694 _(elog_disable, "usage: elog_disable") \
2695 _(elog_enable, "usage: elog_enable") \
2696 _(elog_save, "usage: elog_save <filename>") \
2697 _(get_msg_id, "usage: get_msg_id name_and_crc") \
2698 _(echo, "usage: echo <message>") \
2699 _(help, "usage: help") \
2700 _(q, "usage: quit") \
2701 _(quit, "usage: quit") \
2702 _(search_node_table, "usage: search_node_table <name>...") \
2703 _(set, "usage: set <variable-name> <value>") \
2704 _(script, "usage: script <file-name>") \
2705 _(statseg, "usage: statseg") \
2706 _(unset, "usage: unset <variable-name>")
2709 static void vl_api_##n##_t_handler_uni \
2710 (vl_api_##n##_t * mp) \
2712 vat_main_t * vam = &vat_main; \
2713 if (vam->json_output) { \
2714 vl_api_##n##_t_handler_json(mp); \
2716 vl_api_##n##_t_handler(mp); \
2719 foreach_vpe_api_reply_msg;
2720 #if VPP_API_TEST_BUILTIN == 0
2721 foreach_standalone_reply_msg;
2726 vat_api_hookup (vat_main_t * vam)
2729 vl_msg_api_set_handlers(VL_API_##N, #n, \
2730 vl_api_##n##_t_handler_uni, \
2732 vl_api_##n##_t_endian, \
2733 vl_api_##n##_t_print, \
2734 sizeof(vl_api_##n##_t), 1);
2735 foreach_vpe_api_reply_msg;
2736 #if VPP_API_TEST_BUILTIN == 0
2737 foreach_standalone_reply_msg;
2741 #if (VPP_API_TEST_BUILTIN==0)
2742 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
2744 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
2746 vam->function_by_name = hash_create_string (0, sizeof (uword));
2748 vam->help_by_name = hash_create_string (0, sizeof (uword));
2751 /* API messages we can send */
2752 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
2753 foreach_vpe_api_msg;
2757 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2758 foreach_vpe_api_msg;
2762 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
2763 foreach_cli_function;
2767 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2768 foreach_cli_function;
2772 #if VPP_API_TEST_BUILTIN
2773 static clib_error_t *
2774 vat_api_hookup_shim (vlib_main_t * vm)
2776 vat_api_hookup (&vat_main);
2780 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
2784 * fd.io coding-style-patch-verification: ON
2787 * eval: (c-set-style "gnu")