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_get_first_msg_id_reply_t_handler
624 (vl_api_get_first_msg_id_reply_t * mp)
626 vat_main_t *vam = &vat_main;
627 i32 retval = ntohl (mp->retval);
631 vam->async_errors += (retval < 0);
635 vam->retval = retval;
636 vam->result_ready = 1;
640 errmsg ("first message id %d", ntohs (mp->first_msg_id));
644 static void vl_api_get_first_msg_id_reply_t_handler_json
645 (vl_api_get_first_msg_id_reply_t * mp)
647 vat_main_t *vam = &vat_main;
648 vat_json_node_t node;
650 vat_json_init_object (&node);
651 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652 vat_json_object_add_uint (&node, "first_msg_id",
653 (uint) ntohs (mp->first_msg_id));
655 vat_json_print (vam->ofp, &node);
656 vat_json_free (&node);
658 vam->retval = ntohl (mp->retval);
659 vam->result_ready = 1;
662 /* Format hex dump. */
664 format_hex_bytes (u8 * s, va_list * va)
666 u8 *bytes = va_arg (*va, u8 *);
667 int n_bytes = va_arg (*va, int);
670 /* Print short or long form depending on byte count. */
671 uword short_form = n_bytes <= 32;
672 u32 indent = format_get_indent (s);
677 for (i = 0; i < n_bytes; i++)
679 if (!short_form && (i % 32) == 0)
680 s = format (s, "%08x: ", i);
681 s = format (s, "%02x", bytes[i]);
682 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
683 s = format (s, "\n%U", format_white_space, indent);
690 * Generate boilerplate reply handlers, which
691 * dig the return value out of the xxx_reply_t API message,
692 * stick it into vam->retval, and set vam->result_ready
694 * Could also do this by pointing N message decode slots at
695 * a single function, but that could break in subtle ways.
698 #define foreach_standard_reply_retval_handler
701 static void vl_api_##n##_t_handler \
702 (vl_api_##n##_t * mp) \
704 vat_main_t * vam = &vat_main; \
705 i32 retval = ntohl(mp->retval); \
706 if (vam->async_mode) { \
707 vam->async_errors += (retval < 0); \
709 vam->retval = retval; \
710 vam->result_ready = 1; \
713 foreach_standard_reply_retval_handler;
717 static void vl_api_##n##_t_handler_json \
718 (vl_api_##n##_t * mp) \
720 vat_main_t * vam = &vat_main; \
721 vat_json_node_t node; \
722 vat_json_init_object(&node); \
723 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
724 vat_json_print(vam->ofp, &node); \
725 vam->retval = ntohl(mp->retval); \
726 vam->result_ready = 1; \
728 foreach_standard_reply_retval_handler;
732 * Table of message reply handlers, must include boilerplate handlers
736 #define foreach_vpe_api_reply_msg \
737 _ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
738 _ (SHOW_VERSION_REPLY, show_version_reply) \
740 #define foreach_standalone_reply_msg \
748 #define STR_VTR_OP_CASE(op) \
749 case L2_VTR_ ## op: \
753 api_sw_interface_dump (vat_main_t *vam)
759 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
761 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
764 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
770 addr->function = x[3];
776 unformat_fib_path (unformat_input_t *input, va_list *args)
778 vat_main_t *vam = va_arg (*args, vat_main_t *);
779 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
780 u32 weight, preference;
781 mpls_label_t out_label;
783 clib_memset (path, 0, sizeof (*path));
785 path->sw_if_index = ~0;
789 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
791 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
792 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
795 path->proto = FIB_API_PATH_NH_PROTO_IP4;
797 else if (unformat (input, "%U %U",
798 unformat_vl_api_ip6_address,
799 &path->nh.address.ip6,
800 api_unformat_sw_if_index, vam, &path->sw_if_index))
802 path->proto = FIB_API_PATH_NH_PROTO_IP6;
804 else if (unformat (input, "weight %u", &weight))
806 path->weight = weight;
808 else if (unformat (input, "preference %u", &preference))
810 path->preference = preference;
812 else if (unformat (input, "%U next-hop-table %d",
813 unformat_vl_api_ip4_address,
814 &path->nh.address.ip4, &path->table_id))
816 path->proto = FIB_API_PATH_NH_PROTO_IP4;
818 else if (unformat (input, "%U next-hop-table %d",
819 unformat_vl_api_ip6_address,
820 &path->nh.address.ip6, &path->table_id))
822 path->proto = FIB_API_PATH_NH_PROTO_IP6;
824 else if (unformat (input, "%U",
825 unformat_vl_api_ip4_address, &path->nh.address.ip4))
828 * the recursive next-hops are by default in the default table
831 path->sw_if_index = ~0;
832 path->proto = FIB_API_PATH_NH_PROTO_IP4;
834 else if (unformat (input, "%U",
835 unformat_vl_api_ip6_address, &path->nh.address.ip6))
838 * the recursive next-hops are by default in the default table
841 path->sw_if_index = ~0;
842 path->proto = FIB_API_PATH_NH_PROTO_IP6;
844 else if (unformat (input, "resolve-via-host"))
846 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
848 else if (unformat (input, "resolve-via-attached"))
850 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
852 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
854 path->type = FIB_API_PATH_TYPE_LOCAL;
855 path->sw_if_index = ~0;
856 path->proto = FIB_API_PATH_NH_PROTO_IP4;
858 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
860 path->type = FIB_API_PATH_TYPE_LOCAL;
861 path->sw_if_index = ~0;
862 path->proto = FIB_API_PATH_NH_PROTO_IP6;
864 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
866 else if (unformat (input, "via-label %d", &path->nh.via_label))
868 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
869 path->sw_if_index = ~0;
871 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
873 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
874 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
876 else if (unformat (input, "local"))
878 path->type = FIB_API_PATH_TYPE_LOCAL;
880 else if (unformat (input, "out-labels"))
882 while (unformat (input, "%d", &out_label))
884 path->label_stack[path->n_labels].label = out_label;
885 path->label_stack[path->n_labels].is_uniform = 0;
886 path->label_stack[path->n_labels].ttl = 64;
890 else if (unformat (input, "via"))
892 /* new path, back up and return */
893 unformat_put_input (input);
894 unformat_put_input (input);
895 unformat_put_input (input);
896 unformat_put_input (input);
905 path->proto = ntohl (path->proto);
906 path->type = ntohl (path->type);
907 path->flags = ntohl (path->flags);
908 path->table_id = ntohl (path->table_id);
909 path->sw_if_index = ntohl (path->sw_if_index);
914 #define foreach_create_subif_bit \
921 _(outer_vlan_id_any) \
924 #define foreach_create_subif_flag \
929 _(4, "exact_match") \
930 _(5, "default_sub") \
931 _(6, "outer_vlan_id_any") \
932 _(7, "inner_vlan_id_any")
935 #define foreach_tcp_proto_field \
939 #define foreach_udp_proto_field \
943 #define foreach_ip4_proto_field \
955 u16 src_port, dst_port;
958 #if VPP_API_TEST_BUILTIN == 0
960 unformat_tcp_mask (unformat_input_t *input, va_list *args)
962 u8 **maskp = va_arg (*args, u8 **);
964 u8 found_something = 0;
967 #define _(a) u8 a = 0;
968 foreach_tcp_proto_field;
971 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
975 #define _(a) else if (unformat (input, #a)) a = 1;
976 foreach_tcp_proto_field
981 #define _(a) found_something += a;
982 foreach_tcp_proto_field;
985 if (found_something == 0)
988 vec_validate (mask, sizeof (*tcp) - 1);
990 tcp = (tcp_header_t *) mask;
994 clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
995 foreach_tcp_proto_field;
1003 unformat_udp_mask (unformat_input_t *input, va_list *args)
1005 u8 **maskp = va_arg (*args, u8 **);
1007 u8 found_something = 0;
1010 #define _(a) u8 a = 0;
1011 foreach_udp_proto_field;
1014 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1018 #define _(a) else if (unformat (input, #a)) a = 1;
1019 foreach_udp_proto_field
1024 #define _(a) found_something += a;
1025 foreach_udp_proto_field;
1028 if (found_something == 0)
1031 vec_validate (mask, sizeof (*udp) - 1);
1033 udp = (udp_header_t *) mask;
1037 clib_memset (&udp->a, 0xff, sizeof (udp->a));
1038 foreach_udp_proto_field;
1046 unformat_l4_mask (unformat_input_t *input, va_list *args)
1048 u8 **maskp = va_arg (*args, u8 **);
1049 u16 src_port = 0, dst_port = 0;
1050 tcpudp_header_t *tcpudp;
1052 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1054 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
1056 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
1058 else if (unformat (input, "src_port"))
1060 else if (unformat (input, "dst_port"))
1066 if (!src_port && !dst_port)
1070 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
1072 tcpudp = (tcpudp_header_t *) mask;
1073 tcpudp->src_port = src_port;
1074 tcpudp->dst_port = dst_port;
1082 unformat_ip4_mask (unformat_input_t * input, va_list * args)
1084 u8 **maskp = va_arg (*args, u8 **);
1086 u8 found_something = 0;
1089 #define _(a) u8 a=0;
1090 foreach_ip4_proto_field;
1096 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1098 if (unformat (input, "version"))
1100 else if (unformat (input, "hdr_length"))
1102 else if (unformat (input, "src"))
1104 else if (unformat (input, "dst"))
1106 else if (unformat (input, "proto"))
1109 #define _(a) else if (unformat (input, #a)) a=1;
1110 foreach_ip4_proto_field
1116 #define _(a) found_something += a;
1117 foreach_ip4_proto_field;
1120 if (found_something == 0)
1123 vec_validate (mask, sizeof (*ip) - 1);
1125 ip = (ip4_header_t *) mask;
1127 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1128 foreach_ip4_proto_field;
1131 ip->ip_version_and_header_length = 0;
1134 ip->ip_version_and_header_length |= 0xF0;
1137 ip->ip_version_and_header_length |= 0x0F;
1143 #define foreach_ip6_proto_field \
1151 unformat_ip6_mask (unformat_input_t * input, va_list * args)
1153 u8 **maskp = va_arg (*args, u8 **);
1155 u8 found_something = 0;
1157 u32 ip_version_traffic_class_and_flow_label;
1159 #define _(a) u8 a=0;
1160 foreach_ip6_proto_field;
1163 u8 traffic_class = 0;
1166 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1168 if (unformat (input, "version"))
1170 else if (unformat (input, "traffic-class"))
1172 else if (unformat (input, "flow-label"))
1174 else if (unformat (input, "src"))
1176 else if (unformat (input, "dst"))
1178 else if (unformat (input, "proto"))
1181 #define _(a) else if (unformat (input, #a)) a=1;
1182 foreach_ip6_proto_field
1188 #define _(a) found_something += a;
1189 foreach_ip6_proto_field;
1192 if (found_something == 0)
1195 vec_validate (mask, sizeof (*ip) - 1);
1197 ip = (ip6_header_t *) mask;
1199 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1200 foreach_ip6_proto_field;
1203 ip_version_traffic_class_and_flow_label = 0;
1206 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1209 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1212 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1214 ip->ip_version_traffic_class_and_flow_label =
1215 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1222 unformat_l3_mask (unformat_input_t * input, va_list * args)
1224 u8 **maskp = va_arg (*args, u8 **);
1226 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1228 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
1230 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
1239 unformat_l2_mask (unformat_input_t * input, va_list * args)
1241 u8 **maskp = va_arg (*args, u8 **);
1256 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1258 if (unformat (input, "src"))
1260 else if (unformat (input, "dst"))
1262 else if (unformat (input, "proto"))
1264 else if (unformat (input, "tag1"))
1266 else if (unformat (input, "tag2"))
1268 else if (unformat (input, "ignore-tag1"))
1270 else if (unformat (input, "ignore-tag2"))
1272 else if (unformat (input, "cos1"))
1274 else if (unformat (input, "cos2"))
1276 else if (unformat (input, "dot1q"))
1278 else if (unformat (input, "dot1ad"))
1283 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1284 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1287 if (tag1 || ignore_tag1 || cos1 || dot1q)
1289 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1292 vec_validate (mask, len - 1);
1295 clib_memset (mask, 0xff, 6);
1298 clib_memset (mask + 6, 0xff, 6);
1302 /* inner vlan tag */
1311 mask[21] = mask[20] = 0xff;
1332 mask[16] = mask[17] = 0xff;
1342 mask[12] = mask[13] = 0xff;
1349 unformat_classify_mask (unformat_input_t * input, va_list * args)
1351 u8 **maskp = va_arg (*args, u8 **);
1352 u32 *skipp = va_arg (*args, u32 *);
1353 u32 *matchp = va_arg (*args, u32 *);
1361 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1363 if (unformat (input, "hex %U", unformat_hex_string, &mask))
1365 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
1367 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
1369 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
1383 if (mask || l2 || l3 || l4)
1387 /* "With a free Ethernet header in every package" */
1389 vec_validate (l2, 13);
1393 vec_append (mask, l3);
1398 vec_append (mask, l4);
1403 /* Scan forward looking for the first significant mask octet */
1404 for (i = 0; i < vec_len (mask); i++)
1408 /* compute (skip, match) params */
1409 *skipp = i / sizeof (u32x4);
1410 vec_delete (mask, *skipp * sizeof (u32x4), 0);
1412 /* Pad mask to an even multiple of the vector size */
1413 while (vec_len (mask) % sizeof (u32x4))
1416 match = vec_len (mask) / sizeof (u32x4);
1418 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
1420 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
1421 if (*tmp || *(tmp + 1))
1426 clib_warning ("BUG: match 0");
1428 _vec_len (mask) = match * sizeof (u32x4);
1438 #endif /* VPP_API_TEST_BUILTIN */
1440 #define foreach_l2_next \
1442 _(ethernet, ETHERNET_INPUT) \
1447 unformat_l2_next_index (unformat_input_t * input, va_list * args)
1449 u32 *miss_next_indexp = va_arg (*args, u32 *);
1454 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
1458 if (unformat (input, "%d", &tmp))
1467 *miss_next_indexp = next_index;
1471 #define foreach_ip_next \
1477 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
1479 u32 *miss_next_indexp = va_arg (*args, u32 *);
1484 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
1488 if (unformat (input, "%d", &tmp))
1497 *miss_next_indexp = next_index;
1501 #define foreach_acl_next \
1505 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
1507 u32 *miss_next_indexp = va_arg (*args, u32 *);
1512 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
1516 if (unformat (input, "permit"))
1521 else if (unformat (input, "%d", &tmp))
1530 *miss_next_indexp = next_index;
1535 unformat_policer_precolor (unformat_input_t * input, va_list * args)
1537 u32 *r = va_arg (*args, u32 *);
1539 if (unformat (input, "conform-color"))
1540 *r = POLICE_CONFORM;
1541 else if (unformat (input, "exceed-color"))
1549 #if VPP_API_TEST_BUILTIN == 0
1551 unformat_l4_match (unformat_input_t * input, va_list * args)
1553 u8 **matchp = va_arg (*args, u8 **);
1555 u8 *proto_header = 0;
1561 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1563 if (unformat (input, "src_port %d", &src_port))
1565 else if (unformat (input, "dst_port %d", &dst_port))
1571 h.src_port = clib_host_to_net_u16 (src_port);
1572 h.dst_port = clib_host_to_net_u16 (dst_port);
1573 vec_validate (proto_header, sizeof (h) - 1);
1574 memcpy (proto_header, &h, sizeof (h));
1576 *matchp = proto_header;
1582 unformat_ip4_match (unformat_input_t * input, va_list * args)
1584 u8 **matchp = va_arg (*args, u8 **);
1591 int src = 0, dst = 0;
1592 ip4_address_t src_val, dst_val;
1599 int fragment_id = 0;
1600 u32 fragment_id_val;
1606 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1608 if (unformat (input, "version %d", &version_val))
1610 else if (unformat (input, "hdr_length %d", &hdr_length_val))
1612 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
1614 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
1616 else if (unformat (input, "proto %d", &proto_val))
1618 else if (unformat (input, "tos %d", &tos_val))
1620 else if (unformat (input, "length %d", &length_val))
1622 else if (unformat (input, "fragment_id %d", &fragment_id_val))
1624 else if (unformat (input, "ttl %d", &ttl_val))
1626 else if (unformat (input, "checksum %d", &checksum_val))
1632 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
1633 + ttl + checksum == 0)
1637 * Aligned because we use the real comparison functions
1639 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1641 ip = (ip4_header_t *) match;
1643 /* These are realistically matched in practice */
1645 ip->src_address.as_u32 = src_val.as_u32;
1648 ip->dst_address.as_u32 = dst_val.as_u32;
1651 ip->protocol = proto_val;
1654 /* These are not, but they're included for completeness */
1656 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
1659 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
1665 ip->length = clib_host_to_net_u16 (length_val);
1671 ip->checksum = clib_host_to_net_u16 (checksum_val);
1678 unformat_ip6_match (unformat_input_t * input, va_list * args)
1680 u8 **matchp = va_arg (*args, u8 **);
1685 u8 traffic_class = 0;
1686 u32 traffic_class_val = 0;
1689 int src = 0, dst = 0;
1690 ip6_address_t src_val, dst_val;
1693 int payload_length = 0;
1694 u32 payload_length_val;
1697 u32 ip_version_traffic_class_and_flow_label;
1699 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1701 if (unformat (input, "version %d", &version_val))
1703 else if (unformat (input, "traffic_class %d", &traffic_class_val))
1705 else if (unformat (input, "flow_label %d", &flow_label_val))
1707 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
1709 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
1711 else if (unformat (input, "proto %d", &proto_val))
1713 else if (unformat (input, "payload_length %d", &payload_length_val))
1715 else if (unformat (input, "hop_limit %d", &hop_limit_val))
1721 if (version + traffic_class + flow_label + src + dst + proto +
1722 payload_length + hop_limit == 0)
1726 * Aligned because we use the real comparison functions
1728 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1730 ip = (ip6_header_t *) match;
1733 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
1736 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
1739 ip->protocol = proto_val;
1741 ip_version_traffic_class_and_flow_label = 0;
1744 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
1747 ip_version_traffic_class_and_flow_label |=
1748 (traffic_class_val & 0xFF) << 20;
1751 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
1753 ip->ip_version_traffic_class_and_flow_label =
1754 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1757 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
1760 ip->hop_limit = hop_limit_val;
1767 unformat_l3_match (unformat_input_t * input, va_list * args)
1769 u8 **matchp = va_arg (*args, u8 **);
1771 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1773 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
1775 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
1784 unformat_vlan_tag (unformat_input_t * input, va_list * args)
1786 u8 *tagp = va_arg (*args, u8 *);
1789 if (unformat (input, "%d", &tag))
1791 tagp[0] = (tag >> 8) & 0x0F;
1792 tagp[1] = tag & 0xFF;
1800 unformat_l2_match (unformat_input_t * input, va_list * args)
1802 u8 **matchp = va_arg (*args, u8 **);
1822 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1824 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
1827 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
1829 else if (unformat (input, "proto %U",
1830 unformat_ethernet_type_host_byte_order, &proto_val))
1832 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
1834 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
1836 else if (unformat (input, "ignore-tag1"))
1838 else if (unformat (input, "ignore-tag2"))
1840 else if (unformat (input, "cos1 %d", &cos1_val))
1842 else if (unformat (input, "cos2 %d", &cos2_val))
1847 if ((src + dst + proto + tag1 + tag2 +
1848 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1851 if (tag1 || ignore_tag1 || cos1)
1853 if (tag2 || ignore_tag2 || cos2)
1856 vec_validate_aligned (match, len - 1, sizeof (u32x4));
1859 clib_memcpy (match, dst_val, 6);
1862 clib_memcpy (match + 6, src_val, 6);
1866 /* inner vlan tag */
1867 match[19] = tag2_val[1];
1868 match[18] = tag2_val[0];
1870 match[18] |= (cos2_val & 0x7) << 5;
1873 match[21] = proto_val & 0xff;
1874 match[20] = proto_val >> 8;
1878 match[15] = tag1_val[1];
1879 match[14] = tag1_val[0];
1882 match[14] |= (cos1_val & 0x7) << 5;
1888 match[15] = tag1_val[1];
1889 match[14] = tag1_val[0];
1892 match[17] = proto_val & 0xff;
1893 match[16] = proto_val >> 8;
1896 match[14] |= (cos1_val & 0x7) << 5;
1902 match[18] |= (cos2_val & 0x7) << 5;
1904 match[14] |= (cos1_val & 0x7) << 5;
1907 match[13] = proto_val & 0xff;
1908 match[12] = proto_val >> 8;
1916 unformat_qos_source (unformat_input_t * input, va_list * args)
1918 int *qs = va_arg (*args, int *);
1920 if (unformat (input, "ip"))
1921 *qs = QOS_SOURCE_IP;
1922 else if (unformat (input, "mpls"))
1923 *qs = QOS_SOURCE_MPLS;
1924 else if (unformat (input, "ext"))
1925 *qs = QOS_SOURCE_EXT;
1926 else if (unformat (input, "vlan"))
1927 *qs = QOS_SOURCE_VLAN;
1936 api_unformat_classify_match (unformat_input_t * input, va_list * args)
1938 u8 **matchp = va_arg (*args, u8 **);
1939 u32 skip_n_vectors = va_arg (*args, u32);
1940 u32 match_n_vectors = va_arg (*args, u32);
1947 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1949 if (unformat (input, "hex %U", unformat_hex_string, &match))
1951 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
1953 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
1955 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
1969 if (match || l2 || l3 || l4)
1973 /* "Win a free Ethernet header in every packet" */
1975 vec_validate_aligned (l2, 13, sizeof (u32x4));
1979 vec_append_aligned (match, l3, sizeof (u32x4));
1984 vec_append_aligned (match, l4, sizeof (u32x4));
1989 /* Make sure the vector is big enough even if key is all 0's */
1990 vec_validate_aligned
1991 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
1994 /* Set size, include skipped vectors */
1995 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
2005 #define foreach_vtr_op \
2006 _ ("disable", L2_VTR_DISABLED) \
2007 _ ("push-1", L2_VTR_PUSH_1) \
2008 _ ("push-2", L2_VTR_PUSH_2) \
2009 _ ("pop-1", L2_VTR_POP_1) \
2010 _ ("pop-2", L2_VTR_POP_2) \
2011 _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
2012 _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
2013 _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
2014 _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
2017 api_show_version (vat_main_t *vam)
2019 vl_api_show_version_t *mp;
2022 M (SHOW_VERSION, mp);
2030 api_get_first_msg_id (vat_main_t *vam)
2032 vl_api_get_first_msg_id_t *mp;
2033 unformat_input_t *i = vam->input;
2038 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2040 if (unformat (i, "client %s", &name))
2048 errmsg ("missing client name");
2053 if (vec_len (name) > 63)
2055 errmsg ("client name too long");
2059 M (GET_FIRST_MSG_ID, mp);
2060 clib_memcpy (mp->name, name, vec_len (name));
2066 #define foreach_pbb_vtr_op \
2067 _("disable", L2_VTR_DISABLED) \
2068 _("pop", L2_VTR_POP_2) \
2069 _("push", L2_VTR_PUSH_2)
2072 api_sock_init_shm (vat_main_t * vam)
2074 #if VPP_API_TEST_BUILTIN == 0
2075 unformat_input_t *i = vam->input;
2076 vl_api_shm_elem_config_t *config = 0;
2077 u64 size = 64 << 20;
2080 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2082 if (unformat (i, "size %U", unformat_memory_size, &size))
2089 * Canned custom ring allocator config.
2090 * Should probably parse all of this
2092 vec_validate (config, 6);
2093 config[0].type = VL_API_VLIB_RING;
2094 config[0].size = 256;
2095 config[0].count = 32;
2097 config[1].type = VL_API_VLIB_RING;
2098 config[1].size = 1024;
2099 config[1].count = 16;
2101 config[2].type = VL_API_VLIB_RING;
2102 config[2].size = 4096;
2103 config[2].count = 2;
2105 config[3].type = VL_API_CLIENT_RING;
2106 config[3].size = 256;
2107 config[3].count = 32;
2109 config[4].type = VL_API_CLIENT_RING;
2110 config[4].size = 1024;
2111 config[4].count = 16;
2113 config[5].type = VL_API_CLIENT_RING;
2114 config[5].size = 4096;
2115 config[5].count = 2;
2117 config[6].type = VL_API_QUEUE;
2118 config[6].count = 128;
2119 config[6].size = sizeof (uword);
2121 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
2123 vam->client_index_invalid = 1;
2131 q_or_quit (vat_main_t * vam)
2133 #if VPP_API_TEST_BUILTIN == 0
2134 longjmp (vam->jump_buf, 1);
2136 return 0; /* not so much */
2140 q (vat_main_t * vam)
2142 return q_or_quit (vam);
2146 quit (vat_main_t * vam)
2148 return q_or_quit (vam);
2152 comment (vat_main_t * vam)
2158 elog_save (vat_main_t * vam)
2160 #if VPP_API_TEST_BUILTIN == 0
2161 elog_main_t *em = &vam->elog_main;
2162 unformat_input_t *i = vam->input;
2163 char *file, *chroot_file;
2164 clib_error_t *error;
2166 if (!unformat (i, "%s", &file))
2168 errmsg ("expected file name, got `%U'", format_unformat_error, i);
2172 /* It's fairly hard to get "../oopsie" through unformat; just in case */
2173 if (strstr (file, "..") || index (file, '/'))
2175 errmsg ("illegal characters in filename '%s'", file);
2179 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
2183 errmsg ("Saving %wd of %wd events to %s",
2184 elog_n_events_in_buffer (em),
2185 elog_buffer_capacity (em), chroot_file);
2187 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
2188 vec_free (chroot_file);
2191 clib_error_report (error);
2193 errmsg ("Use the vpp event loger...");
2200 elog_setup (vat_main_t * vam)
2202 #if VPP_API_TEST_BUILTIN == 0
2203 elog_main_t *em = &vam->elog_main;
2204 unformat_input_t *i = vam->input;
2205 u32 nevents = 128 << 10;
2207 (void) unformat (i, "nevents %d", &nevents);
2209 elog_init (em, nevents);
2210 vl_api_set_elog_main (em);
2211 vl_api_set_elog_trace_api_messages (1);
2212 errmsg ("Event logger initialized with %u events", nevents);
2214 errmsg ("Use the vpp event loger...");
2220 elog_enable (vat_main_t * vam)
2222 #if VPP_API_TEST_BUILTIN == 0
2223 elog_main_t *em = &vam->elog_main;
2225 elog_enable_disable (em, 1 /* enable */ );
2226 vl_api_set_elog_trace_api_messages (1);
2227 errmsg ("Event logger enabled...");
2229 errmsg ("Use the vpp event loger...");
2235 elog_disable (vat_main_t * vam)
2237 #if VPP_API_TEST_BUILTIN == 0
2238 elog_main_t *em = &vam->elog_main;
2240 elog_enable_disable (em, 0 /* enable */ );
2241 vl_api_set_elog_trace_api_messages (1);
2242 errmsg ("Event logger disabled...");
2244 errmsg ("Use the vpp event loger...");
2250 statseg (vat_main_t * vam)
2252 ssvm_private_t *ssvmp = &vam->stat_segment;
2253 ssvm_shared_header_t *shared_header = ssvmp->sh;
2254 vlib_counter_t **counters;
2255 u64 thread0_index1_packets;
2256 u64 thread0_index1_bytes;
2257 f64 vector_rate, input_rate;
2260 uword *counter_vector_by_name;
2261 if (vam->stat_segment_lockp == 0)
2263 errmsg ("Stat segment not mapped...");
2267 /* look up "/if/rx for sw_if_index 1 as a test */
2269 clib_spinlock_lock (vam->stat_segment_lockp);
2271 counter_vector_by_name = (uword *) shared_header->opaque[1];
2273 p = hash_get_mem (counter_vector_by_name, "/if/rx");
2276 clib_spinlock_unlock (vam->stat_segment_lockp);
2277 errmsg ("/if/tx not found?");
2281 /* Fish per-thread vector of combined counters from shared memory */
2282 counters = (vlib_counter_t **) p[0];
2284 if (vec_len (counters[0]) < 2)
2286 clib_spinlock_unlock (vam->stat_segment_lockp);
2287 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
2291 /* Read thread 0 sw_if_index 1 counter */
2292 thread0_index1_packets = counters[0][1].packets;
2293 thread0_index1_bytes = counters[0][1].bytes;
2295 p = hash_get_mem (counter_vector_by_name, "vector_rate");
2298 clib_spinlock_unlock (vam->stat_segment_lockp);
2299 errmsg ("vector_rate not found?");
2303 vector_rate = *(f64 *) (p[0]);
2304 p = hash_get_mem (counter_vector_by_name, "input_rate");
2307 clib_spinlock_unlock (vam->stat_segment_lockp);
2308 errmsg ("input_rate not found?");
2311 input_rate = *(f64 *) (p[0]);
2313 clib_spinlock_unlock (vam->stat_segment_lockp);
2315 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
2316 vector_rate, input_rate);
2317 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
2318 thread0_index1_packets, thread0_index1_bytes);
2324 cmd_cmp (void *a1, void *a2)
2329 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
2333 help (vat_main_t * vam)
2338 unformat_input_t *i = vam->input;
2341 if (unformat (i, "%s", &name))
2347 hs = hash_get_mem (vam->help_by_name, name);
2349 print (vam->ofp, "usage: %s %s", name, hs[0]);
2351 print (vam->ofp, "No such msg / command '%s'", name);
2356 print (vam->ofp, "Help is available for the following:");
2359 hash_foreach_pair (p, vam->function_by_name,
2361 vec_add1 (cmds, (u8 *)(p->key));
2365 vec_sort_with_function (cmds, cmd_cmp);
2367 for (j = 0; j < vec_len (cmds); j++)
2368 print (vam->ofp, "%s", cmds[j]);
2375 set (vat_main_t * vam)
2377 u8 *name = 0, *value = 0;
2378 unformat_input_t *i = vam->input;
2380 if (unformat (i, "%s", &name))
2382 /* The input buffer is a vector, not a string. */
2383 value = vec_dup (i->buffer);
2384 vec_delete (value, i->index, 0);
2385 /* Almost certainly has a trailing newline */
2386 if (value[vec_len (value) - 1] == '\n')
2387 value[vec_len (value) - 1] = 0;
2388 /* Make sure it's a proper string, one way or the other */
2389 vec_add1 (value, 0);
2390 (void) clib_macro_set_value (&vam->macro_main,
2391 (char *) name, (char *) value);
2394 errmsg ("usage: set <name> <value>");
2402 unset (vat_main_t * vam)
2406 if (unformat (vam->input, "%s", &name))
2407 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
2408 errmsg ("unset: %s wasn't set", name);
2421 macro_sort_cmp (void *a1, void *a2)
2423 macro_sort_t *s1 = a1;
2424 macro_sort_t *s2 = a2;
2426 return strcmp ((char *) (s1->name), (char *) (s2->name));
2430 dump_macro_table (vat_main_t * vam)
2432 macro_sort_t *sort_me = 0, *sm;
2437 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
2439 vec_add2 (sort_me, sm, 1);
2440 sm->name = (u8 *)(p->key);
2441 sm->value = (u8 *) (p->value[0]);
2445 vec_sort_with_function (sort_me, macro_sort_cmp);
2447 if (vec_len (sort_me))
2448 print (vam->ofp, "%-15s%s", "Name", "Value");
2450 print (vam->ofp, "The macro table is empty...");
2452 for (i = 0; i < vec_len (sort_me); i++)
2453 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
2458 value_sort_cmp (void *a1, void *a2)
2460 name_sort_t *n1 = a1;
2461 name_sort_t *n2 = a2;
2463 if (n1->value < n2->value)
2465 if (n1->value > n2->value)
2472 dump_msg_api_table (vat_main_t * vam)
2474 api_main_t *am = vlibapi_get_main ();
2475 name_sort_t *nses = 0, *ns;
2480 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
2482 vec_add2 (nses, ns, 1);
2483 ns->name = (u8 *)(hp->key);
2484 ns->value = (u32) hp->value[0];
2488 vec_sort_with_function (nses, value_sort_cmp);
2490 for (i = 0; i < vec_len (nses); i++)
2491 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
2497 get_msg_id (vat_main_t * vam)
2502 if (unformat (vam->input, "%s", &name_and_crc))
2504 message_index = vl_msg_api_get_msg_index (name_and_crc);
2505 if (message_index == ~0)
2507 print (vam->ofp, " '%s' not found", name_and_crc);
2510 print (vam->ofp, " '%s' has message index %d",
2511 name_and_crc, message_index);
2514 errmsg ("name_and_crc required...");
2519 search_node_table (vat_main_t * vam)
2521 unformat_input_t *line_input = vam->input;
2524 vlib_node_t *node, *next_node;
2527 if (vam->graph_node_index_by_name == 0)
2529 print (vam->ofp, "Node table empty, issue get_node_graph...");
2533 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2535 if (unformat (line_input, "%s", &node_to_find))
2537 vec_add1 (node_to_find, 0);
2538 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
2541 print (vam->ofp, "%s not found...", node_to_find);
2544 node = vam->graph_nodes[0][p[0]];
2545 print (vam->ofp, "[%d] %s", p[0], node->name);
2546 for (j = 0; j < vec_len (node->next_nodes); j++)
2548 if (node->next_nodes[j] != ~0)
2550 next_node = vam->graph_nodes[0][node->next_nodes[j]];
2551 print (vam->ofp, " [%d] %s", j, next_node->name);
2558 clib_warning ("parse error '%U'", format_unformat_error,
2564 vec_free (node_to_find);
2573 script (vat_main_t * vam)
2575 #if (VPP_API_TEST_BUILTIN==0)
2577 char *save_current_file;
2578 unformat_input_t save_input;
2579 jmp_buf save_jump_buf;
2580 u32 save_line_number;
2582 FILE *new_fp, *save_ifp;
2584 if (unformat (vam->input, "%s", &s))
2586 new_fp = fopen ((char *) s, "r");
2589 errmsg ("Couldn't open script file %s", s);
2596 errmsg ("Missing script name");
2600 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
2601 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
2602 save_ifp = vam->ifp;
2603 save_line_number = vam->input_line_number;
2604 save_current_file = (char *) vam->current_file;
2606 vam->input_line_number = 0;
2608 vam->current_file = s;
2611 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
2612 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
2613 vam->ifp = save_ifp;
2614 vam->input_line_number = save_line_number;
2615 vam->current_file = (u8 *) save_current_file;
2620 clib_warning ("use the exec command...");
2626 echo (vat_main_t * vam)
2628 print (vam->ofp, "%v", vam->input->buffer);
2632 int exec (vat_main_t *vam) __attribute__ ((weak));
2634 exec (vat_main_t *vam)
2639 /* List of API message constructors, CLI names map to api_xxx */
2640 #define foreach_vpe_api_msg \
2641 _(show_version, "") \
2642 _(get_first_msg_id, "client <name>") \
2643 _(sock_init_shm, "size <nnn>") \
2644 /* List of command functions, CLI names map directly to functions */
2645 #define foreach_cli_function \
2646 _(comment, "usage: comment <ignore-rest-of-line>") \
2647 _(dump_macro_table, "usage: dump_macro_table ") \
2648 _(dump_msg_api_table, "usage: dump_msg_api_table") \
2649 _(elog_setup, "usage: elog_setup [nevents, default 128K]") \
2650 _(elog_disable, "usage: elog_disable") \
2651 _(elog_enable, "usage: elog_enable") \
2652 _(elog_save, "usage: elog_save <filename>") \
2653 _(get_msg_id, "usage: get_msg_id name_and_crc") \
2654 _(echo, "usage: echo <message>") \
2655 _(help, "usage: help") \
2656 _(q, "usage: quit") \
2657 _(quit, "usage: quit") \
2658 _(search_node_table, "usage: search_node_table <name>...") \
2659 _(set, "usage: set <variable-name> <value>") \
2660 _(script, "usage: script <file-name>") \
2661 _(statseg, "usage: statseg") \
2662 _(unset, "usage: unset <variable-name>")
2665 static void vl_api_##n##_t_handler_uni \
2666 (vl_api_##n##_t * mp) \
2668 vat_main_t * vam = &vat_main; \
2669 if (vam->json_output) { \
2670 vl_api_##n##_t_handler_json(mp); \
2672 vl_api_##n##_t_handler(mp); \
2675 foreach_vpe_api_reply_msg;
2676 #if VPP_API_TEST_BUILTIN == 0
2677 foreach_standalone_reply_msg;
2682 vat_api_hookup (vat_main_t * vam)
2685 vl_msg_api_set_handlers(VL_API_##N, #n, \
2686 vl_api_##n##_t_handler_uni, \
2688 vl_api_##n##_t_endian, \
2689 vl_api_##n##_t_print, \
2690 sizeof(vl_api_##n##_t), 1);
2691 foreach_vpe_api_reply_msg;
2692 #if VPP_API_TEST_BUILTIN == 0
2693 foreach_standalone_reply_msg;
2697 #if (VPP_API_TEST_BUILTIN==0)
2698 vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
2700 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
2702 vam->function_by_name = hash_create_string (0, sizeof (uword));
2704 vam->help_by_name = hash_create_string (0, sizeof (uword));
2707 /* API messages we can send */
2708 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
2709 foreach_vpe_api_msg;
2713 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2714 foreach_vpe_api_msg;
2718 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
2719 foreach_cli_function;
2723 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2724 foreach_cli_function;
2728 #if VPP_API_TEST_BUILTIN
2729 static clib_error_t *
2730 vat_api_hookup_shim (vlib_main_t * vm)
2732 vat_api_hookup (&vat_main);
2736 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
2740 * fd.io coding-style-patch-verification: ON
2743 * eval: (c-set-style "gnu")