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 <vnet/l2/l2_classify.h>
33 #include <vnet/l2/l2_vtr.h>
34 #include <vnet/classify/in_out_acl.h>
35 #include <vnet/classify/policer_classify.h>
36 #include <vnet/classify/flow_classify.h>
37 #include <vnet/mpls/mpls.h>
38 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ip/ip6_hop_by_hop.h>
41 #include <vnet/ip/ip_source_and_port_range_check.h>
42 #include <vnet/policer/xlate.h>
43 #include <vnet/span/span.h>
44 #include <vnet/policer/policer.h>
45 #include <vnet/policer/police.h>
46 #include <vnet/mfib/mfib_types.h>
47 #include <vnet/bonding/node.h>
48 #include <vnet/qos/qos_types.h>
49 #include <vnet/ethernet/ethernet_types_api.h>
50 #include <vnet/ip/ip_types_api.h>
51 #include "vat/json_format.h"
52 #include <vnet/ip/ip_types_api.h>
53 #include <vnet/ethernet/ethernet_types_api.h>
58 #include <vlibmemory/memclnt.api_enum.h>
59 #include <vlibmemory/memclnt.api_types.h>
61 #define vl_endianfun /* define message structures */
62 #include <vlibmemory/memclnt.api.h>
65 /* instantiate all the print functions we know about */
66 #if VPP_API_TEST_BUILTIN == 0
67 #define vl_print(handle, ...)
69 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
72 #include <vlibmemory/memclnt.api.h>
75 #define __plugin_msg_base 0
76 #include <vlibapi/vat_helper_macros.h>
78 void vl_api_set_elog_main (elog_main_t * m);
79 int vl_api_set_elog_trace_api_messages (int enable);
81 #if VPP_API_TEST_BUILTIN == 0
91 vat_socket_connect (vat_main_t * vam)
94 api_main_t *am = vlibapi_get_main ();
95 vam->socket_client_main = &socket_client_main;
96 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
98 0 /* default socket rx, tx buffer */ )))
101 /* vpp expects the client index in network order */
102 vam->my_client_index = htonl (socket_client_main.client_index);
103 am->my_client_index = vam->my_client_index;
106 #else /* vpp built-in case, we don't do sockets... */
108 vat_socket_connect (vat_main_t * vam)
114 vl_socket_client_read (int wait)
120 vl_socket_client_write ()
126 vl_socket_client_msg_alloc (int nbytes)
134 vat_time_now (vat_main_t * vam)
136 #if VPP_API_TEST_BUILTIN
137 return vlib_time_now (vam->vlib_main);
139 return clib_time_now (&vam->clib_time);
144 errmsg (char *fmt, ...)
146 vat_main_t *vam = &vat_main;
151 s = va_format (0, fmt, &va);
156 #if VPP_API_TEST_BUILTIN
157 vlib_cli_output (vam->vlib_main, (char *) s);
160 if (vam->ifp != stdin)
161 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
162 vam->input_line_number);
164 fformat (vam->ofp, "%s\n", (char *) s);
172 #if VPP_API_TEST_BUILTIN == 0
174 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
176 vat_main_t *vam = va_arg (*args, vat_main_t *);
177 u32 *result = va_arg (*args, u32 *);
181 if (!unformat (input, "%s", &if_name))
184 p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
191 /* Parse an IP4 address %d.%d.%d.%d. */
193 unformat_ip4_address (unformat_input_t * input, va_list * args)
195 u8 *result = va_arg (*args, u8 *);
198 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
201 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
213 unformat_ethernet_address (unformat_input_t * input, va_list * args)
215 u8 *result = va_arg (*args, u8 *);
218 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
219 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
223 for (i = 0; i < 6; i++)
224 if (a[i] >= (1 << 8))
227 for (i = 0; i < 6; i++)
233 /* Returns ethernet type as an int in host byte order. */
235 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
238 u16 *result = va_arg (*args, u16 *);
242 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
244 if (type >= (1 << 16))
252 /* Parse an IP46 address. */
254 unformat_ip46_address (unformat_input_t * input, va_list * args)
256 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
257 ip46_type_t type = va_arg (*args, ip46_type_t);
258 if ((type != IP46_TYPE_IP6) &&
259 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
261 ip46_address_mask_ip4 (ip46);
264 else if ((type != IP46_TYPE_IP4) &&
265 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
272 /* Parse an IP6 address. */
274 unformat_ip6_address (unformat_input_t * input, va_list * args)
276 ip6_address_t *result = va_arg (*args, ip6_address_t *);
278 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
279 uword c, n_colon, double_colon_index;
281 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
282 double_colon_index = ARRAY_LEN (hex_quads);
283 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
286 if (c >= '0' && c <= '9')
288 else if (c >= 'a' && c <= 'f')
289 hex_digit = c + 10 - 'a';
290 else if (c >= 'A' && c <= 'F')
291 hex_digit = c + 10 - 'A';
292 else if (c == ':' && n_colon < 2)
296 unformat_put_input (input);
300 /* Too many hex quads. */
301 if (n_hex_quads >= ARRAY_LEN (hex_quads))
306 hex_quad = (hex_quad << 4) | hex_digit;
308 /* Hex quad must fit in 16 bits. */
309 if (n_hex_digits >= 4)
316 /* Save position of :: */
319 /* More than one :: ? */
320 if (double_colon_index < ARRAY_LEN (hex_quads))
322 double_colon_index = n_hex_quads;
325 if (n_colon > 0 && n_hex_digits > 0)
327 hex_quads[n_hex_quads++] = hex_quad;
333 if (n_hex_digits > 0)
334 hex_quads[n_hex_quads++] = hex_quad;
339 /* Expand :: to appropriate number of zero hex quads. */
340 if (double_colon_index < ARRAY_LEN (hex_quads))
342 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
344 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
345 hex_quads[n_zero + i] = hex_quads[i];
347 for (i = 0; i < n_zero; i++)
348 hex_quads[double_colon_index + i] = 0;
350 n_hex_quads = ARRAY_LEN (hex_quads);
353 /* Too few hex quads given. */
354 if (n_hex_quads < ARRAY_LEN (hex_quads))
357 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
358 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
365 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
367 u32 *r = va_arg (*args, u32 *);
370 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
371 foreach_ipsec_policy_action
379 format_ipsec_crypto_alg (u8 * s, va_list * args)
381 u32 i = va_arg (*args, u32);
386 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
387 foreach_ipsec_crypto_alg
390 return format (s, "unknown");
392 return format (s, "%s", t);
396 format_ipsec_integ_alg (u8 * s, va_list * args)
398 u32 i = va_arg (*args, u32);
403 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
404 foreach_ipsec_integ_alg
407 return format (s, "unknown");
409 return format (s, "%s", t);
412 #else /* VPP_API_TEST_BUILTIN == 1 */
414 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
416 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
417 vnet_main_t *vnm = vnet_get_main ();
418 u32 *result = va_arg (*args, u32 *);
420 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
423 #endif /* VPP_API_TEST_BUILTIN */
425 #if (VPP_API_TEST_BUILTIN==0)
427 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
428 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
429 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
430 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
433 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
435 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
436 mfib_itf_attribute_t attr;
439 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
441 if (unformat (input, mfib_itf_flag_long_names[attr]))
442 *iflags |= (1 << attr);
444 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
446 if (unformat (input, mfib_itf_flag_names[attr]))
447 *iflags |= (1 << attr);
450 return (old == *iflags ? 0 : 1);
454 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
456 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
457 mfib_entry_attribute_t attr;
460 FOR_EACH_MFIB_ATTRIBUTE (attr)
462 if (unformat (input, mfib_flag_long_names[attr]))
463 *eflags |= (1 << attr);
465 FOR_EACH_MFIB_ATTRIBUTE (attr)
467 if (unformat (input, mfib_flag_names[attr]))
468 *eflags |= (1 << attr);
471 return (old == *eflags ? 0 : 1);
475 format_ip4_address (u8 * s, va_list * args)
477 u8 *a = va_arg (*args, u8 *);
478 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 format_ip6_address (u8 * s, va_list * args)
484 ip6_address_t *a = va_arg (*args, ip6_address_t *);
485 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
487 i_max_n_zero = ARRAY_LEN (a->as_u16);
489 i_first_zero = i_max_n_zero;
491 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
493 u32 is_zero = a->as_u16[i] == 0;
494 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
500 if ((!is_zero && n_zeros > max_n_zeros)
501 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
503 i_max_n_zero = i_first_zero;
504 max_n_zeros = n_zeros;
505 i_first_zero = ARRAY_LEN (a->as_u16);
510 last_double_colon = 0;
511 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
513 if (i == i_max_n_zero && max_n_zeros > 1)
515 s = format (s, "::");
516 i += max_n_zeros - 1;
517 last_double_colon = 1;
521 s = format (s, "%s%x",
522 (last_double_colon || i == 0) ? "" : ":",
523 clib_net_to_host_u16 (a->as_u16[i]));
524 last_double_colon = 0;
531 /* Format an IP46 address. */
533 format_ip46_address (u8 * s, va_list * args)
535 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
536 ip46_type_t type = va_arg (*args, ip46_type_t);
542 is_ip4 = ip46_address_is_ip4 (ip46);
553 format (s, "%U", format_ip4_address, &ip46->ip4) :
554 format (s, "%U", format_ip6_address, &ip46->ip6);
558 format_ethernet_address (u8 * s, va_list * args)
560 u8 *a = va_arg (*args, u8 *);
562 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
563 a[0], a[1], a[2], a[3], a[4], a[5]);
568 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
571 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
573 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
574 sizeof (ip6_address_t));
578 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
579 #define vl_api_bridge_domain_details_t_print vl_noop_handler
581 static void vl_api_get_first_msg_id_reply_t_handler
582 (vl_api_get_first_msg_id_reply_t * mp)
584 vat_main_t *vam = &vat_main;
585 i32 retval = ntohl (mp->retval);
589 vam->async_errors += (retval < 0);
593 vam->retval = retval;
594 vam->result_ready = 1;
598 errmsg ("first message id %d", ntohs (mp->first_msg_id));
602 static void vl_api_get_first_msg_id_reply_t_handler_json
603 (vl_api_get_first_msg_id_reply_t * mp)
605 vat_main_t *vam = &vat_main;
606 vat_json_node_t node;
608 vat_json_init_object (&node);
609 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
610 vat_json_object_add_uint (&node, "first_msg_id",
611 (uint) ntohs (mp->first_msg_id));
613 vat_json_print (vam->ofp, &node);
614 vat_json_free (&node);
616 vam->retval = ntohl (mp->retval);
617 vam->result_ready = 1;
620 /* Format hex dump. */
622 format_hex_bytes (u8 * s, va_list * va)
624 u8 *bytes = va_arg (*va, u8 *);
625 int n_bytes = va_arg (*va, int);
628 /* Print short or long form depending on byte count. */
629 uword short_form = n_bytes <= 32;
630 u32 indent = format_get_indent (s);
635 for (i = 0; i < n_bytes; i++)
637 if (!short_form && (i % 32) == 0)
638 s = format (s, "%08x: ", i);
639 s = format (s, "%02x", bytes[i]);
640 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
641 s = format (s, "\n%U", format_white_space, indent);
648 * Generate boilerplate reply handlers, which
649 * dig the return value out of the xxx_reply_t API message,
650 * stick it into vam->retval, and set vam->result_ready
652 * Could also do this by pointing N message decode slots at
653 * a single function, but that could break in subtle ways.
656 #define foreach_standard_reply_retval_handler
659 static void vl_api_##n##_t_handler \
660 (vl_api_##n##_t * mp) \
662 vat_main_t * vam = &vat_main; \
663 i32 retval = ntohl(mp->retval); \
664 if (vam->async_mode) { \
665 vam->async_errors += (retval < 0); \
667 vam->retval = retval; \
668 vam->result_ready = 1; \
671 foreach_standard_reply_retval_handler;
675 static void vl_api_##n##_t_handler_json \
676 (vl_api_##n##_t * mp) \
678 vat_main_t * vam = &vat_main; \
679 vat_json_node_t node; \
680 vat_json_init_object(&node); \
681 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
682 vat_json_print(vam->ofp, &node); \
683 vam->retval = ntohl(mp->retval); \
684 vam->result_ready = 1; \
686 foreach_standard_reply_retval_handler;
690 * Table of message reply handlers, must include boilerplate handlers
694 #define foreach_vpe_api_reply_msg \
695 _ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
697 #define foreach_standalone_reply_msg \
705 #define STR_VTR_OP_CASE(op) \
706 case L2_VTR_ ## op: \
710 api_sw_interface_dump (vat_main_t *vam)
716 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
718 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
721 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
727 addr->function = x[3];
733 unformat_fib_path (unformat_input_t *input, va_list *args)
735 vat_main_t *vam = va_arg (*args, vat_main_t *);
736 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
737 u32 weight, preference;
738 mpls_label_t out_label;
740 clib_memset (path, 0, sizeof (*path));
742 path->sw_if_index = ~0;
746 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
748 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
749 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
752 path->proto = FIB_API_PATH_NH_PROTO_IP4;
754 else if (unformat (input, "%U %U",
755 unformat_vl_api_ip6_address,
756 &path->nh.address.ip6,
757 api_unformat_sw_if_index, vam, &path->sw_if_index))
759 path->proto = FIB_API_PATH_NH_PROTO_IP6;
761 else if (unformat (input, "weight %u", &weight))
763 path->weight = weight;
765 else if (unformat (input, "preference %u", &preference))
767 path->preference = preference;
769 else if (unformat (input, "%U next-hop-table %d",
770 unformat_vl_api_ip4_address,
771 &path->nh.address.ip4, &path->table_id))
773 path->proto = FIB_API_PATH_NH_PROTO_IP4;
775 else if (unformat (input, "%U next-hop-table %d",
776 unformat_vl_api_ip6_address,
777 &path->nh.address.ip6, &path->table_id))
779 path->proto = FIB_API_PATH_NH_PROTO_IP6;
781 else if (unformat (input, "%U",
782 unformat_vl_api_ip4_address, &path->nh.address.ip4))
785 * the recursive next-hops are by default in the default table
788 path->sw_if_index = ~0;
789 path->proto = FIB_API_PATH_NH_PROTO_IP4;
791 else if (unformat (input, "%U",
792 unformat_vl_api_ip6_address, &path->nh.address.ip6))
795 * the recursive next-hops are by default in the default table
798 path->sw_if_index = ~0;
799 path->proto = FIB_API_PATH_NH_PROTO_IP6;
801 else if (unformat (input, "resolve-via-host"))
803 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
805 else if (unformat (input, "resolve-via-attached"))
807 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
809 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
811 path->type = FIB_API_PATH_TYPE_LOCAL;
812 path->sw_if_index = ~0;
813 path->proto = FIB_API_PATH_NH_PROTO_IP4;
815 else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
817 path->type = FIB_API_PATH_TYPE_LOCAL;
818 path->sw_if_index = ~0;
819 path->proto = FIB_API_PATH_NH_PROTO_IP6;
821 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
823 else if (unformat (input, "via-label %d", &path->nh.via_label))
825 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
826 path->sw_if_index = ~0;
828 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
830 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
831 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
833 else if (unformat (input, "local"))
835 path->type = FIB_API_PATH_TYPE_LOCAL;
837 else if (unformat (input, "out-labels"))
839 while (unformat (input, "%d", &out_label))
841 path->label_stack[path->n_labels].label = out_label;
842 path->label_stack[path->n_labels].is_uniform = 0;
843 path->label_stack[path->n_labels].ttl = 64;
847 else if (unformat (input, "via"))
849 /* new path, back up and return */
850 unformat_put_input (input);
851 unformat_put_input (input);
852 unformat_put_input (input);
853 unformat_put_input (input);
862 path->proto = ntohl (path->proto);
863 path->type = ntohl (path->type);
864 path->flags = ntohl (path->flags);
865 path->table_id = ntohl (path->table_id);
866 path->sw_if_index = ntohl (path->sw_if_index);
871 #define foreach_create_subif_bit \
878 _(outer_vlan_id_any) \
881 #define foreach_create_subif_flag \
886 _(4, "exact_match") \
887 _(5, "default_sub") \
888 _(6, "outer_vlan_id_any") \
889 _(7, "inner_vlan_id_any")
892 #define foreach_tcp_proto_field \
896 #define foreach_udp_proto_field \
900 #define foreach_ip4_proto_field \
912 u16 src_port, dst_port;
915 #if VPP_API_TEST_BUILTIN == 0
917 unformat_tcp_mask (unformat_input_t *input, va_list *args)
919 u8 **maskp = va_arg (*args, u8 **);
921 u8 found_something = 0;
924 #define _(a) u8 a = 0;
925 foreach_tcp_proto_field;
928 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
932 #define _(a) else if (unformat (input, #a)) a = 1;
933 foreach_tcp_proto_field
938 #define _(a) found_something += a;
939 foreach_tcp_proto_field;
942 if (found_something == 0)
945 vec_validate (mask, sizeof (*tcp) - 1);
947 tcp = (tcp_header_t *) mask;
951 clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
952 foreach_tcp_proto_field;
960 unformat_udp_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_udp_proto_field;
971 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
975 #define _(a) else if (unformat (input, #a)) a = 1;
976 foreach_udp_proto_field
981 #define _(a) found_something += a;
982 foreach_udp_proto_field;
985 if (found_something == 0)
988 vec_validate (mask, sizeof (*udp) - 1);
990 udp = (udp_header_t *) mask;
994 clib_memset (&udp->a, 0xff, sizeof (udp->a));
995 foreach_udp_proto_field;
1003 unformat_l4_mask (unformat_input_t *input, va_list *args)
1005 u8 **maskp = va_arg (*args, u8 **);
1006 u16 src_port = 0, dst_port = 0;
1007 tcpudp_header_t *tcpudp;
1009 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1011 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
1013 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
1015 else if (unformat (input, "src_port"))
1017 else if (unformat (input, "dst_port"))
1023 if (!src_port && !dst_port)
1027 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
1029 tcpudp = (tcpudp_header_t *) mask;
1030 tcpudp->src_port = src_port;
1031 tcpudp->dst_port = dst_port;
1039 unformat_ip4_mask (unformat_input_t * input, va_list * args)
1041 u8 **maskp = va_arg (*args, u8 **);
1043 u8 found_something = 0;
1046 #define _(a) u8 a=0;
1047 foreach_ip4_proto_field;
1053 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1055 if (unformat (input, "version"))
1057 else if (unformat (input, "hdr_length"))
1059 else if (unformat (input, "src"))
1061 else if (unformat (input, "dst"))
1063 else if (unformat (input, "proto"))
1066 #define _(a) else if (unformat (input, #a)) a=1;
1067 foreach_ip4_proto_field
1073 #define _(a) found_something += a;
1074 foreach_ip4_proto_field;
1077 if (found_something == 0)
1080 vec_validate (mask, sizeof (*ip) - 1);
1082 ip = (ip4_header_t *) mask;
1084 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1085 foreach_ip4_proto_field;
1088 ip->ip_version_and_header_length = 0;
1091 ip->ip_version_and_header_length |= 0xF0;
1094 ip->ip_version_and_header_length |= 0x0F;
1100 #define foreach_ip6_proto_field \
1108 unformat_ip6_mask (unformat_input_t * input, va_list * args)
1110 u8 **maskp = va_arg (*args, u8 **);
1112 u8 found_something = 0;
1114 u32 ip_version_traffic_class_and_flow_label;
1116 #define _(a) u8 a=0;
1117 foreach_ip6_proto_field;
1120 u8 traffic_class = 0;
1123 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1125 if (unformat (input, "version"))
1127 else if (unformat (input, "traffic-class"))
1129 else if (unformat (input, "flow-label"))
1131 else if (unformat (input, "src"))
1133 else if (unformat (input, "dst"))
1135 else if (unformat (input, "proto"))
1138 #define _(a) else if (unformat (input, #a)) a=1;
1139 foreach_ip6_proto_field
1145 #define _(a) found_something += a;
1146 foreach_ip6_proto_field;
1149 if (found_something == 0)
1152 vec_validate (mask, sizeof (*ip) - 1);
1154 ip = (ip6_header_t *) mask;
1156 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1157 foreach_ip6_proto_field;
1160 ip_version_traffic_class_and_flow_label = 0;
1163 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1166 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1169 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1171 ip->ip_version_traffic_class_and_flow_label =
1172 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1179 unformat_l3_mask (unformat_input_t * input, va_list * args)
1181 u8 **maskp = va_arg (*args, u8 **);
1183 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1185 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
1187 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
1196 unformat_l2_mask (unformat_input_t * input, va_list * args)
1198 u8 **maskp = va_arg (*args, u8 **);
1213 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1215 if (unformat (input, "src"))
1217 else if (unformat (input, "dst"))
1219 else if (unformat (input, "proto"))
1221 else if (unformat (input, "tag1"))
1223 else if (unformat (input, "tag2"))
1225 else if (unformat (input, "ignore-tag1"))
1227 else if (unformat (input, "ignore-tag2"))
1229 else if (unformat (input, "cos1"))
1231 else if (unformat (input, "cos2"))
1233 else if (unformat (input, "dot1q"))
1235 else if (unformat (input, "dot1ad"))
1240 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1241 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1244 if (tag1 || ignore_tag1 || cos1 || dot1q)
1246 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1249 vec_validate (mask, len - 1);
1252 clib_memset (mask, 0xff, 6);
1255 clib_memset (mask + 6, 0xff, 6);
1259 /* inner vlan tag */
1268 mask[21] = mask[20] = 0xff;
1289 mask[16] = mask[17] = 0xff;
1299 mask[12] = mask[13] = 0xff;
1306 unformat_classify_mask (unformat_input_t * input, va_list * args)
1308 u8 **maskp = va_arg (*args, u8 **);
1309 u32 *skipp = va_arg (*args, u32 *);
1310 u32 *matchp = va_arg (*args, u32 *);
1318 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1320 if (unformat (input, "hex %U", unformat_hex_string, &mask))
1322 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
1324 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
1326 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
1340 if (mask || l2 || l3 || l4)
1344 /* "With a free Ethernet header in every package" */
1346 vec_validate (l2, 13);
1350 vec_append (mask, l3);
1355 vec_append (mask, l4);
1360 /* Scan forward looking for the first significant mask octet */
1361 for (i = 0; i < vec_len (mask); i++)
1365 /* compute (skip, match) params */
1366 *skipp = i / sizeof (u32x4);
1367 vec_delete (mask, *skipp * sizeof (u32x4), 0);
1369 /* Pad mask to an even multiple of the vector size */
1370 while (vec_len (mask) % sizeof (u32x4))
1373 match = vec_len (mask) / sizeof (u32x4);
1375 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
1377 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
1378 if (*tmp || *(tmp + 1))
1383 clib_warning ("BUG: match 0");
1385 _vec_len (mask) = match * sizeof (u32x4);
1395 #endif /* VPP_API_TEST_BUILTIN */
1397 #define foreach_l2_next \
1399 _(ethernet, ETHERNET_INPUT) \
1404 unformat_l2_next_index (unformat_input_t * input, va_list * args)
1406 u32 *miss_next_indexp = va_arg (*args, u32 *);
1411 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
1415 if (unformat (input, "%d", &tmp))
1424 *miss_next_indexp = next_index;
1428 #define foreach_ip_next \
1434 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
1436 u32 *miss_next_indexp = va_arg (*args, u32 *);
1441 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
1445 if (unformat (input, "%d", &tmp))
1454 *miss_next_indexp = next_index;
1458 #define foreach_acl_next \
1462 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
1464 u32 *miss_next_indexp = va_arg (*args, u32 *);
1469 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
1473 if (unformat (input, "permit"))
1478 else if (unformat (input, "%d", &tmp))
1487 *miss_next_indexp = next_index;
1492 unformat_policer_precolor (unformat_input_t * input, va_list * args)
1494 u32 *r = va_arg (*args, u32 *);
1496 if (unformat (input, "conform-color"))
1497 *r = POLICE_CONFORM;
1498 else if (unformat (input, "exceed-color"))
1506 #if VPP_API_TEST_BUILTIN == 0
1508 unformat_l4_match (unformat_input_t * input, va_list * args)
1510 u8 **matchp = va_arg (*args, u8 **);
1512 u8 *proto_header = 0;
1518 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1520 if (unformat (input, "src_port %d", &src_port))
1522 else if (unformat (input, "dst_port %d", &dst_port))
1528 h.src_port = clib_host_to_net_u16 (src_port);
1529 h.dst_port = clib_host_to_net_u16 (dst_port);
1530 vec_validate (proto_header, sizeof (h) - 1);
1531 memcpy (proto_header, &h, sizeof (h));
1533 *matchp = proto_header;
1539 unformat_ip4_match (unformat_input_t * input, va_list * args)
1541 u8 **matchp = va_arg (*args, u8 **);
1548 int src = 0, dst = 0;
1549 ip4_address_t src_val, dst_val;
1556 int fragment_id = 0;
1557 u32 fragment_id_val;
1563 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1565 if (unformat (input, "version %d", &version_val))
1567 else if (unformat (input, "hdr_length %d", &hdr_length_val))
1569 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
1571 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
1573 else if (unformat (input, "proto %d", &proto_val))
1575 else if (unformat (input, "tos %d", &tos_val))
1577 else if (unformat (input, "length %d", &length_val))
1579 else if (unformat (input, "fragment_id %d", &fragment_id_val))
1581 else if (unformat (input, "ttl %d", &ttl_val))
1583 else if (unformat (input, "checksum %d", &checksum_val))
1589 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
1590 + ttl + checksum == 0)
1594 * Aligned because we use the real comparison functions
1596 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1598 ip = (ip4_header_t *) match;
1600 /* These are realistically matched in practice */
1602 ip->src_address.as_u32 = src_val.as_u32;
1605 ip->dst_address.as_u32 = dst_val.as_u32;
1608 ip->protocol = proto_val;
1611 /* These are not, but they're included for completeness */
1613 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
1616 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
1622 ip->length = clib_host_to_net_u16 (length_val);
1628 ip->checksum = clib_host_to_net_u16 (checksum_val);
1635 unformat_ip6_match (unformat_input_t * input, va_list * args)
1637 u8 **matchp = va_arg (*args, u8 **);
1642 u8 traffic_class = 0;
1643 u32 traffic_class_val = 0;
1646 int src = 0, dst = 0;
1647 ip6_address_t src_val, dst_val;
1650 int payload_length = 0;
1651 u32 payload_length_val;
1654 u32 ip_version_traffic_class_and_flow_label;
1656 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1658 if (unformat (input, "version %d", &version_val))
1660 else if (unformat (input, "traffic_class %d", &traffic_class_val))
1662 else if (unformat (input, "flow_label %d", &flow_label_val))
1664 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
1666 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
1668 else if (unformat (input, "proto %d", &proto_val))
1670 else if (unformat (input, "payload_length %d", &payload_length_val))
1672 else if (unformat (input, "hop_limit %d", &hop_limit_val))
1678 if (version + traffic_class + flow_label + src + dst + proto +
1679 payload_length + hop_limit == 0)
1683 * Aligned because we use the real comparison functions
1685 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1687 ip = (ip6_header_t *) match;
1690 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
1693 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
1696 ip->protocol = proto_val;
1698 ip_version_traffic_class_and_flow_label = 0;
1701 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
1704 ip_version_traffic_class_and_flow_label |=
1705 (traffic_class_val & 0xFF) << 20;
1708 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
1710 ip->ip_version_traffic_class_and_flow_label =
1711 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1714 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
1717 ip->hop_limit = hop_limit_val;
1724 unformat_l3_match (unformat_input_t * input, va_list * args)
1726 u8 **matchp = va_arg (*args, u8 **);
1728 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1730 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
1732 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
1741 unformat_vlan_tag (unformat_input_t * input, va_list * args)
1743 u8 *tagp = va_arg (*args, u8 *);
1746 if (unformat (input, "%d", &tag))
1748 tagp[0] = (tag >> 8) & 0x0F;
1749 tagp[1] = tag & 0xFF;
1757 unformat_l2_match (unformat_input_t * input, va_list * args)
1759 u8 **matchp = va_arg (*args, u8 **);
1779 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1781 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
1784 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
1786 else if (unformat (input, "proto %U",
1787 unformat_ethernet_type_host_byte_order, &proto_val))
1789 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
1791 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
1793 else if (unformat (input, "ignore-tag1"))
1795 else if (unformat (input, "ignore-tag2"))
1797 else if (unformat (input, "cos1 %d", &cos1_val))
1799 else if (unformat (input, "cos2 %d", &cos2_val))
1804 if ((src + dst + proto + tag1 + tag2 +
1805 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1808 if (tag1 || ignore_tag1 || cos1)
1810 if (tag2 || ignore_tag2 || cos2)
1813 vec_validate_aligned (match, len - 1, sizeof (u32x4));
1816 clib_memcpy (match, dst_val, 6);
1819 clib_memcpy (match + 6, src_val, 6);
1823 /* inner vlan tag */
1824 match[19] = tag2_val[1];
1825 match[18] = tag2_val[0];
1827 match[18] |= (cos2_val & 0x7) << 5;
1830 match[21] = proto_val & 0xff;
1831 match[20] = proto_val >> 8;
1835 match[15] = tag1_val[1];
1836 match[14] = tag1_val[0];
1839 match[14] |= (cos1_val & 0x7) << 5;
1845 match[15] = tag1_val[1];
1846 match[14] = tag1_val[0];
1849 match[17] = proto_val & 0xff;
1850 match[16] = proto_val >> 8;
1853 match[14] |= (cos1_val & 0x7) << 5;
1859 match[18] |= (cos2_val & 0x7) << 5;
1861 match[14] |= (cos1_val & 0x7) << 5;
1864 match[13] = proto_val & 0xff;
1865 match[12] = proto_val >> 8;
1873 unformat_qos_source (unformat_input_t * input, va_list * args)
1875 int *qs = va_arg (*args, int *);
1877 if (unformat (input, "ip"))
1878 *qs = QOS_SOURCE_IP;
1879 else if (unformat (input, "mpls"))
1880 *qs = QOS_SOURCE_MPLS;
1881 else if (unformat (input, "ext"))
1882 *qs = QOS_SOURCE_EXT;
1883 else if (unformat (input, "vlan"))
1884 *qs = QOS_SOURCE_VLAN;
1893 api_unformat_classify_match (unformat_input_t * input, va_list * args)
1895 u8 **matchp = va_arg (*args, u8 **);
1896 u32 skip_n_vectors = va_arg (*args, u32);
1897 u32 match_n_vectors = va_arg (*args, u32);
1904 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1906 if (unformat (input, "hex %U", unformat_hex_string, &match))
1908 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
1910 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
1912 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
1926 if (match || l2 || l3 || l4)
1930 /* "Win a free Ethernet header in every packet" */
1932 vec_validate_aligned (l2, 13, sizeof (u32x4));
1936 vec_append_aligned (match, l3, sizeof (u32x4));
1941 vec_append_aligned (match, l4, sizeof (u32x4));
1946 /* Make sure the vector is big enough even if key is all 0's */
1947 vec_validate_aligned
1948 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
1951 /* Set size, include skipped vectors */
1952 _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
1962 #define foreach_vtr_op \
1963 _ ("disable", L2_VTR_DISABLED) \
1964 _ ("push-1", L2_VTR_PUSH_1) \
1965 _ ("push-2", L2_VTR_PUSH_2) \
1966 _ ("pop-1", L2_VTR_POP_1) \
1967 _ ("pop-2", L2_VTR_POP_2) \
1968 _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
1969 _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
1970 _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
1971 _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
1974 api_get_first_msg_id (vat_main_t *vam)
1976 vl_api_get_first_msg_id_t *mp;
1977 unformat_input_t *i = vam->input;
1982 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1984 if (unformat (i, "client %s", &name))
1992 errmsg ("missing client name");
1997 if (vec_len (name) > 63)
1999 errmsg ("client name too long");
2003 M (GET_FIRST_MSG_ID, mp);
2004 clib_memcpy (mp->name, name, vec_len (name));
2010 #define foreach_pbb_vtr_op \
2011 _("disable", L2_VTR_DISABLED) \
2012 _("pop", L2_VTR_POP_2) \
2013 _("push", L2_VTR_PUSH_2)
2016 api_sock_init_shm (vat_main_t * vam)
2018 #if VPP_API_TEST_BUILTIN == 0
2019 unformat_input_t *i = vam->input;
2020 vl_api_shm_elem_config_t *config = 0;
2021 u64 size = 64 << 20;
2024 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2026 if (unformat (i, "size %U", unformat_memory_size, &size))
2033 * Canned custom ring allocator config.
2034 * Should probably parse all of this
2036 vec_validate (config, 6);
2037 config[0].type = VL_API_VLIB_RING;
2038 config[0].size = 256;
2039 config[0].count = 32;
2041 config[1].type = VL_API_VLIB_RING;
2042 config[1].size = 1024;
2043 config[1].count = 16;
2045 config[2].type = VL_API_VLIB_RING;
2046 config[2].size = 4096;
2047 config[2].count = 2;
2049 config[3].type = VL_API_CLIENT_RING;
2050 config[3].size = 256;
2051 config[3].count = 32;
2053 config[4].type = VL_API_CLIENT_RING;
2054 config[4].size = 1024;
2055 config[4].count = 16;
2057 config[5].type = VL_API_CLIENT_RING;
2058 config[5].size = 4096;
2059 config[5].count = 2;
2061 config[6].type = VL_API_QUEUE;
2062 config[6].count = 128;
2063 config[6].size = sizeof (uword);
2065 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
2067 vam->client_index_invalid = 1;
2075 q_or_quit (vat_main_t * vam)
2077 #if VPP_API_TEST_BUILTIN == 0
2078 longjmp (vam->jump_buf, 1);
2080 return 0; /* not so much */
2084 q (vat_main_t * vam)
2086 return q_or_quit (vam);
2090 quit (vat_main_t * vam)
2092 return q_or_quit (vam);
2096 comment (vat_main_t * vam)
2102 elog_save (vat_main_t * vam)
2104 #if VPP_API_TEST_BUILTIN == 0
2105 elog_main_t *em = &vam->elog_main;
2106 unformat_input_t *i = vam->input;
2107 char *file, *chroot_file;
2108 clib_error_t *error;
2110 if (!unformat (i, "%s", &file))
2112 errmsg ("expected file name, got `%U'", format_unformat_error, i);
2116 /* It's fairly hard to get "../oopsie" through unformat; just in case */
2117 if (strstr (file, "..") || index (file, '/'))
2119 errmsg ("illegal characters in filename '%s'", file);
2123 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
2127 errmsg ("Saving %wd of %wd events to %s",
2128 elog_n_events_in_buffer (em),
2129 elog_buffer_capacity (em), chroot_file);
2131 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
2132 vec_free (chroot_file);
2135 clib_error_report (error);
2137 errmsg ("Use the vpp event loger...");
2144 elog_setup (vat_main_t * vam)
2146 #if VPP_API_TEST_BUILTIN == 0
2147 elog_main_t *em = &vam->elog_main;
2148 unformat_input_t *i = vam->input;
2149 u32 nevents = 128 << 10;
2151 (void) unformat (i, "nevents %d", &nevents);
2153 elog_init (em, nevents);
2154 vl_api_set_elog_main (em);
2155 vl_api_set_elog_trace_api_messages (1);
2156 errmsg ("Event logger initialized with %u events", nevents);
2158 errmsg ("Use the vpp event loger...");
2164 elog_enable (vat_main_t * vam)
2166 #if VPP_API_TEST_BUILTIN == 0
2167 elog_main_t *em = &vam->elog_main;
2169 elog_enable_disable (em, 1 /* enable */ );
2170 vl_api_set_elog_trace_api_messages (1);
2171 errmsg ("Event logger enabled...");
2173 errmsg ("Use the vpp event loger...");
2179 elog_disable (vat_main_t * vam)
2181 #if VPP_API_TEST_BUILTIN == 0
2182 elog_main_t *em = &vam->elog_main;
2184 elog_enable_disable (em, 0 /* enable */ );
2185 vl_api_set_elog_trace_api_messages (1);
2186 errmsg ("Event logger disabled...");
2188 errmsg ("Use the vpp event loger...");
2194 statseg (vat_main_t * vam)
2196 ssvm_private_t *ssvmp = &vam->stat_segment;
2197 ssvm_shared_header_t *shared_header = ssvmp->sh;
2198 vlib_counter_t **counters;
2199 u64 thread0_index1_packets;
2200 u64 thread0_index1_bytes;
2201 f64 vector_rate, input_rate;
2204 uword *counter_vector_by_name;
2205 if (vam->stat_segment_lockp == 0)
2207 errmsg ("Stat segment not mapped...");
2211 /* look up "/if/rx for sw_if_index 1 as a test */
2213 clib_spinlock_lock (vam->stat_segment_lockp);
2215 counter_vector_by_name = (uword *) shared_header->opaque[1];
2217 p = hash_get_mem (counter_vector_by_name, "/if/rx");
2220 clib_spinlock_unlock (vam->stat_segment_lockp);
2221 errmsg ("/if/tx not found?");
2225 /* Fish per-thread vector of combined counters from shared memory */
2226 counters = (vlib_counter_t **) p[0];
2228 if (vec_len (counters[0]) < 2)
2230 clib_spinlock_unlock (vam->stat_segment_lockp);
2231 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
2235 /* Read thread 0 sw_if_index 1 counter */
2236 thread0_index1_packets = counters[0][1].packets;
2237 thread0_index1_bytes = counters[0][1].bytes;
2239 p = hash_get_mem (counter_vector_by_name, "vector_rate");
2242 clib_spinlock_unlock (vam->stat_segment_lockp);
2243 errmsg ("vector_rate not found?");
2247 vector_rate = *(f64 *) (p[0]);
2248 p = hash_get_mem (counter_vector_by_name, "input_rate");
2251 clib_spinlock_unlock (vam->stat_segment_lockp);
2252 errmsg ("input_rate not found?");
2255 input_rate = *(f64 *) (p[0]);
2257 clib_spinlock_unlock (vam->stat_segment_lockp);
2259 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
2260 vector_rate, input_rate);
2261 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
2262 thread0_index1_packets, thread0_index1_bytes);
2268 cmd_cmp (void *a1, void *a2)
2273 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
2277 help (vat_main_t * vam)
2282 unformat_input_t *i = vam->input;
2285 if (unformat (i, "%s", &name))
2291 hs = hash_get_mem (vam->help_by_name, name);
2293 print (vam->ofp, "usage: %s %s", name, hs[0]);
2295 print (vam->ofp, "No such msg / command '%s'", name);
2300 print (vam->ofp, "Help is available for the following:");
2303 hash_foreach_pair (p, vam->function_by_name,
2305 vec_add1 (cmds, (u8 *)(p->key));
2309 vec_sort_with_function (cmds, cmd_cmp);
2311 for (j = 0; j < vec_len (cmds); j++)
2312 print (vam->ofp, "%s", cmds[j]);
2319 set (vat_main_t * vam)
2321 u8 *name = 0, *value = 0;
2322 unformat_input_t *i = vam->input;
2324 if (unformat (i, "%s", &name))
2326 /* The input buffer is a vector, not a string. */
2327 value = vec_dup (i->buffer);
2328 vec_delete (value, i->index, 0);
2329 /* Almost certainly has a trailing newline */
2330 if (value[vec_len (value) - 1] == '\n')
2331 value[vec_len (value) - 1] = 0;
2332 /* Make sure it's a proper string, one way or the other */
2333 vec_add1 (value, 0);
2334 (void) clib_macro_set_value (&vam->macro_main,
2335 (char *) name, (char *) value);
2338 errmsg ("usage: set <name> <value>");
2346 unset (vat_main_t * vam)
2350 if (unformat (vam->input, "%s", &name))
2351 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
2352 errmsg ("unset: %s wasn't set", name);
2365 macro_sort_cmp (void *a1, void *a2)
2367 macro_sort_t *s1 = a1;
2368 macro_sort_t *s2 = a2;
2370 return strcmp ((char *) (s1->name), (char *) (s2->name));
2374 dump_macro_table (vat_main_t * vam)
2376 macro_sort_t *sort_me = 0, *sm;
2381 hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
2383 vec_add2 (sort_me, sm, 1);
2384 sm->name = (u8 *)(p->key);
2385 sm->value = (u8 *) (p->value[0]);
2389 vec_sort_with_function (sort_me, macro_sort_cmp);
2391 if (vec_len (sort_me))
2392 print (vam->ofp, "%-15s%s", "Name", "Value");
2394 print (vam->ofp, "The macro table is empty...");
2396 for (i = 0; i < vec_len (sort_me); i++)
2397 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
2402 value_sort_cmp (void *a1, void *a2)
2404 name_sort_t *n1 = a1;
2405 name_sort_t *n2 = a2;
2407 if (n1->value < n2->value)
2409 if (n1->value > n2->value)
2416 dump_msg_api_table (vat_main_t * vam)
2418 api_main_t *am = vlibapi_get_main ();
2419 name_sort_t *nses = 0, *ns;
2424 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
2426 vec_add2 (nses, ns, 1);
2427 ns->name = (u8 *)(hp->key);
2428 ns->value = (u32) hp->value[0];
2432 vec_sort_with_function (nses, value_sort_cmp);
2434 for (i = 0; i < vec_len (nses); i++)
2435 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
2441 get_msg_id (vat_main_t * vam)
2446 if (unformat (vam->input, "%s", &name_and_crc))
2448 message_index = vl_msg_api_get_msg_index (name_and_crc);
2449 if (message_index == ~0)
2451 print (vam->ofp, " '%s' not found", name_and_crc);
2454 print (vam->ofp, " '%s' has message index %d",
2455 name_and_crc, message_index);
2458 errmsg ("name_and_crc required...");
2463 search_node_table (vat_main_t * vam)
2465 unformat_input_t *line_input = vam->input;
2468 vlib_node_t *node, *next_node;
2471 if (vam->graph_node_index_by_name == 0)
2473 print (vam->ofp, "Node table empty, issue get_node_graph...");
2477 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2479 if (unformat (line_input, "%s", &node_to_find))
2481 vec_add1 (node_to_find, 0);
2482 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
2485 print (vam->ofp, "%s not found...", node_to_find);
2488 node = vam->graph_nodes[0][p[0]];
2489 print (vam->ofp, "[%d] %s", p[0], node->name);
2490 for (j = 0; j < vec_len (node->next_nodes); j++)
2492 if (node->next_nodes[j] != ~0)
2494 next_node = vam->graph_nodes[0][node->next_nodes[j]];
2495 print (vam->ofp, " [%d] %s", j, next_node->name);
2502 clib_warning ("parse error '%U'", format_unformat_error,
2508 vec_free (node_to_find);
2517 script (vat_main_t * vam)
2519 #if (VPP_API_TEST_BUILTIN==0)
2521 char *save_current_file;
2522 unformat_input_t save_input;
2523 jmp_buf save_jump_buf;
2524 u32 save_line_number;
2526 FILE *new_fp, *save_ifp;
2528 if (unformat (vam->input, "%s", &s))
2530 new_fp = fopen ((char *) s, "r");
2533 errmsg ("Couldn't open script file %s", s);
2540 errmsg ("Missing script name");
2544 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
2545 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
2546 save_ifp = vam->ifp;
2547 save_line_number = vam->input_line_number;
2548 save_current_file = (char *) vam->current_file;
2550 vam->input_line_number = 0;
2552 vam->current_file = s;
2555 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
2556 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
2557 vam->ifp = save_ifp;
2558 vam->input_line_number = save_line_number;
2559 vam->current_file = (u8 *) save_current_file;
2564 clib_warning ("use the exec command...");
2570 echo (vat_main_t * vam)
2572 print (vam->ofp, "%v", vam->input->buffer);
2576 int exec (vat_main_t *vam) __attribute__ ((weak));
2578 exec (vat_main_t *vam)
2583 /* List of API message constructors, CLI names map to api_xxx */
2584 #define foreach_vpe_api_msg \
2585 _(get_first_msg_id, "client <name>") \
2586 _(sock_init_shm, "size <nnn>") \
2587 /* List of command functions, CLI names map directly to functions */
2588 #define foreach_cli_function \
2589 _(comment, "usage: comment <ignore-rest-of-line>") \
2590 _(dump_macro_table, "usage: dump_macro_table ") \
2591 _(dump_msg_api_table, "usage: dump_msg_api_table") \
2592 _(elog_setup, "usage: elog_setup [nevents, default 128K]") \
2593 _(elog_disable, "usage: elog_disable") \
2594 _(elog_enable, "usage: elog_enable") \
2595 _(elog_save, "usage: elog_save <filename>") \
2596 _(get_msg_id, "usage: get_msg_id name_and_crc") \
2597 _(echo, "usage: echo <message>") \
2598 _(help, "usage: help") \
2599 _(q, "usage: quit") \
2600 _(quit, "usage: quit") \
2601 _(search_node_table, "usage: search_node_table <name>...") \
2602 _(set, "usage: set <variable-name> <value>") \
2603 _(script, "usage: script <file-name>") \
2604 _(statseg, "usage: statseg") \
2605 _(unset, "usage: unset <variable-name>")
2608 static void vl_api_##n##_t_handler_uni \
2609 (vl_api_##n##_t * mp) \
2611 vat_main_t * vam = &vat_main; \
2612 if (vam->json_output) { \
2613 vl_api_##n##_t_handler_json(mp); \
2615 vl_api_##n##_t_handler(mp); \
2618 foreach_vpe_api_reply_msg;
2619 #if VPP_API_TEST_BUILTIN == 0
2620 foreach_standalone_reply_msg;
2625 vat_api_hookup (vat_main_t * vam)
2628 vl_msg_api_set_handlers (VL_API_##N + 1, #n, vl_api_##n##_t_handler_uni, \
2629 vl_noop_handler, vl_api_##n##_t_endian, \
2630 vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1, \
2631 vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
2632 vl_api_##n##_t_fromjson);
2633 foreach_vpe_api_reply_msg;
2634 #if VPP_API_TEST_BUILTIN == 0
2635 foreach_standalone_reply_msg;
2639 #if (VPP_API_TEST_BUILTIN==0)
2640 vl_msg_api_set_first_available_msg_id (VL_MSG_MEMCLNT_LAST + 1);
2642 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
2644 vam->function_by_name = hash_create_string (0, sizeof (uword));
2646 vam->help_by_name = hash_create_string (0, sizeof (uword));
2649 /* API messages we can send */
2650 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
2651 foreach_vpe_api_msg;
2655 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2656 foreach_vpe_api_msg;
2660 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
2661 foreach_cli_function;
2665 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2666 foreach_cli_function;
2670 #if VPP_API_TEST_BUILTIN
2671 static clib_error_t *
2672 vat_api_hookup_shim (vlib_main_t * vm)
2674 vat_api_hookup (&vat_main);
2678 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
2682 * fd.io coding-style-patch-verification: ON
2685 * eval: (c-set-style "gnu")