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>
60 #include <vlibmemory/memclnt.api_tojson.h>
61 #include <vlibmemory/memclnt.api_fromjson.h>
63 #define vl_endianfun /* define message structures */
64 #include <vlibmemory/memclnt.api.h>
67 #define vl_calcsizefun
68 #include <vlibmemory/memclnt.api.h>
71 /* instantiate all the print functions we know about */
73 #include <vlibmemory/memclnt.api.h>
76 #define __plugin_msg_base 0
77 #include <vlibapi/vat_helper_macros.h>
79 void vl_api_set_elog_main (elog_main_t * m);
80 int vl_api_set_elog_trace_api_messages (int enable);
82 #if VPP_API_TEST_BUILTIN == 0
92 vat_socket_connect (vat_main_t * vam)
95 api_main_t *am = vlibapi_get_main ();
96 vam->socket_client_main = &socket_client_main;
97 if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
99 0 /* default socket rx, tx buffer */ )))
102 /* vpp expects the client index in network order */
103 vam->my_client_index = htonl (socket_client_main.client_index);
104 am->my_client_index = vam->my_client_index;
107 #else /* vpp built-in case, we don't do sockets... */
109 vat_socket_connect (vat_main_t * vam)
115 vl_socket_client_read (int wait)
121 vl_socket_client_write ()
127 vl_socket_client_msg_alloc (int nbytes)
135 vat_time_now (vat_main_t * vam)
137 #if VPP_API_TEST_BUILTIN
138 return vlib_time_now (vam->vlib_main);
140 return clib_time_now (&vam->clib_time);
145 errmsg (char *fmt, ...)
147 vat_main_t *vam = &vat_main;
152 s = va_format (0, fmt, &va);
157 #if VPP_API_TEST_BUILTIN
158 vlib_cli_output (vam->vlib_main, (char *) s);
161 if (vam->ifp != stdin)
162 fformat (vam->ofp, "%s(%d): \n", vam->current_file,
163 vam->input_line_number);
165 fformat (vam->ofp, "%s\n", (char *) s);
173 #if VPP_API_TEST_BUILTIN == 0
175 /* Parse an IP4 address %d.%d.%d.%d. */
177 unformat_ip4_address (unformat_input_t * input, va_list * args)
179 u8 *result = va_arg (*args, u8 *);
182 if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
185 if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
197 unformat_ethernet_address (unformat_input_t * input, va_list * args)
199 u8 *result = va_arg (*args, u8 *);
202 if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
203 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
207 for (i = 0; i < 6; i++)
208 if (a[i] >= (1 << 8))
211 for (i = 0; i < 6; i++)
217 /* Returns ethernet type as an int in host byte order. */
219 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
222 u16 *result = va_arg (*args, u16 *);
226 if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
228 if (type >= (1 << 16))
236 /* Parse an IP46 address. */
238 unformat_ip46_address (unformat_input_t * input, va_list * args)
240 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
241 ip46_type_t type = va_arg (*args, ip46_type_t);
242 if ((type != IP46_TYPE_IP6) &&
243 unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
245 ip46_address_mask_ip4 (ip46);
248 else if ((type != IP46_TYPE_IP4) &&
249 unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
256 /* Parse an IP6 address. */
258 unformat_ip6_address (unformat_input_t * input, va_list * args)
260 ip6_address_t *result = va_arg (*args, ip6_address_t *);
262 uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
263 uword c, n_colon, double_colon_index;
265 n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
266 double_colon_index = ARRAY_LEN (hex_quads);
267 while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
270 if (c >= '0' && c <= '9')
272 else if (c >= 'a' && c <= 'f')
273 hex_digit = c + 10 - 'a';
274 else if (c >= 'A' && c <= 'F')
275 hex_digit = c + 10 - 'A';
276 else if (c == ':' && n_colon < 2)
280 unformat_put_input (input);
284 /* Too many hex quads. */
285 if (n_hex_quads >= ARRAY_LEN (hex_quads))
290 hex_quad = (hex_quad << 4) | hex_digit;
292 /* Hex quad must fit in 16 bits. */
293 if (n_hex_digits >= 4)
300 /* Save position of :: */
303 /* More than one :: ? */
304 if (double_colon_index < ARRAY_LEN (hex_quads))
306 double_colon_index = n_hex_quads;
309 if (n_colon > 0 && n_hex_digits > 0)
311 hex_quads[n_hex_quads++] = hex_quad;
317 if (n_hex_digits > 0)
318 hex_quads[n_hex_quads++] = hex_quad;
323 /* Expand :: to appropriate number of zero hex quads. */
324 if (double_colon_index < ARRAY_LEN (hex_quads))
326 word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
328 for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
329 hex_quads[n_zero + i] = hex_quads[i];
331 for (i = 0; i < n_zero; i++)
332 hex_quads[double_colon_index + i] = 0;
334 n_hex_quads = ARRAY_LEN (hex_quads);
337 /* Too few hex quads given. */
338 if (n_hex_quads < ARRAY_LEN (hex_quads))
341 for (i = 0; i < ARRAY_LEN (hex_quads); i++)
342 result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
349 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
351 u32 *r = va_arg (*args, u32 *);
354 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
355 foreach_ipsec_policy_action
363 format_ipsec_crypto_alg (u8 * s, va_list * args)
365 u32 i = va_arg (*args, u32);
370 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
371 foreach_ipsec_crypto_alg
374 return format (s, "unknown");
376 return format (s, "%s", t);
380 format_ipsec_integ_alg (u8 * s, va_list * args)
382 u32 i = va_arg (*args, u32);
387 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
388 foreach_ipsec_integ_alg
391 return format (s, "unknown");
393 return format (s, "%s", t);
396 #else /* VPP_API_TEST_BUILTIN == 1 */
398 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
400 vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
401 vnet_main_t *vnm = vnet_get_main ();
402 u32 *result = va_arg (*args, u32 *);
404 return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
407 #endif /* VPP_API_TEST_BUILTIN */
409 #if (VPP_API_TEST_BUILTIN==0)
411 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
412 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
413 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
414 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
417 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
419 mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
420 mfib_itf_attribute_t attr;
423 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
425 if (unformat (input, mfib_itf_flag_long_names[attr]))
426 *iflags |= (1 << attr);
428 FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
430 if (unformat (input, mfib_itf_flag_names[attr]))
431 *iflags |= (1 << attr);
434 return (old == *iflags ? 0 : 1);
438 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
440 mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
441 mfib_entry_attribute_t attr;
444 FOR_EACH_MFIB_ATTRIBUTE (attr)
446 if (unformat (input, mfib_flag_long_names[attr]))
447 *eflags |= (1 << attr);
449 FOR_EACH_MFIB_ATTRIBUTE (attr)
451 if (unformat (input, mfib_flag_names[attr]))
452 *eflags |= (1 << attr);
455 return (old == *eflags ? 0 : 1);
459 format_ip4_address (u8 * s, va_list * args)
461 u8 *a = va_arg (*args, u8 *);
462 return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
466 format_ip6_address (u8 * s, va_list * args)
468 ip6_address_t *a = va_arg (*args, ip6_address_t *);
469 u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
471 i_max_n_zero = ARRAY_LEN (a->as_u16);
473 i_first_zero = i_max_n_zero;
475 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
477 u32 is_zero = a->as_u16[i] == 0;
478 if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
484 if ((!is_zero && n_zeros > max_n_zeros)
485 || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
487 i_max_n_zero = i_first_zero;
488 max_n_zeros = n_zeros;
489 i_first_zero = ARRAY_LEN (a->as_u16);
494 last_double_colon = 0;
495 for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
497 if (i == i_max_n_zero && max_n_zeros > 1)
499 s = format (s, "::");
500 i += max_n_zeros - 1;
501 last_double_colon = 1;
505 s = format (s, "%s%x",
506 (last_double_colon || i == 0) ? "" : ":",
507 clib_net_to_host_u16 (a->as_u16[i]));
508 last_double_colon = 0;
515 /* Format an IP46 address. */
517 format_ip46_address (u8 * s, va_list * args)
519 ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
520 ip46_type_t type = va_arg (*args, ip46_type_t);
526 is_ip4 = ip46_address_is_ip4 (ip46);
537 format (s, "%U", format_ip4_address, &ip46->ip4) :
538 format (s, "%U", format_ip6_address, &ip46->ip6);
542 format_ethernet_address (u8 * s, va_list * args)
544 u8 *a = va_arg (*args, u8 *);
546 return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
547 a[0], a[1], a[2], a[3], a[4], a[5]);
552 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
555 dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
557 clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
558 sizeof (ip6_address_t));
562 static void vl_api_get_first_msg_id_reply_t_handler
563 (vl_api_get_first_msg_id_reply_t * mp)
565 vat_main_t *vam = &vat_main;
566 i32 retval = ntohl (mp->retval);
570 vam->async_errors += (retval < 0);
574 vam->retval = retval;
575 vam->result_ready = 1;
579 errmsg ("first message id %d", ntohs (mp->first_msg_id));
583 static void vl_api_get_first_msg_id_reply_t_handler_json
584 (vl_api_get_first_msg_id_reply_t * mp)
586 vat_main_t *vam = &vat_main;
587 vat_json_node_t node;
589 vat_json_init_object (&node);
590 vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
591 vat_json_object_add_uint (&node, "first_msg_id",
592 (uint) ntohs (mp->first_msg_id));
594 vat_json_print (vam->ofp, &node);
595 vat_json_free (&node);
597 vam->retval = ntohl (mp->retval);
598 vam->result_ready = 1;
601 /* Format hex dump. */
603 format_hex_bytes (u8 * s, va_list * va)
605 u8 *bytes = va_arg (*va, u8 *);
606 int n_bytes = va_arg (*va, int);
609 /* Print short or long form depending on byte count. */
610 uword short_form = n_bytes <= 32;
611 u32 indent = format_get_indent (s);
616 for (i = 0; i < n_bytes; i++)
618 if (!short_form && (i % 32) == 0)
619 s = format (s, "%08x: ", i);
620 s = format (s, "%02x", bytes[i]);
621 if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
622 s = format (s, "\n%U", format_white_space, indent);
629 vl_api_control_ping_reply_t_handler (vl_api_control_ping_reply_t *mp)
631 vat_main_t *vam = &vat_main;
632 i32 retval = ntohl (mp->retval);
635 vam->async_errors += (retval < 0);
639 vam->retval = retval;
640 vam->result_ready = 1;
642 if (vam->socket_client_main)
643 vam->socket_client_main->control_pings_outstanding--;
647 vl_api_control_ping_reply_t_handler_json (vl_api_control_ping_reply_t *mp)
649 vat_main_t *vam = &vat_main;
650 i32 retval = ntohl (mp->retval);
652 if (VAT_JSON_NONE != vam->json_tree.type)
654 vat_json_print (vam->ofp, &vam->json_tree);
655 vat_json_free (&vam->json_tree);
656 vam->json_tree.type = VAT_JSON_NONE;
661 vat_json_init_array (&vam->json_tree);
662 vat_json_print (vam->ofp, &vam->json_tree);
663 vam->json_tree.type = VAT_JSON_NONE;
666 vam->retval = retval;
667 vam->result_ready = 1;
671 * Generate boilerplate reply handlers, which
672 * dig the return value out of the xxx_reply_t API message,
673 * stick it into vam->retval, and set vam->result_ready
675 * Could also do this by pointing N message decode slots at
676 * a single function, but that could break in subtle ways.
679 #define foreach_standard_reply_retval_handler
682 static void vl_api_##n##_t_handler \
683 (vl_api_##n##_t * mp) \
685 vat_main_t * vam = &vat_main; \
686 i32 retval = ntohl(mp->retval); \
687 if (vam->async_mode) { \
688 vam->async_errors += (retval < 0); \
690 vam->retval = retval; \
691 vam->result_ready = 1; \
694 foreach_standard_reply_retval_handler;
698 static void vl_api_##n##_t_handler_json \
699 (vl_api_##n##_t * mp) \
701 vat_main_t * vam = &vat_main; \
702 vat_json_node_t node; \
703 vat_json_init_object(&node); \
704 vat_json_object_add_int(&node, "retval", ntohl(mp->retval)); \
705 vat_json_print(vam->ofp, &node); \
706 vam->retval = ntohl(mp->retval); \
707 vam->result_ready = 1; \
709 foreach_standard_reply_retval_handler;
713 * Table of message reply handlers, must include boilerplate handlers
717 #define foreach_vpe_api_reply_msg \
718 _ (GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply) \
719 _ (CONTROL_PING_REPLY, control_ping_reply)
721 #define foreach_standalone_reply_msg \
729 #define STR_VTR_OP_CASE(op) \
730 case L2_VTR_ ## op: \
734 str_vtr_op (u32 vtr_op)
738 STR_VTR_OP_CASE (DISABLED);
739 STR_VTR_OP_CASE (PUSH_1);
740 STR_VTR_OP_CASE (PUSH_2);
741 STR_VTR_OP_CASE (POP_1);
742 STR_VTR_OP_CASE (POP_2);
743 STR_VTR_OP_CASE (TRANSLATE_1_1);
744 STR_VTR_OP_CASE (TRANSLATE_1_2);
745 STR_VTR_OP_CASE (TRANSLATE_2_1);
746 STR_VTR_OP_CASE (TRANSLATE_2_2);
753 unformat_vlib_pci_addr (unformat_input_t *input, va_list *args)
755 vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
758 if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
764 addr->function = x[3];
770 unformat_fib_path (unformat_input_t *input, va_list *args)
772 vat_main_t *vam = va_arg (*args, vat_main_t *);
773 vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
774 u32 weight, preference;
775 mpls_label_t out_label;
777 clib_memset (path, 0, sizeof (*path));
779 path->sw_if_index = ~0;
783 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
785 if (unformat (input, "%U %U", unformat_vl_api_ip4_address,
786 &path->nh.address.ip4, api_unformat_sw_if_index, vam,
789 path->proto = FIB_API_PATH_NH_PROTO_IP4;
791 else if (unformat (input, "%U %U",
792 unformat_vl_api_ip6_address,
793 &path->nh.address.ip6,
794 api_unformat_sw_if_index, vam, &path->sw_if_index))
796 path->proto = FIB_API_PATH_NH_PROTO_IP6;
798 else if (unformat (input, "weight %u", &weight))
800 path->weight = weight;
802 else if (unformat (input, "preference %u", &preference))
804 path->preference = preference;
806 else if (unformat (input, "%U next-hop-table %d",
807 unformat_vl_api_ip4_address,
808 &path->nh.address.ip4, &path->table_id))
810 path->proto = FIB_API_PATH_NH_PROTO_IP4;
812 else if (unformat (input, "%U next-hop-table %d",
813 unformat_vl_api_ip6_address,
814 &path->nh.address.ip6, &path->table_id))
816 path->proto = FIB_API_PATH_NH_PROTO_IP6;
818 else if (unformat (input, "%U",
819 unformat_vl_api_ip4_address, &path->nh.address.ip4))
822 * the recursive next-hops are by default in the default table
825 path->sw_if_index = ~0;
826 path->proto = FIB_API_PATH_NH_PROTO_IP4;
828 else if (unformat (input, "%U",
829 unformat_vl_api_ip6_address, &path->nh.address.ip6))
832 * the recursive next-hops are by default in the default table
835 path->sw_if_index = ~0;
836 path->proto = FIB_API_PATH_NH_PROTO_IP6;
838 else if (unformat (input, "resolve-via-host"))
840 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
842 else if (unformat (input, "resolve-via-attached"))
844 path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
846 else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
848 path->type = FIB_API_PATH_TYPE_LOCAL;
849 path->sw_if_index = ~0;
850 path->proto = FIB_API_PATH_NH_PROTO_IP4;
852 else if (unformat (input, "ip6-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_IP6;
858 else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
860 else if (unformat (input, "via-label %d", &path->nh.via_label))
862 path->proto = FIB_API_PATH_NH_PROTO_MPLS;
863 path->sw_if_index = ~0;
865 else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
867 path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
868 path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
870 else if (unformat (input, "local"))
872 path->type = FIB_API_PATH_TYPE_LOCAL;
874 else if (unformat (input, "out-labels"))
876 while (unformat (input, "%d", &out_label))
878 path->label_stack[path->n_labels].label = out_label;
879 path->label_stack[path->n_labels].is_uniform = 0;
880 path->label_stack[path->n_labels].ttl = 64;
884 else if (unformat (input, "via"))
886 /* new path, back up and return */
887 unformat_put_input (input);
888 unformat_put_input (input);
889 unformat_put_input (input);
890 unformat_put_input (input);
899 path->proto = ntohl (path->proto);
900 path->type = ntohl (path->type);
901 path->flags = ntohl (path->flags);
902 path->table_id = ntohl (path->table_id);
903 path->sw_if_index = ntohl (path->sw_if_index);
908 #define foreach_create_subif_bit \
915 _(outer_vlan_id_any) \
918 #define foreach_create_subif_flag \
923 _(4, "exact_match") \
924 _(5, "default_sub") \
925 _(6, "outer_vlan_id_any") \
926 _(7, "inner_vlan_id_any")
929 #define foreach_tcp_proto_field \
933 #define foreach_udp_proto_field \
937 #define foreach_ip4_proto_field \
949 u16 src_port, dst_port;
952 #if VPP_API_TEST_BUILTIN == 0
954 unformat_tcp_mask (unformat_input_t *input, va_list *args)
956 u8 **maskp = va_arg (*args, u8 **);
958 u8 found_something = 0;
961 #define _(a) u8 a = 0;
962 foreach_tcp_proto_field;
965 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
969 #define _(a) else if (unformat (input, #a)) a = 1;
970 foreach_tcp_proto_field
975 #define _(a) found_something += a;
976 foreach_tcp_proto_field;
979 if (found_something == 0)
982 vec_validate (mask, sizeof (*tcp) - 1);
984 tcp = (tcp_header_t *) mask;
988 clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
989 foreach_tcp_proto_field;
997 unformat_udp_mask (unformat_input_t *input, va_list *args)
999 u8 **maskp = va_arg (*args, u8 **);
1001 u8 found_something = 0;
1004 #define _(a) u8 a = 0;
1005 foreach_udp_proto_field;
1008 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1012 #define _(a) else if (unformat (input, #a)) a = 1;
1013 foreach_udp_proto_field
1018 #define _(a) found_something += a;
1019 foreach_udp_proto_field;
1022 if (found_something == 0)
1025 vec_validate (mask, sizeof (*udp) - 1);
1027 udp = (udp_header_t *) mask;
1031 clib_memset (&udp->a, 0xff, sizeof (udp->a));
1032 foreach_udp_proto_field;
1040 unformat_l4_mask (unformat_input_t *input, va_list *args)
1042 u8 **maskp = va_arg (*args, u8 **);
1043 u16 src_port = 0, dst_port = 0;
1044 tcpudp_header_t *tcpudp;
1046 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1048 if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
1050 else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
1052 else if (unformat (input, "src_port"))
1054 else if (unformat (input, "dst_port"))
1060 if (!src_port && !dst_port)
1064 vec_validate (mask, sizeof (tcpudp_header_t) - 1);
1066 tcpudp = (tcpudp_header_t *) mask;
1067 tcpudp->src_port = src_port;
1068 tcpudp->dst_port = dst_port;
1076 unformat_ip4_mask (unformat_input_t * input, va_list * args)
1078 u8 **maskp = va_arg (*args, u8 **);
1080 u8 found_something = 0;
1083 #define _(a) u8 a=0;
1084 foreach_ip4_proto_field;
1090 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1092 if (unformat (input, "version"))
1094 else if (unformat (input, "hdr_length"))
1096 else if (unformat (input, "src"))
1098 else if (unformat (input, "dst"))
1100 else if (unformat (input, "proto"))
1103 #define _(a) else if (unformat (input, #a)) a=1;
1104 foreach_ip4_proto_field
1110 #define _(a) found_something += a;
1111 foreach_ip4_proto_field;
1114 if (found_something == 0)
1117 vec_validate (mask, sizeof (*ip) - 1);
1119 ip = (ip4_header_t *) mask;
1121 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1122 foreach_ip4_proto_field;
1125 ip->ip_version_and_header_length = 0;
1128 ip->ip_version_and_header_length |= 0xF0;
1131 ip->ip_version_and_header_length |= 0x0F;
1137 #define foreach_ip6_proto_field \
1145 unformat_ip6_mask (unformat_input_t * input, va_list * args)
1147 u8 **maskp = va_arg (*args, u8 **);
1149 u8 found_something = 0;
1151 u32 ip_version_traffic_class_and_flow_label;
1153 #define _(a) u8 a=0;
1154 foreach_ip6_proto_field;
1157 u8 traffic_class = 0;
1160 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1162 if (unformat (input, "version"))
1164 else if (unformat (input, "traffic-class"))
1166 else if (unformat (input, "flow-label"))
1168 else if (unformat (input, "src"))
1170 else if (unformat (input, "dst"))
1172 else if (unformat (input, "proto"))
1175 #define _(a) else if (unformat (input, #a)) a=1;
1176 foreach_ip6_proto_field
1182 #define _(a) found_something += a;
1183 foreach_ip6_proto_field;
1186 if (found_something == 0)
1189 vec_validate (mask, sizeof (*ip) - 1);
1191 ip = (ip6_header_t *) mask;
1193 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
1194 foreach_ip6_proto_field;
1197 ip_version_traffic_class_and_flow_label = 0;
1200 ip_version_traffic_class_and_flow_label |= 0xF0000000;
1203 ip_version_traffic_class_and_flow_label |= 0x0FF00000;
1206 ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
1208 ip->ip_version_traffic_class_and_flow_label =
1209 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1216 unformat_l3_mask (unformat_input_t * input, va_list * args)
1218 u8 **maskp = va_arg (*args, u8 **);
1220 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1222 if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
1224 else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
1233 unformat_l2_mask (unformat_input_t * input, va_list * args)
1235 u8 **maskp = va_arg (*args, u8 **);
1250 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1252 if (unformat (input, "src"))
1254 else if (unformat (input, "dst"))
1256 else if (unformat (input, "proto"))
1258 else if (unformat (input, "tag1"))
1260 else if (unformat (input, "tag2"))
1262 else if (unformat (input, "ignore-tag1"))
1264 else if (unformat (input, "ignore-tag2"))
1266 else if (unformat (input, "cos1"))
1268 else if (unformat (input, "cos2"))
1270 else if (unformat (input, "dot1q"))
1272 else if (unformat (input, "dot1ad"))
1277 if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
1278 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1281 if (tag1 || ignore_tag1 || cos1 || dot1q)
1283 if (tag2 || ignore_tag2 || cos2 || dot1ad)
1286 vec_validate (mask, len - 1);
1289 clib_memset (mask, 0xff, 6);
1292 clib_memset (mask + 6, 0xff, 6);
1296 /* inner vlan tag */
1305 mask[21] = mask[20] = 0xff;
1326 mask[16] = mask[17] = 0xff;
1336 mask[12] = mask[13] = 0xff;
1343 unformat_classify_mask (unformat_input_t * input, va_list * args)
1345 u8 **maskp = va_arg (*args, u8 **);
1346 u32 *skipp = va_arg (*args, u32 *);
1347 u32 *matchp = va_arg (*args, u32 *);
1355 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1357 if (unformat (input, "hex %U", unformat_hex_string, &mask))
1359 else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
1361 else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
1363 else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
1377 if (mask || l2 || l3 || l4)
1381 /* "With a free Ethernet header in every package" */
1383 vec_validate (l2, 13);
1387 vec_append (mask, l3);
1392 vec_append (mask, l4);
1397 /* Scan forward looking for the first significant mask octet */
1398 for (i = 0; i < vec_len (mask); i++)
1402 /* compute (skip, match) params */
1403 *skipp = i / sizeof (u32x4);
1404 vec_delete (mask, *skipp * sizeof (u32x4), 0);
1406 /* Pad mask to an even multiple of the vector size */
1407 while (vec_len (mask) % sizeof (u32x4))
1410 match = vec_len (mask) / sizeof (u32x4);
1412 for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
1414 u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
1415 if (*tmp || *(tmp + 1))
1420 clib_warning ("BUG: match 0");
1422 vec_set_len (mask, match * sizeof (u32x4));
1432 #endif /* VPP_API_TEST_BUILTIN */
1434 #define foreach_l2_next \
1436 _(ethernet, ETHERNET_INPUT) \
1441 unformat_l2_next_index (unformat_input_t * input, va_list * args)
1443 u32 *miss_next_indexp = va_arg (*args, u32 *);
1448 if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
1452 if (unformat (input, "%d", &tmp))
1461 *miss_next_indexp = next_index;
1465 #define foreach_ip_next \
1471 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
1473 u32 *miss_next_indexp = va_arg (*args, u32 *);
1478 if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
1482 if (unformat (input, "%d", &tmp))
1491 *miss_next_indexp = next_index;
1495 #define foreach_acl_next \
1499 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
1501 u32 *miss_next_indexp = va_arg (*args, u32 *);
1506 if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
1510 if (unformat (input, "permit"))
1515 else if (unformat (input, "%d", &tmp))
1524 *miss_next_indexp = next_index;
1529 unformat_policer_precolor (unformat_input_t * input, va_list * args)
1531 u32 *r = va_arg (*args, u32 *);
1533 if (unformat (input, "conform-color"))
1534 *r = POLICE_CONFORM;
1535 else if (unformat (input, "exceed-color"))
1543 #if VPP_API_TEST_BUILTIN == 0
1545 unformat_l4_match (unformat_input_t * input, va_list * args)
1547 u8 **matchp = va_arg (*args, u8 **);
1549 u8 *proto_header = 0;
1555 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1557 if (unformat (input, "src_port %d", &src_port))
1559 else if (unformat (input, "dst_port %d", &dst_port))
1565 h.src_port = clib_host_to_net_u16 (src_port);
1566 h.dst_port = clib_host_to_net_u16 (dst_port);
1567 vec_validate (proto_header, sizeof (h) - 1);
1568 memcpy (proto_header, &h, sizeof (h));
1570 *matchp = proto_header;
1576 unformat_ip4_match (unformat_input_t * input, va_list * args)
1578 u8 **matchp = va_arg (*args, u8 **);
1585 int src = 0, dst = 0;
1586 ip4_address_t src_val, dst_val;
1593 int fragment_id = 0;
1594 u32 fragment_id_val;
1600 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1602 if (unformat (input, "version %d", &version_val))
1604 else if (unformat (input, "hdr_length %d", &hdr_length_val))
1606 else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
1608 else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
1610 else if (unformat (input, "proto %d", &proto_val))
1612 else if (unformat (input, "tos %d", &tos_val))
1614 else if (unformat (input, "length %d", &length_val))
1616 else if (unformat (input, "fragment_id %d", &fragment_id_val))
1618 else if (unformat (input, "ttl %d", &ttl_val))
1620 else if (unformat (input, "checksum %d", &checksum_val))
1626 if (version + hdr_length + src + dst + proto + tos + length + fragment_id
1627 + ttl + checksum == 0)
1631 * Aligned because we use the real comparison functions
1633 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1635 ip = (ip4_header_t *) match;
1637 /* These are realistically matched in practice */
1639 ip->src_address.as_u32 = src_val.as_u32;
1642 ip->dst_address.as_u32 = dst_val.as_u32;
1645 ip->protocol = proto_val;
1648 /* These are not, but they're included for completeness */
1650 ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
1653 ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
1659 ip->length = clib_host_to_net_u16 (length_val);
1665 ip->checksum = clib_host_to_net_u16 (checksum_val);
1672 unformat_ip6_match (unformat_input_t * input, va_list * args)
1674 u8 **matchp = va_arg (*args, u8 **);
1679 u8 traffic_class = 0;
1680 u32 traffic_class_val = 0;
1683 int src = 0, dst = 0;
1684 ip6_address_t src_val, dst_val;
1687 int payload_length = 0;
1688 u32 payload_length_val;
1691 u32 ip_version_traffic_class_and_flow_label;
1693 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1695 if (unformat (input, "version %d", &version_val))
1697 else if (unformat (input, "traffic_class %d", &traffic_class_val))
1699 else if (unformat (input, "flow_label %d", &flow_label_val))
1701 else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
1703 else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
1705 else if (unformat (input, "proto %d", &proto_val))
1707 else if (unformat (input, "payload_length %d", &payload_length_val))
1709 else if (unformat (input, "hop_limit %d", &hop_limit_val))
1715 if (version + traffic_class + flow_label + src + dst + proto +
1716 payload_length + hop_limit == 0)
1720 * Aligned because we use the real comparison functions
1722 vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
1724 ip = (ip6_header_t *) match;
1727 clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
1730 clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
1733 ip->protocol = proto_val;
1735 ip_version_traffic_class_and_flow_label = 0;
1738 ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
1741 ip_version_traffic_class_and_flow_label |=
1742 (traffic_class_val & 0xFF) << 20;
1745 ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
1747 ip->ip_version_traffic_class_and_flow_label =
1748 clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
1751 ip->payload_length = clib_host_to_net_u16 (payload_length_val);
1754 ip->hop_limit = hop_limit_val;
1761 unformat_l3_match (unformat_input_t * input, va_list * args)
1763 u8 **matchp = va_arg (*args, u8 **);
1765 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1767 if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
1769 else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
1778 unformat_vlan_tag (unformat_input_t * input, va_list * args)
1780 u8 *tagp = va_arg (*args, u8 *);
1783 if (unformat (input, "%d", &tag))
1785 tagp[0] = (tag >> 8) & 0x0F;
1786 tagp[1] = tag & 0xFF;
1794 unformat_l2_match (unformat_input_t * input, va_list * args)
1796 u8 **matchp = va_arg (*args, u8 **);
1816 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1818 if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
1821 if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
1823 else if (unformat (input, "proto %U",
1824 unformat_ethernet_type_host_byte_order, &proto_val))
1826 else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
1828 else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
1830 else if (unformat (input, "ignore-tag1"))
1832 else if (unformat (input, "ignore-tag2"))
1834 else if (unformat (input, "cos1 %d", &cos1_val))
1836 else if (unformat (input, "cos2 %d", &cos2_val))
1841 if ((src + dst + proto + tag1 + tag2 +
1842 ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
1845 if (tag1 || ignore_tag1 || cos1)
1847 if (tag2 || ignore_tag2 || cos2)
1850 vec_validate_aligned (match, len - 1, sizeof (u32x4));
1853 clib_memcpy (match, dst_val, 6);
1856 clib_memcpy (match + 6, src_val, 6);
1860 /* inner vlan tag */
1861 match[19] = tag2_val[1];
1862 match[18] = tag2_val[0];
1864 match[18] |= (cos2_val & 0x7) << 5;
1867 match[21] = proto_val & 0xff;
1868 match[20] = proto_val >> 8;
1872 match[15] = tag1_val[1];
1873 match[14] = tag1_val[0];
1876 match[14] |= (cos1_val & 0x7) << 5;
1882 match[15] = tag1_val[1];
1883 match[14] = tag1_val[0];
1886 match[17] = proto_val & 0xff;
1887 match[16] = proto_val >> 8;
1890 match[14] |= (cos1_val & 0x7) << 5;
1896 match[18] |= (cos2_val & 0x7) << 5;
1898 match[14] |= (cos1_val & 0x7) << 5;
1901 match[13] = proto_val & 0xff;
1902 match[12] = proto_val >> 8;
1910 unformat_qos_source (unformat_input_t * input, va_list * args)
1912 int *qs = va_arg (*args, int *);
1914 if (unformat (input, "ip"))
1915 *qs = QOS_SOURCE_IP;
1916 else if (unformat (input, "mpls"))
1917 *qs = QOS_SOURCE_MPLS;
1918 else if (unformat (input, "ext"))
1919 *qs = QOS_SOURCE_EXT;
1920 else if (unformat (input, "vlan"))
1921 *qs = QOS_SOURCE_VLAN;
1930 api_unformat_classify_match (unformat_input_t * input, va_list * args)
1932 u8 **matchp = va_arg (*args, u8 **);
1933 u32 skip_n_vectors = va_arg (*args, u32);
1934 u32 match_n_vectors = va_arg (*args, u32);
1941 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1943 if (unformat (input, "hex %U", unformat_hex_string, &match))
1945 else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
1947 else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
1949 else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
1963 if (match || l2 || l3 || l4)
1967 /* "Win a free Ethernet header in every packet" */
1969 vec_validate_aligned (l2, 13, sizeof (u32x4));
1973 vec_append_aligned (match, l3, sizeof (u32x4));
1978 vec_append_aligned (match, l4, sizeof (u32x4));
1983 /* Make sure the vector is big enough even if key is all 0's */
1984 vec_validate_aligned
1985 (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
1988 /* Set size, include skipped vectors */
1989 vec_set_len (match, (match_n_vectors + skip_n_vectors) * sizeof (u32x4));
1999 #define foreach_vtr_op \
2000 _ ("disable", L2_VTR_DISABLED) \
2001 _ ("push-1", L2_VTR_PUSH_1) \
2002 _ ("push-2", L2_VTR_PUSH_2) \
2003 _ ("pop-1", L2_VTR_POP_1) \
2004 _ ("pop-2", L2_VTR_POP_2) \
2005 _ ("translate-1-1", L2_VTR_TRANSLATE_1_1) \
2006 _ ("translate-1-2", L2_VTR_TRANSLATE_1_2) \
2007 _ ("translate-2-1", L2_VTR_TRANSLATE_2_1) \
2008 _ ("translate-2-2", L2_VTR_TRANSLATE_2_2)
2011 api_get_first_msg_id (vat_main_t *vam)
2013 vl_api_get_first_msg_id_t *mp;
2014 unformat_input_t *i = vam->input;
2019 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2021 if (unformat (i, "client %s", &name))
2029 errmsg ("missing client name");
2034 if (vec_len (name) > 63)
2036 errmsg ("client name too long");
2040 M (GET_FIRST_MSG_ID, mp);
2041 clib_memcpy (mp->name, name, vec_len (name));
2047 #define foreach_pbb_vtr_op \
2048 _("disable", L2_VTR_DISABLED) \
2049 _("pop", L2_VTR_POP_2) \
2050 _("push", L2_VTR_PUSH_2)
2053 api_sock_init_shm (vat_main_t * vam)
2055 #if VPP_API_TEST_BUILTIN == 0
2056 unformat_input_t *i = vam->input;
2057 vl_api_shm_elem_config_t *config = 0;
2058 u64 size = 64 << 20;
2061 while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2063 if (unformat (i, "size %U", unformat_memory_size, &size))
2070 * Canned custom ring allocator config.
2071 * Should probably parse all of this
2073 vec_validate (config, 6);
2074 config[0].type = VL_API_VLIB_RING;
2075 config[0].size = 256;
2076 config[0].count = 32;
2078 config[1].type = VL_API_VLIB_RING;
2079 config[1].size = 1024;
2080 config[1].count = 16;
2082 config[2].type = VL_API_VLIB_RING;
2083 config[2].size = 4096;
2084 config[2].count = 2;
2086 config[3].type = VL_API_CLIENT_RING;
2087 config[3].size = 256;
2088 config[3].count = 32;
2090 config[4].type = VL_API_CLIENT_RING;
2091 config[4].size = 1024;
2092 config[4].count = 16;
2094 config[5].type = VL_API_CLIENT_RING;
2095 config[5].size = 4096;
2096 config[5].count = 2;
2098 config[6].type = VL_API_QUEUE;
2099 config[6].count = 128;
2100 config[6].size = sizeof (uword);
2102 rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
2104 vam->client_index_invalid = 1;
2112 q_or_quit (vat_main_t * vam)
2114 #if VPP_API_TEST_BUILTIN == 0
2115 longjmp (vam->jump_buf, 1);
2117 return 0; /* not so much */
2121 q (vat_main_t * vam)
2123 return q_or_quit (vam);
2127 quit (vat_main_t * vam)
2129 return q_or_quit (vam);
2133 comment (vat_main_t * vam)
2139 elog_save (vat_main_t * vam)
2141 #if VPP_API_TEST_BUILTIN == 0
2142 elog_main_t *em = &vam->elog_main;
2143 unformat_input_t *i = vam->input;
2144 char *file, *chroot_file;
2145 clib_error_t *error;
2147 if (!unformat (i, "%s", &file))
2149 errmsg ("expected file name, got `%U'", format_unformat_error, i);
2153 /* It's fairly hard to get "../oopsie" through unformat; just in case */
2154 if (strstr (file, "..") || index (file, '/'))
2156 errmsg ("illegal characters in filename '%s'", file);
2160 chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
2164 errmsg ("Saving %wd of %wd events to %s",
2165 elog_n_events_in_buffer (em),
2166 elog_buffer_capacity (em), chroot_file);
2168 error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
2169 vec_free (chroot_file);
2172 clib_error_report (error);
2174 errmsg ("Use the vpp event loger...");
2181 elog_setup (vat_main_t * vam)
2183 #if VPP_API_TEST_BUILTIN == 0
2184 elog_main_t *em = &vam->elog_main;
2185 unformat_input_t *i = vam->input;
2186 u32 nevents = 128 << 10;
2188 (void) unformat (i, "nevents %d", &nevents);
2190 elog_init (em, nevents);
2191 vl_api_set_elog_main (em);
2192 vl_api_set_elog_trace_api_messages (1);
2193 errmsg ("Event logger initialized with %u events", nevents);
2195 errmsg ("Use the vpp event loger...");
2201 elog_enable (vat_main_t * vam)
2203 #if VPP_API_TEST_BUILTIN == 0
2204 elog_main_t *em = &vam->elog_main;
2206 elog_enable_disable (em, 1 /* enable */ );
2207 vl_api_set_elog_trace_api_messages (1);
2208 errmsg ("Event logger enabled...");
2210 errmsg ("Use the vpp event loger...");
2216 elog_disable (vat_main_t * vam)
2218 #if VPP_API_TEST_BUILTIN == 0
2219 elog_main_t *em = &vam->elog_main;
2221 elog_enable_disable (em, 0 /* enable */ );
2222 vl_api_set_elog_trace_api_messages (1);
2223 errmsg ("Event logger disabled...");
2225 errmsg ("Use the vpp event loger...");
2231 statseg (vat_main_t * vam)
2233 ssvm_private_t *ssvmp = &vam->stat_segment;
2234 ssvm_shared_header_t *shared_header = ssvmp->sh;
2235 vlib_counter_t **counters;
2236 u64 thread0_index1_packets;
2237 u64 thread0_index1_bytes;
2238 f64 vector_rate, input_rate;
2241 uword *counter_vector_by_name;
2242 if (vam->stat_segment_lockp == 0)
2244 errmsg ("Stat segment not mapped...");
2248 /* look up "/if/rx for sw_if_index 1 as a test */
2250 clib_spinlock_lock (vam->stat_segment_lockp);
2252 counter_vector_by_name = (uword *) shared_header->opaque[1];
2254 p = hash_get_mem (counter_vector_by_name, "/if/rx");
2257 clib_spinlock_unlock (vam->stat_segment_lockp);
2258 errmsg ("/if/tx not found?");
2262 /* Fish per-thread vector of combined counters from shared memory */
2263 counters = (vlib_counter_t **) p[0];
2265 if (vec_len (counters[0]) < 2)
2267 clib_spinlock_unlock (vam->stat_segment_lockp);
2268 errmsg ("/if/tx vector length %d", vec_len (counters[0]));
2272 /* Read thread 0 sw_if_index 1 counter */
2273 thread0_index1_packets = counters[0][1].packets;
2274 thread0_index1_bytes = counters[0][1].bytes;
2276 p = hash_get_mem (counter_vector_by_name, "vector_rate");
2279 clib_spinlock_unlock (vam->stat_segment_lockp);
2280 errmsg ("vector_rate not found?");
2284 vector_rate = *(f64 *) (p[0]);
2285 p = hash_get_mem (counter_vector_by_name, "input_rate");
2288 clib_spinlock_unlock (vam->stat_segment_lockp);
2289 errmsg ("input_rate not found?");
2292 input_rate = *(f64 *) (p[0]);
2294 clib_spinlock_unlock (vam->stat_segment_lockp);
2296 print (vam->ofp, "vector_rate %.2f input_rate %.2f",
2297 vector_rate, input_rate);
2298 print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
2299 thread0_index1_packets, thread0_index1_bytes);
2305 cmd_cmp (void *a1, void *a2)
2310 return strcmp ((char *) (c1[0]), (char *) (c2[0]));
2314 help (vat_main_t * vam)
2319 unformat_input_t *i = vam->input;
2322 if (unformat (i, "%s", &name))
2328 hs = hash_get_mem (vam->help_by_name, name);
2330 print (vam->ofp, "usage: %s %s", name, hs[0]);
2332 print (vam->ofp, "No such msg / command '%s'", name);
2337 print (vam->ofp, "Help is available for the following:");
2339 hash_foreach_pair (p, vam->function_by_name,
2341 vec_add1 (cmds, (u8 *)(p->key));
2344 vec_sort_with_function (cmds, cmd_cmp);
2346 for (j = 0; j < vec_len (cmds); j++)
2347 print (vam->ofp, "%s", cmds[j]);
2354 set (vat_main_t * vam)
2356 u8 *name = 0, *value = 0;
2357 unformat_input_t *i = vam->input;
2359 if (unformat (i, "%s", &name))
2361 /* The input buffer is a vector, not a string. */
2362 value = vec_dup (i->buffer);
2363 vec_delete (value, i->index, 0);
2364 /* Almost certainly has a trailing newline */
2365 if (value[vec_len (value) - 1] == '\n')
2366 value[vec_len (value) - 1] = 0;
2367 /* Make sure it's a proper string, one way or the other */
2368 vec_add1 (value, 0);
2369 (void) clib_macro_set_value (&vam->macro_main,
2370 (char *) name, (char *) value);
2373 errmsg ("usage: set <name> <value>");
2381 unset (vat_main_t * vam)
2385 if (unformat (vam->input, "%s", &name))
2386 if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
2387 errmsg ("unset: %s wasn't set", name);
2400 macro_sort_cmp (void *a1, void *a2)
2402 macro_sort_t *s1 = a1;
2403 macro_sort_t *s2 = a2;
2405 return strcmp ((char *) (s1->name), (char *) (s2->name));
2409 dump_macro_table (vat_main_t * vam)
2411 macro_sort_t *sort_me = 0, *sm;
2415 hash_foreach_pair (p, vam->macro_main.the_value_table_hash, ({
2416 vec_add2 (sort_me, sm, 1);
2417 sm->name = (u8 *) (p->key);
2418 sm->value = (u8 *) (p->value[0]);
2421 vec_sort_with_function (sort_me, macro_sort_cmp);
2423 if (vec_len (sort_me))
2424 print (vam->ofp, "%-15s%s", "Name", "Value");
2426 print (vam->ofp, "The macro table is empty...");
2428 for (i = 0; i < vec_len (sort_me); i++)
2429 print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
2434 value_sort_cmp (void *a1, void *a2)
2436 name_sort_t *n1 = a1;
2437 name_sort_t *n2 = a2;
2439 if (n1->value < n2->value)
2441 if (n1->value > n2->value)
2448 dump_msg_api_table (vat_main_t * vam)
2450 api_main_t *am = vlibapi_get_main ();
2451 name_sort_t *nses = 0, *ns;
2455 hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
2457 vec_add2 (nses, ns, 1);
2458 ns->name = (u8 *)(hp->key);
2459 ns->value = (u32) hp->value[0];
2462 vec_sort_with_function (nses, value_sort_cmp);
2464 for (i = 0; i < vec_len (nses); i++)
2465 print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
2471 get_msg_id (vat_main_t * vam)
2476 if (unformat (vam->input, "%s", &name_and_crc))
2478 message_index = vl_msg_api_get_msg_index (name_and_crc);
2479 if (message_index == ~0)
2481 print (vam->ofp, " '%s' not found", name_and_crc);
2484 print (vam->ofp, " '%s' has message index %d",
2485 name_and_crc, message_index);
2488 errmsg ("name_and_crc required...");
2493 search_node_table (vat_main_t * vam)
2495 unformat_input_t *line_input = vam->input;
2498 vlib_node_t *node, *next_node;
2501 if (vam->graph_node_index_by_name == 0)
2503 print (vam->ofp, "Node table empty, issue get_node_graph...");
2507 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2509 if (unformat (line_input, "%s", &node_to_find))
2511 vec_add1 (node_to_find, 0);
2512 p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
2515 print (vam->ofp, "%s not found...", node_to_find);
2518 node = vam->graph_nodes[0][p[0]];
2519 print (vam->ofp, "[%d] %s", p[0], node->name);
2520 for (j = 0; j < vec_len (node->next_nodes); j++)
2522 if (node->next_nodes[j] != ~0)
2524 next_node = vam->graph_nodes[0][node->next_nodes[j]];
2525 print (vam->ofp, " [%d] %s", j, next_node->name);
2532 clib_warning ("parse error '%U'", format_unformat_error,
2538 vec_free (node_to_find);
2547 script (vat_main_t * vam)
2549 #if (VPP_API_TEST_BUILTIN==0)
2551 char *save_current_file;
2552 unformat_input_t save_input;
2553 jmp_buf save_jump_buf;
2554 u32 save_line_number;
2556 FILE *new_fp, *save_ifp;
2558 if (unformat (vam->input, "%s", &s))
2560 new_fp = fopen ((char *) s, "r");
2563 errmsg ("Couldn't open script file %s", s);
2570 errmsg ("Missing script name");
2574 clib_memcpy (&save_input, &vam->input, sizeof (save_input));
2575 clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
2576 save_ifp = vam->ifp;
2577 save_line_number = vam->input_line_number;
2578 save_current_file = (char *) vam->current_file;
2580 vam->input_line_number = 0;
2582 vam->current_file = s;
2585 clib_memcpy (&vam->input, &save_input, sizeof (save_input));
2586 clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
2587 vam->ifp = save_ifp;
2588 vam->input_line_number = save_line_number;
2589 vam->current_file = (u8 *) save_current_file;
2594 clib_warning ("use the exec command...");
2600 echo (vat_main_t * vam)
2602 print (vam->ofp, "%v", vam->input->buffer);
2606 int exec (vat_main_t *vam) __attribute__ ((weak));
2608 exec (vat_main_t *vam)
2614 name_sort_cmp (void *a1, void *a2)
2616 name_sort_t *n1 = a1;
2617 name_sort_t *n2 = a2;
2619 return strcmp ((char *) n1->name, (char *) n2->name);
2623 dump_interface_table (vat_main_t *vam)
2626 name_sort_t *nses = 0, *ns;
2628 if (vam->json_output)
2631 "JSON output supported only for VPE API calls and dump_stats_table");
2635 hash_foreach_pair (p, vam->sw_if_index_by_interface_name, ({
2636 vec_add2 (nses, ns, 1);
2637 ns->name = (u8 *) (p->key);
2638 ns->value = (u32) p->value[0];
2641 vec_sort_with_function (nses, name_sort_cmp);
2643 print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
2644 vec_foreach (ns, nses)
2646 print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
2653 dump_sub_interface_table (vat_main_t *vam)
2655 const sw_interface_subif_t *sub = NULL;
2657 if (vam->json_output)
2660 "JSON output supported only for VPE API calls and dump_stats_table");
2664 print (vam->ofp, "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
2665 "Interface", "sw_if_index", "sub id", "dot1ad", "tags", "outer id",
2666 "inner id", "exact", "default", "outer any", "inner any");
2668 vec_foreach (sub, vam->sw_if_subif_table)
2670 print (vam->ofp, "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
2671 sub->interface_name, sub->sw_if_index, sub->sub_id,
2672 sub->sub_dot1ad ? "dot1ad" : "dot1q", sub->sub_number_of_tags,
2673 sub->sub_outer_vlan_id, sub->sub_inner_vlan_id,
2674 sub->sub_exact_match, sub->sub_default,
2675 sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
2676 if (sub->vtr_op != L2_VTR_DISABLED)
2679 " vlan-tag-rewrite - op: %-14s [ dot1q: %d "
2680 "tag1: %d tag2: %d ]",
2681 str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q, sub->vtr_tag1,
2689 /* List of API message constructors, CLI names map to api_xxx */
2690 #define foreach_vpe_api_msg \
2691 _(get_first_msg_id, "client <name>") \
2692 _(sock_init_shm, "size <nnn>") \
2693 /* List of command functions, CLI names map directly to functions */
2694 #define foreach_cli_function \
2695 _ (comment, "usage: comment <ignore-rest-of-line>") \
2696 _ (dump_interface_table, "usage: dump_interface_table") \
2697 _ (dump_sub_interface_table, "usage: dump_sub_interface_table") \
2698 _ (dump_macro_table, "usage: dump_macro_table ") \
2699 _ (dump_msg_api_table, "usage: dump_msg_api_table") \
2700 _ (elog_setup, "usage: elog_setup [nevents, default 128K]") \
2701 _ (elog_disable, "usage: elog_disable") \
2702 _ (elog_enable, "usage: elog_enable") \
2703 _ (elog_save, "usage: elog_save <filename>") \
2704 _ (get_msg_id, "usage: get_msg_id name_and_crc") \
2705 _ (echo, "usage: echo <message>") \
2706 _ (help, "usage: help") \
2707 _ (q, "usage: quit") \
2708 _ (quit, "usage: quit") \
2709 _ (search_node_table, "usage: search_node_table <name>...") \
2710 _ (set, "usage: set <variable-name> <value>") \
2711 _ (script, "usage: script <file-name>") \
2712 _ (statseg, "usage: statseg") \
2713 _ (unset, "usage: unset <variable-name>")
2716 static void vl_api_##n##_t_handler_uni \
2717 (vl_api_##n##_t * mp) \
2719 vat_main_t * vam = &vat_main; \
2720 if (vam->json_output) { \
2721 vl_api_##n##_t_handler_json(mp); \
2723 vl_api_##n##_t_handler(mp); \
2726 foreach_vpe_api_reply_msg;
2727 #if VPP_API_TEST_BUILTIN == 0
2728 foreach_standalone_reply_msg;
2733 vat_api_hookup (vat_main_t * vam)
2736 vl_msg_api_config (&(vl_msg_api_msg_config_t){ \
2737 .id = VL_API_##N + 1, \
2739 .handler = vl_api_##n##_t_handler_uni, \
2740 .endian = vl_api_##n##_t_endian, \
2741 .format_fn = vl_api_##n##_t_format, \
2742 .size = sizeof (vl_api_##n##_t), \
2744 .tojson = vl_api_##n##_t_tojson, \
2745 .fromjson = vl_api_##n##_t_fromjson, \
2746 .calc_size = vl_api_##n##_t_calc_size, \
2748 foreach_vpe_api_reply_msg;
2749 #if VPP_API_TEST_BUILTIN == 0
2750 foreach_standalone_reply_msg;
2754 #if (VPP_API_TEST_BUILTIN==0)
2755 vl_msg_api_set_first_available_msg_id (VL_MSG_MEMCLNT_LAST + 1);
2757 vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
2759 vam->function_by_name = hash_create_string (0, sizeof (uword));
2761 vam->help_by_name = hash_create_string (0, sizeof (uword));
2764 /* API messages we can send */
2765 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
2766 foreach_vpe_api_msg;
2770 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2771 foreach_vpe_api_msg;
2775 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
2776 foreach_cli_function;
2780 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
2781 foreach_cli_function;
2785 #if VPP_API_TEST_BUILTIN
2786 static clib_error_t *
2787 vat_api_hookup_shim (vlib_main_t * vm)
2789 vat_api_hookup (&vat_main);
2793 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
2797 * fd.io coding-style-patch-verification: ON
2800 * eval: (c-set-style "gnu")