1/*
2 *------------------------------------------------------------------
3 * api_format.c
4 *
5 * Copyright (c) 2014-2016 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:
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
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 *------------------------------------------------------------------
18 */
19
20#include <vat/vat.h>
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/l2tp/l2tp.h>
31#include <vnet/vxlan/vxlan.h>
32#include <vnet/geneve/geneve.h>
33#include <vnet/gre/gre.h>
34#include <vnet/vxlan-gpe/vxlan_gpe.h>
35#include <vnet/lisp-gpe/lisp_gpe.h>
36
37#include <vpp/api/vpe_msg_enum.h>
38#include <vnet/l2/l2_classify.h>
39#include <vnet/l2/l2_vtr.h>
40#include <vnet/classify/in_out_acl.h>
41#include <vnet/classify/policer_classify.h>
42#include <vnet/classify/flow_classify.h>
43#include <vnet/mpls/mpls.h>
44#include <vnet/ipsec/ipsec.h>
45#include <inttypes.h>
46#include <vnet/cop/cop.h>
47#include <vnet/ip/ip6_hop_by_hop.h>
48#include <vnet/ip/ip_source_and_port_range_check.h>
49#include <vnet/policer/xlate.h>
50#include <vnet/span/span.h>
51#include <vnet/policer/policer.h>
52#include <vnet/policer/police.h>
53#include <vnet/mfib/mfib_types.h>
54#include <vnet/bonding/node.h>
55#include <vnet/qos/qos_types.h>
56#include <vnet/ethernet/ethernet_types_api.h>
57#include <vnet/ip/ip_types_api.h>
58#include "vat/json_format.h"
59#include <vnet/ip/ip_types_api.h>
60#include <vnet/ethernet/ethernet_types_api.h>
61
62#include <inttypes.h>
63#include <sys/stat.h>
64
65#define vl_typedefs		/* define message structures */
66#include <vpp/api/vpe_all_api_h.h>
67#undef vl_typedefs
68
69/* declare message handlers for each api */
70
71#define vl_endianfun		/* define message structures */
72#include <vpp/api/vpe_all_api_h.h>
73#undef vl_endianfun
74
75/* instantiate all the print functions we know about */
76#if VPP_API_TEST_BUILTIN == 0
77#define vl_print(handle, ...)
78#else
79#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80#endif
81#define vl_printfun
82#include <vpp/api/vpe_all_api_h.h>
83#undef vl_printfun
84
85#define __plugin_msg_base 0
86#include <vlibapi/vat_helper_macros.h>
87
88#include <vnet/format_fns.h>
89
90void vl_api_set_elog_main (elog_main_t * m);
91int vl_api_set_elog_trace_api_messages (int enable);
92
93#if VPP_API_TEST_BUILTIN == 0
94#include <netdb.h>
95
96u32
97vl (void *p)
98{
99  return vec_len (p);
100}
101
102int
103vat_socket_connect (vat_main_t * vam)
104{
105  int rv;
106  api_main_t *am = vlibapi_get_main ();
107  vam->socket_client_main = &socket_client_main;
108  if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
109				      "vpp_api_test",
110				      0 /* default socket rx, tx buffer */ )))
111    return rv;
112
113  /* vpp expects the client index in network order */
114  vam->my_client_index = htonl (socket_client_main.client_index);
115  am->my_client_index = vam->my_client_index;
116  return 0;
117}
118#else /* vpp built-in case, we don't do sockets... */
119int
120vat_socket_connect (vat_main_t * vam)
121{
122  return 0;
123}
124
125int
126vl_socket_client_read (int wait)
127{
128  return -1;
129};
130
131int
132vl_socket_client_write ()
133{
134  return -1;
135};
136
137void *
138vl_socket_client_msg_alloc (int nbytes)
139{
140  return 0;
141}
142#endif
143
144
145f64
146vat_time_now (vat_main_t * vam)
147{
148#if VPP_API_TEST_BUILTIN
149  return vlib_time_now (vam->vlib_main);
150#else
151  return clib_time_now (&vam->clib_time);
152#endif
153}
154
155void
156errmsg (char *fmt, ...)
157{
158  vat_main_t *vam = &vat_main;
159  va_list va;
160  u8 *s;
161
162  va_start (va, fmt);
163  s = va_format (0, fmt, &va);
164  va_end (va);
165
166  vec_add1 (s, 0);
167
168#if VPP_API_TEST_BUILTIN
169  vlib_cli_output (vam->vlib_main, (char *) s);
170#else
171  {
172    if (vam->ifp != stdin)
173      fformat (vam->ofp, "%s(%d): \n", vam->current_file,
174	       vam->input_line_number);
175    else
176      fformat (vam->ofp, "%s\n", (char *) s);
177    fflush (vam->ofp);
178  }
179#endif
180
181  vec_free (s);
182}
183
184#if VPP_API_TEST_BUILTIN == 0
185static uword
186api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
187{
188  vat_main_t *vam = va_arg (*args, vat_main_t *);
189  u32 *result = va_arg (*args, u32 *);
190  u8 *if_name;
191  uword *p;
192
193  if (!unformat (input, "%s", &if_name))
194    return 0;
195
196  p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
197  if (p == 0)
198    return 0;
199  *result = p[0];
200  return 1;
201}
202
203static uword
204api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
205{
206  return 0;
207}
208
209/* Parse an IP4 address %d.%d.%d.%d. */
210uword
211unformat_ip4_address (unformat_input_t * input, va_list * args)
212{
213  u8 *result = va_arg (*args, u8 *);
214  unsigned a[4];
215
216  if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
217    return 0;
218
219  if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
220    return 0;
221
222  result[0] = a[0];
223  result[1] = a[1];
224  result[2] = a[2];
225  result[3] = a[3];
226
227  return 1;
228}
229
230uword
231unformat_ethernet_address (unformat_input_t * input, va_list * args)
232{
233  u8 *result = va_arg (*args, u8 *);
234  u32 i, a[6];
235
236  if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
237		 &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
238    return 0;
239
240  /* Check range. */
241  for (i = 0; i < 6; i++)
242    if (a[i] >= (1 << 8))
243      return 0;
244
245  for (i = 0; i < 6; i++)
246    result[i] = a[i];
247
248  return 1;
249}
250
251/* Returns ethernet type as an int in host byte order. */
252uword
253unformat_ethernet_type_host_byte_order (unformat_input_t * input,
254					va_list * args)
255{
256  u16 *result = va_arg (*args, u16 *);
257  int type;
258
259  /* Numeric type. */
260  if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
261    {
262      if (type >= (1 << 16))
263	return 0;
264      *result = type;
265      return 1;
266    }
267  return 0;
268}
269
270/* Parse an IP46 address. */
271uword
272unformat_ip46_address (unformat_input_t * input, va_list * args)
273{
274  ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
275  ip46_type_t type = va_arg (*args, ip46_type_t);
276  if ((type != IP46_TYPE_IP6) &&
277      unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
278    {
279      ip46_address_mask_ip4 (ip46);
280      return 1;
281    }
282  else if ((type != IP46_TYPE_IP4) &&
283	   unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
284    {
285      return 1;
286    }
287  return 0;
288}
289
290/* Parse an IP6 address. */
291uword
292unformat_ip6_address (unformat_input_t * input, va_list * args)
293{
294  ip6_address_t *result = va_arg (*args, ip6_address_t *);
295  u16 hex_quads[8];
296  uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
297  uword c, n_colon, double_colon_index;
298
299  n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
300  double_colon_index = ARRAY_LEN (hex_quads);
301  while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
302    {
303      hex_digit = 16;
304      if (c >= '0' && c <= '9')
305	hex_digit = c - '0';
306      else if (c >= 'a' && c <= 'f')
307	hex_digit = c + 10 - 'a';
308      else if (c >= 'A' && c <= 'F')
309	hex_digit = c + 10 - 'A';
310      else if (c == ':' && n_colon < 2)
311	n_colon++;
312      else
313	{
314	  unformat_put_input (input);
315	  break;
316	}
317
318      /* Too many hex quads. */
319      if (n_hex_quads >= ARRAY_LEN (hex_quads))
320	return 0;
321
322      if (hex_digit < 16)
323	{
324	  hex_quad = (hex_quad << 4) | hex_digit;
325
326	  /* Hex quad must fit in 16 bits. */
327	  if (n_hex_digits >= 4)
328	    return 0;
329
330	  n_colon = 0;
331	  n_hex_digits++;
332	}
333
334      /* Save position of :: */
335      if (n_colon == 2)
336	{
337	  /* More than one :: ? */
338	  if (double_colon_index < ARRAY_LEN (hex_quads))
339	    return 0;
340	  double_colon_index = n_hex_quads;
341	}
342
343      if (n_colon > 0 && n_hex_digits > 0)
344	{
345	  hex_quads[n_hex_quads++] = hex_quad;
346	  hex_quad = 0;
347	  n_hex_digits = 0;
348	}
349    }
350
351  if (n_hex_digits > 0)
352    hex_quads[n_hex_quads++] = hex_quad;
353
354  {
355    word i;
356
357    /* Expand :: to appropriate number of zero hex quads. */
358    if (double_colon_index < ARRAY_LEN (hex_quads))
359      {
360	word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
361
362	for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
363	  hex_quads[n_zero + i] = hex_quads[i];
364
365	for (i = 0; i < n_zero; i++)
366	  hex_quads[double_colon_index + i] = 0;
367
368	n_hex_quads = ARRAY_LEN (hex_quads);
369      }
370
371    /* Too few hex quads given. */
372    if (n_hex_quads < ARRAY_LEN (hex_quads))
373      return 0;
374
375    for (i = 0; i < ARRAY_LEN (hex_quads); i++)
376      result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
377
378    return 1;
379  }
380}
381
382uword
383unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
384{
385  u32 *r = va_arg (*args, u32 *);
386
387  if (0);
388#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
389  foreach_ipsec_policy_action
390#undef _
391    else
392    return 0;
393  return 1;
394}
395
396u8 *
397format_ipsec_crypto_alg (u8 * s, va_list * args)
398{
399  u32 i = va_arg (*args, u32);
400  u8 *t = 0;
401
402  switch (i)
403    {
404#define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
405      foreach_ipsec_crypto_alg
406#undef _
407    default:
408      return format (s, "unknown");
409    }
410  return format (s, "%s", t);
411}
412
413u8 *
414format_ipsec_integ_alg (u8 * s, va_list * args)
415{
416  u32 i = va_arg (*args, u32);
417  u8 *t = 0;
418
419  switch (i)
420    {
421#define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
422      foreach_ipsec_integ_alg
423#undef _
424    default:
425      return format (s, "unknown");
426    }
427  return format (s, "%s", t);
428}
429
430#else /* VPP_API_TEST_BUILTIN == 1 */
431static uword
432api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
433{
434  vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
435  vnet_main_t *vnm = vnet_get_main ();
436  u32 *result = va_arg (*args, u32 *);
437
438  return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
439}
440
441static uword
442api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
443{
444  vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
445  vnet_main_t *vnm = vnet_get_main ();
446  u32 *result = va_arg (*args, u32 *);
447
448  return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
449}
450
451#endif /* VPP_API_TEST_BUILTIN */
452
453uword
454unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
455{
456  u32 *r = va_arg (*args, u32 *);
457
458  if (0);
459#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
460  foreach_ipsec_crypto_alg
461#undef _
462    else
463    return 0;
464  return 1;
465}
466
467uword
468unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
469{
470  u32 *r = va_arg (*args, u32 *);
471
472  if (0);
473#define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
474  foreach_ipsec_integ_alg
475#undef _
476    else
477    return 0;
478  return 1;
479}
480
481static uword
482unformat_policer_rate_type (unformat_input_t * input, va_list * args)
483{
484  u8 *r = va_arg (*args, u8 *);
485
486  if (unformat (input, "kbps"))
487    *r = SSE2_QOS_RATE_KBPS;
488  else if (unformat (input, "pps"))
489    *r = SSE2_QOS_RATE_PPS;
490  else
491    return 0;
492  return 1;
493}
494
495static uword
496unformat_policer_round_type (unformat_input_t * input, va_list * args)
497{
498  u8 *r = va_arg (*args, u8 *);
499
500  if (unformat (input, "closest"))
501    *r = SSE2_QOS_ROUND_TO_CLOSEST;
502  else if (unformat (input, "up"))
503    *r = SSE2_QOS_ROUND_TO_UP;
504  else if (unformat (input, "down"))
505    *r = SSE2_QOS_ROUND_TO_DOWN;
506  else
507    return 0;
508  return 1;
509}
510
511static uword
512unformat_policer_type (unformat_input_t * input, va_list * args)
513{
514  u8 *r = va_arg (*args, u8 *);
515
516  if (unformat (input, "1r2c"))
517    *r = SSE2_QOS_POLICER_TYPE_1R2C;
518  else if (unformat (input, "1r3c"))
519    *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
520  else if (unformat (input, "2r3c-2698"))
521    *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
522  else if (unformat (input, "2r3c-4115"))
523    *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
524  else if (unformat (input, "2r3c-mef5cf1"))
525    *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
526  else
527    return 0;
528  return 1;
529}
530
531static uword
532unformat_dscp (unformat_input_t * input, va_list * va)
533{
534  u8 *r = va_arg (*va, u8 *);
535
536  if (0);
537#define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
538  foreach_vnet_dscp
539#undef _
540    else
541    return 0;
542  return 1;
543}
544
545static uword
546unformat_policer_action_type (unformat_input_t * input, va_list * va)
547{
548  sse2_qos_pol_action_params_st *a
549    = va_arg (*va, sse2_qos_pol_action_params_st *);
550
551  if (unformat (input, "drop"))
552    a->action_type = SSE2_QOS_ACTION_DROP;
553  else if (unformat (input, "transmit"))
554    a->action_type = SSE2_QOS_ACTION_TRANSMIT;
555  else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
556    a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
557  else
558    return 0;
559  return 1;
560}
561
562static uword
563unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
564{
565  u32 *r = va_arg (*va, u32 *);
566  u32 tid;
567
568  if (unformat (input, "ip4"))
569    tid = POLICER_CLASSIFY_TABLE_IP4;
570  else if (unformat (input, "ip6"))
571    tid = POLICER_CLASSIFY_TABLE_IP6;
572  else if (unformat (input, "l2"))
573    tid = POLICER_CLASSIFY_TABLE_L2;
574  else
575    return 0;
576
577  *r = tid;
578  return 1;
579}
580
581static uword
582unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
583{
584  u32 *r = va_arg (*va, u32 *);
585  u32 tid;
586
587  if (unformat (input, "ip4"))
588    tid = FLOW_CLASSIFY_TABLE_IP4;
589  else if (unformat (input, "ip6"))
590    tid = FLOW_CLASSIFY_TABLE_IP6;
591  else
592    return 0;
593
594  *r = tid;
595  return 1;
596}
597
598#if (VPP_API_TEST_BUILTIN==0)
599
600static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
601static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
602static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
603static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
604
605uword
606unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
607{
608  mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
609  mfib_itf_attribute_t attr;
610
611  old = *iflags;
612  FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
613  {
614    if (unformat (input, mfib_itf_flag_long_names[attr]))
615      *iflags |= (1 << attr);
616  }
617  FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
618  {
619    if (unformat (input, mfib_itf_flag_names[attr]))
620      *iflags |= (1 << attr);
621  }
622
623  return (old == *iflags ? 0 : 1);
624}
625
626uword
627unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
628{
629  mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
630  mfib_entry_attribute_t attr;
631
632  old = *eflags;
633  FOR_EACH_MFIB_ATTRIBUTE (attr)
634  {
635    if (unformat (input, mfib_flag_long_names[attr]))
636      *eflags |= (1 << attr);
637  }
638  FOR_EACH_MFIB_ATTRIBUTE (attr)
639  {
640    if (unformat (input, mfib_flag_names[attr]))
641      *eflags |= (1 << attr);
642  }
643
644  return (old == *eflags ? 0 : 1);
645}
646
647u8 *
648format_ip4_address (u8 * s, va_list * args)
649{
650  u8 *a = va_arg (*args, u8 *);
651  return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
652}
653
654u8 *
655format_ip6_address (u8 * s, va_list * args)
656{
657  ip6_address_t *a = va_arg (*args, ip6_address_t *);
658  u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
659
660  i_max_n_zero = ARRAY_LEN (a->as_u16);
661  max_n_zeros = 0;
662  i_first_zero = i_max_n_zero;
663  n_zeros = 0;
664  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
665    {
666      u32 is_zero = a->as_u16[i] == 0;
667      if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
668	{
669	  i_first_zero = i;
670	  n_zeros = 0;
671	}
672      n_zeros += is_zero;
673      if ((!is_zero && n_zeros > max_n_zeros)
674	  || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
675	{
676	  i_max_n_zero = i_first_zero;
677	  max_n_zeros = n_zeros;
678	  i_first_zero = ARRAY_LEN (a->as_u16);
679	  n_zeros = 0;
680	}
681    }
682
683  last_double_colon = 0;
684  for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
685    {
686      if (i == i_max_n_zero && max_n_zeros > 1)
687	{
688	  s = format (s, "::");
689	  i += max_n_zeros - 1;
690	  last_double_colon = 1;
691	}
692      else
693	{
694	  s = format (s, "%s%x",
695		      (last_double_colon || i == 0) ? "" : ":",
696		      clib_net_to_host_u16 (a->as_u16[i]));
697	  last_double_colon = 0;
698	}
699    }
700
701  return s;
702}
703
704/* Format an IP46 address. */
705u8 *
706format_ip46_address (u8 * s, va_list * args)
707{
708  ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
709  ip46_type_t type = va_arg (*args, ip46_type_t);
710  int is_ip4 = 1;
711
712  switch (type)
713    {
714    case IP46_TYPE_ANY:
715      is_ip4 = ip46_address_is_ip4 (ip46);
716      break;
717    case IP46_TYPE_IP4:
718      is_ip4 = 1;
719      break;
720    case IP46_TYPE_IP6:
721      is_ip4 = 0;
722      break;
723    }
724
725  return is_ip4 ?
726    format (s, "%U", format_ip4_address, &ip46->ip4) :
727    format (s, "%U", format_ip6_address, &ip46->ip6);
728}
729
730u8 *
731format_ethernet_address (u8 * s, va_list * args)
732{
733  u8 *a = va_arg (*args, u8 *);
734
735  return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
736		 a[0], a[1], a[2], a[3], a[4], a[5]);
737}
738#endif
739
740static void
741increment_v4_address (vl_api_ip4_address_t * i)
742{
743  ip4_address_t *a = (ip4_address_t *) i;
744  u32 v;
745
746  v = ntohl (a->as_u32) + 1;
747  a->as_u32 = ntohl (v);
748}
749
750static void
751increment_v6_address (vl_api_ip6_address_t * i)
752{
753  ip6_address_t *a = (ip6_address_t *) i;
754  u64 v0, v1;
755
756  v0 = clib_net_to_host_u64 (a->as_u64[0]);
757  v1 = clib_net_to_host_u64 (a->as_u64[1]);
758
759  v1 += 1;
760  if (v1 == 0)
761    v0 += 1;
762  a->as_u64[0] = clib_net_to_host_u64 (v0);
763  a->as_u64[1] = clib_net_to_host_u64 (v1);
764}
765
766static void
767increment_address (vl_api_address_t * a)
768{
769  if (a->af == ADDRESS_IP4)
770    increment_v4_address (&a->un.ip4);
771  else if (a->af == ADDRESS_IP6)
772    increment_v6_address (&a->un.ip6);
773}
774
775static void
776set_ip4_address (vl_api_address_t * a, u32 v)
777{
778  if (a->af == ADDRESS_IP4)
779    {
780      ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
781      i->as_u32 = v;
782    }
783}
784
785void
786ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
787{
788  if (is_ip4)
789    dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
790  else
791    clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
792		      sizeof (ip6_address_t));
793}
794
795static void
796increment_mac_address (u8 * mac)
797{
798  u64 tmp = *((u64 *) mac);
799  tmp = clib_net_to_host_u64 (tmp);
800  tmp += 1 << 16;		/* skip unused (least significant) octets */
801  tmp = clib_host_to_net_u64 (tmp);
802
803  clib_memcpy (mac, &tmp, 6);
804}
805
806static void
807vat_json_object_add_address (vat_json_node_t * node,
808			     const char *str, const vl_api_address_t * addr)
809{
810  if (ADDRESS_IP6 == addr->af)
811    {
812      struct in6_addr ip6;
813
814      clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
815      vat_json_object_add_ip6 (node, str, ip6);
816    }
817  else
818    {
819      struct in_addr ip4;
820
821      clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
822      vat_json_object_add_ip4 (node, str, ip4);
823    }
824}
825
826static void
827vat_json_object_add_prefix (vat_json_node_t * node,
828			    const vl_api_prefix_t * prefix)
829{
830  vat_json_object_add_uint (node, "len", prefix->len);
831  vat_json_object_add_address (node, "address", &prefix->address);
832}
833
834static void vl_api_create_loopback_reply_t_handler
835  (vl_api_create_loopback_reply_t * mp)
836{
837  vat_main_t *vam = &vat_main;
838  i32 retval = ntohl (mp->retval);
839
840  vam->retval = retval;
841  vam->regenerate_interface_table = 1;
842  vam->sw_if_index = ntohl (mp->sw_if_index);
843  vam->result_ready = 1;
844}
845
846static void vl_api_create_loopback_reply_t_handler_json
847  (vl_api_create_loopback_reply_t * mp)
848{
849  vat_main_t *vam = &vat_main;
850  vat_json_node_t node;
851
852  vat_json_init_object (&node);
853  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
854  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
855
856  vat_json_print (vam->ofp, &node);
857  vat_json_free (&node);
858  vam->retval = ntohl (mp->retval);
859  vam->result_ready = 1;
860}
861
862static void vl_api_create_loopback_instance_reply_t_handler
863  (vl_api_create_loopback_instance_reply_t * mp)
864{
865  vat_main_t *vam = &vat_main;
866  i32 retval = ntohl (mp->retval);
867
868  vam->retval = retval;
869  vam->regenerate_interface_table = 1;
870  vam->sw_if_index = ntohl (mp->sw_if_index);
871  vam->result_ready = 1;
872}
873
874static void vl_api_create_loopback_instance_reply_t_handler_json
875  (vl_api_create_loopback_instance_reply_t * mp)
876{
877  vat_main_t *vam = &vat_main;
878  vat_json_node_t node;
879
880  vat_json_init_object (&node);
881  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
882  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
883
884  vat_json_print (vam->ofp, &node);
885  vat_json_free (&node);
886  vam->retval = ntohl (mp->retval);
887  vam->result_ready = 1;
888}
889
890static void vl_api_af_packet_create_reply_t_handler
891  (vl_api_af_packet_create_reply_t * mp)
892{
893  vat_main_t *vam = &vat_main;
894  i32 retval = ntohl (mp->retval);
895
896  vam->retval = retval;
897  vam->regenerate_interface_table = 1;
898  vam->sw_if_index = ntohl (mp->sw_if_index);
899  vam->result_ready = 1;
900}
901
902static void vl_api_af_packet_create_reply_t_handler_json
903  (vl_api_af_packet_create_reply_t * mp)
904{
905  vat_main_t *vam = &vat_main;
906  vat_json_node_t node;
907
908  vat_json_init_object (&node);
909  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
910  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
911
912  vat_json_print (vam->ofp, &node);
913  vat_json_free (&node);
914
915  vam->retval = ntohl (mp->retval);
916  vam->result_ready = 1;
917}
918
919static void vl_api_create_vlan_subif_reply_t_handler
920  (vl_api_create_vlan_subif_reply_t * mp)
921{
922  vat_main_t *vam = &vat_main;
923  i32 retval = ntohl (mp->retval);
924
925  vam->retval = retval;
926  vam->regenerate_interface_table = 1;
927  vam->sw_if_index = ntohl (mp->sw_if_index);
928  vam->result_ready = 1;
929}
930
931static void vl_api_create_vlan_subif_reply_t_handler_json
932  (vl_api_create_vlan_subif_reply_t * mp)
933{
934  vat_main_t *vam = &vat_main;
935  vat_json_node_t node;
936
937  vat_json_init_object (&node);
938  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
939  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
940
941  vat_json_print (vam->ofp, &node);
942  vat_json_free (&node);
943
944  vam->retval = ntohl (mp->retval);
945  vam->result_ready = 1;
946}
947
948static void vl_api_create_subif_reply_t_handler
949  (vl_api_create_subif_reply_t * mp)
950{
951  vat_main_t *vam = &vat_main;
952  i32 retval = ntohl (mp->retval);
953
954  vam->retval = retval;
955  vam->regenerate_interface_table = 1;
956  vam->sw_if_index = ntohl (mp->sw_if_index);
957  vam->result_ready = 1;
958}
959
960static void vl_api_create_subif_reply_t_handler_json
961  (vl_api_create_subif_reply_t * mp)
962{
963  vat_main_t *vam = &vat_main;
964  vat_json_node_t node;
965
966  vat_json_init_object (&node);
967  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
968  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
969
970  vat_json_print (vam->ofp, &node);
971  vat_json_free (&node);
972
973  vam->retval = ntohl (mp->retval);
974  vam->result_ready = 1;
975}
976
977static void vl_api_interface_name_renumber_reply_t_handler
978  (vl_api_interface_name_renumber_reply_t * mp)
979{
980  vat_main_t *vam = &vat_main;
981  i32 retval = ntohl (mp->retval);
982
983  vam->retval = retval;
984  vam->regenerate_interface_table = 1;
985  vam->result_ready = 1;
986}
987
988static void vl_api_interface_name_renumber_reply_t_handler_json
989  (vl_api_interface_name_renumber_reply_t * mp)
990{
991  vat_main_t *vam = &vat_main;
992  vat_json_node_t node;
993
994  vat_json_init_object (&node);
995  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
996
997  vat_json_print (vam->ofp, &node);
998  vat_json_free (&node);
999
1000  vam->retval = ntohl (mp->retval);
1001  vam->result_ready = 1;
1002}
1003
1004/*
1005 * Special-case: build the interface table, maintain
1006 * the next loopback sw_if_index vbl.
1007 */
1008static void vl_api_sw_interface_details_t_handler
1009  (vl_api_sw_interface_details_t * mp)
1010{
1011  vat_main_t *vam = &vat_main;
1012  u8 *s = format (0, "%s%c", mp->interface_name, 0);
1013
1014  hash_set_mem (vam->sw_if_index_by_interface_name, s,
1015		ntohl (mp->sw_if_index));
1016
1017  /* In sub interface case, fill the sub interface table entry */
1018  if (mp->sw_if_index != mp->sup_sw_if_index)
1019    {
1020      sw_interface_subif_t *sub = NULL;
1021
1022      vec_add2 (vam->sw_if_subif_table, sub, 1);
1023
1024      vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1025      strncpy ((char *) sub->interface_name, (char *) s,
1026	       vec_len (sub->interface_name));
1027      sub->sw_if_index = ntohl (mp->sw_if_index);
1028      sub->sub_id = ntohl (mp->sub_id);
1029
1030      sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1031
1032      sub->sub_number_of_tags = mp->sub_number_of_tags;
1033      sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1034      sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1035
1036      /* vlan tag rewrite */
1037      sub->vtr_op = ntohl (mp->vtr_op);
1038      sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1039      sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1040      sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1041    }
1042}
1043
1044static void vl_api_sw_interface_details_t_handler_json
1045  (vl_api_sw_interface_details_t * mp)
1046{
1047  vat_main_t *vam = &vat_main;
1048  vat_json_node_t *node = NULL;
1049
1050  if (VAT_JSON_ARRAY != vam->json_tree.type)
1051    {
1052      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1053      vat_json_init_array (&vam->json_tree);
1054    }
1055  node = vat_json_array_add (&vam->json_tree);
1056
1057  vat_json_init_object (node);
1058  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1059  vat_json_object_add_uint (node, "sup_sw_if_index",
1060			    ntohl (mp->sup_sw_if_index));
1061  vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1062			     sizeof (mp->l2_address));
1063  vat_json_object_add_string_copy (node, "interface_name",
1064				   mp->interface_name);
1065  vat_json_object_add_string_copy (node, "interface_dev_type",
1066				   mp->interface_dev_type);
1067  vat_json_object_add_uint (node, "flags", mp->flags);
1068  vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1069  vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1070  vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1071  vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1072  vat_json_object_add_uint (node, "sub_number_of_tags",
1073			    mp->sub_number_of_tags);
1074  vat_json_object_add_uint (node, "sub_outer_vlan_id",
1075			    ntohs (mp->sub_outer_vlan_id));
1076  vat_json_object_add_uint (node, "sub_inner_vlan_id",
1077			    ntohs (mp->sub_inner_vlan_id));
1078  vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1079  vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1080  vat_json_object_add_uint (node, "vtr_push_dot1q",
1081			    ntohl (mp->vtr_push_dot1q));
1082  vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1083  vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1084  if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1085    {
1086      vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1087				       format (0, "%U",
1088					       format_ethernet_address,
1089					       &mp->b_dmac));
1090      vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1091				       format (0, "%U",
1092					       format_ethernet_address,
1093					       &mp->b_smac));
1094      vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1095      vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1096    }
1097}
1098
1099#if VPP_API_TEST_BUILTIN == 0
1100static void vl_api_sw_interface_event_t_handler
1101  (vl_api_sw_interface_event_t * mp)
1102{
1103  vat_main_t *vam = &vat_main;
1104  if (vam->interface_event_display)
1105    errmsg ("interface flags: sw_if_index %d %s %s",
1106	    ntohl (mp->sw_if_index),
1107	    ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1108	    "admin-up" : "admin-down",
1109	    ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1110	    "link-up" : "link-down");
1111}
1112#endif
1113
1114__clib_unused static void
1115vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1116{
1117  /* JSON output not supported */
1118}
1119
1120static void
1121vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1122{
1123  vat_main_t *vam = &vat_main;
1124  i32 retval = ntohl (mp->retval);
1125
1126  vam->retval = retval;
1127  vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1128  vam->result_ready = 1;
1129}
1130
1131static void
1132vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1133{
1134  vat_main_t *vam = &vat_main;
1135  vat_json_node_t node;
1136  void *oldheap;
1137  u8 *reply;
1138
1139  vat_json_init_object (&node);
1140  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1141  vat_json_object_add_uint (&node, "reply_in_shmem",
1142			    ntohl (mp->reply_in_shmem));
1143  /* Toss the shared-memory original... */
1144  oldheap = vl_msg_push_heap ();
1145
1146  reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1147  vec_free (reply);
1148
1149  vl_msg_pop_heap (oldheap);
1150
1151  vat_json_print (vam->ofp, &node);
1152  vat_json_free (&node);
1153
1154  vam->retval = ntohl (mp->retval);
1155  vam->result_ready = 1;
1156}
1157
1158static void
1159vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1160{
1161  vat_main_t *vam = &vat_main;
1162  i32 retval = ntohl (mp->retval);
1163
1164  vec_reset_length (vam->cmd_reply);
1165
1166  vam->retval = retval;
1167  if (retval == 0)
1168    vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1169  vam->result_ready = 1;
1170}
1171
1172static void
1173vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1174{
1175  vat_main_t *vam = &vat_main;
1176  vat_json_node_t node;
1177  u8 *reply = 0;		/* reply vector */
1178
1179  reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1180  vec_reset_length (vam->cmd_reply);
1181
1182  vat_json_init_object (&node);
1183  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1184  vat_json_object_add_string_copy (&node, "reply", reply);
1185
1186  vat_json_print (vam->ofp, &node);
1187  vat_json_free (&node);
1188  vec_free (reply);
1189
1190  vam->retval = ntohl (mp->retval);
1191  vam->result_ready = 1;
1192}
1193
1194static void vl_api_classify_add_del_table_reply_t_handler
1195  (vl_api_classify_add_del_table_reply_t * mp)
1196{
1197  vat_main_t *vam = &vat_main;
1198  i32 retval = ntohl (mp->retval);
1199  if (vam->async_mode)
1200    {
1201      vam->async_errors += (retval < 0);
1202    }
1203  else
1204    {
1205      vam->retval = retval;
1206      if (retval == 0 &&
1207	  ((mp->new_table_index != 0xFFFFFFFF) ||
1208	   (mp->skip_n_vectors != 0xFFFFFFFF) ||
1209	   (mp->match_n_vectors != 0xFFFFFFFF)))
1210	/*
1211	 * Note: this is just barely thread-safe, depends on
1212	 * the main thread spinning waiting for an answer...
1213	 */
1214	errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1215		ntohl (mp->new_table_index),
1216		ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1217      vam->result_ready = 1;
1218    }
1219}
1220
1221static void vl_api_classify_add_del_table_reply_t_handler_json
1222  (vl_api_classify_add_del_table_reply_t * mp)
1223{
1224  vat_main_t *vam = &vat_main;
1225  vat_json_node_t node;
1226
1227  vat_json_init_object (&node);
1228  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1229  vat_json_object_add_uint (&node, "new_table_index",
1230			    ntohl (mp->new_table_index));
1231  vat_json_object_add_uint (&node, "skip_n_vectors",
1232			    ntohl (mp->skip_n_vectors));
1233  vat_json_object_add_uint (&node, "match_n_vectors",
1234			    ntohl (mp->match_n_vectors));
1235
1236  vat_json_print (vam->ofp, &node);
1237  vat_json_free (&node);
1238
1239  vam->retval = ntohl (mp->retval);
1240  vam->result_ready = 1;
1241}
1242
1243static void vl_api_get_node_index_reply_t_handler
1244  (vl_api_get_node_index_reply_t * mp)
1245{
1246  vat_main_t *vam = &vat_main;
1247  i32 retval = ntohl (mp->retval);
1248  if (vam->async_mode)
1249    {
1250      vam->async_errors += (retval < 0);
1251    }
1252  else
1253    {
1254      vam->retval = retval;
1255      if (retval == 0)
1256	errmsg ("node index %d", ntohl (mp->node_index));
1257      vam->result_ready = 1;
1258    }
1259}
1260
1261static void vl_api_get_node_index_reply_t_handler_json
1262  (vl_api_get_node_index_reply_t * mp)
1263{
1264  vat_main_t *vam = &vat_main;
1265  vat_json_node_t node;
1266
1267  vat_json_init_object (&node);
1268  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1269  vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1270
1271  vat_json_print (vam->ofp, &node);
1272  vat_json_free (&node);
1273
1274  vam->retval = ntohl (mp->retval);
1275  vam->result_ready = 1;
1276}
1277
1278static void vl_api_get_next_index_reply_t_handler
1279  (vl_api_get_next_index_reply_t * mp)
1280{
1281  vat_main_t *vam = &vat_main;
1282  i32 retval = ntohl (mp->retval);
1283  if (vam->async_mode)
1284    {
1285      vam->async_errors += (retval < 0);
1286    }
1287  else
1288    {
1289      vam->retval = retval;
1290      if (retval == 0)
1291	errmsg ("next node index %d", ntohl (mp->next_index));
1292      vam->result_ready = 1;
1293    }
1294}
1295
1296static void vl_api_get_next_index_reply_t_handler_json
1297  (vl_api_get_next_index_reply_t * mp)
1298{
1299  vat_main_t *vam = &vat_main;
1300  vat_json_node_t node;
1301
1302  vat_json_init_object (&node);
1303  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1304  vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1305
1306  vat_json_print (vam->ofp, &node);
1307  vat_json_free (&node);
1308
1309  vam->retval = ntohl (mp->retval);
1310  vam->result_ready = 1;
1311}
1312
1313static void vl_api_add_node_next_reply_t_handler
1314  (vl_api_add_node_next_reply_t * mp)
1315{
1316  vat_main_t *vam = &vat_main;
1317  i32 retval = ntohl (mp->retval);
1318  if (vam->async_mode)
1319    {
1320      vam->async_errors += (retval < 0);
1321    }
1322  else
1323    {
1324      vam->retval = retval;
1325      if (retval == 0)
1326	errmsg ("next index %d", ntohl (mp->next_index));
1327      vam->result_ready = 1;
1328    }
1329}
1330
1331static void vl_api_add_node_next_reply_t_handler_json
1332  (vl_api_add_node_next_reply_t * mp)
1333{
1334  vat_main_t *vam = &vat_main;
1335  vat_json_node_t node;
1336
1337  vat_json_init_object (&node);
1338  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1339  vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1340
1341  vat_json_print (vam->ofp, &node);
1342  vat_json_free (&node);
1343
1344  vam->retval = ntohl (mp->retval);
1345  vam->result_ready = 1;
1346}
1347
1348static void vl_api_show_version_reply_t_handler
1349  (vl_api_show_version_reply_t * mp)
1350{
1351  vat_main_t *vam = &vat_main;
1352  i32 retval = ntohl (mp->retval);
1353
1354  if (retval >= 0)
1355    {
1356      errmsg ("        program: %s", mp->program);
1357      errmsg ("        version: %s", mp->version);
1358      errmsg ("     build date: %s", mp->build_date);
1359      errmsg ("build directory: %s", mp->build_directory);
1360    }
1361  vam->retval = retval;
1362  vam->result_ready = 1;
1363}
1364
1365static void vl_api_show_version_reply_t_handler_json
1366  (vl_api_show_version_reply_t * mp)
1367{
1368  vat_main_t *vam = &vat_main;
1369  vat_json_node_t node;
1370
1371  vat_json_init_object (&node);
1372  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1373  vat_json_object_add_string_copy (&node, "program", mp->program);
1374  vat_json_object_add_string_copy (&node, "version", mp->version);
1375  vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1376  vat_json_object_add_string_copy (&node, "build_directory",
1377				   mp->build_directory);
1378
1379  vat_json_print (vam->ofp, &node);
1380  vat_json_free (&node);
1381
1382  vam->retval = ntohl (mp->retval);
1383  vam->result_ready = 1;
1384}
1385
1386static void vl_api_show_threads_reply_t_handler
1387  (vl_api_show_threads_reply_t * mp)
1388{
1389  vat_main_t *vam = &vat_main;
1390  i32 retval = ntohl (mp->retval);
1391  int i, count = 0;
1392
1393  if (retval >= 0)
1394    count = ntohl (mp->count);
1395
1396  for (i = 0; i < count; i++)
1397    print (vam->ofp,
1398	   "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1399	   ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1400	   mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1401	   ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1402	   ntohl (mp->thread_data[i].cpu_socket));
1403
1404  vam->retval = retval;
1405  vam->result_ready = 1;
1406}
1407
1408static void vl_api_show_threads_reply_t_handler_json
1409  (vl_api_show_threads_reply_t * mp)
1410{
1411  vat_main_t *vam = &vat_main;
1412  vat_json_node_t node;
1413  vl_api_thread_data_t *td;
1414  i32 retval = ntohl (mp->retval);
1415  int i, count = 0;
1416
1417  if (retval >= 0)
1418    count = ntohl (mp->count);
1419
1420  vat_json_init_object (&node);
1421  vat_json_object_add_int (&node, "retval", retval);
1422  vat_json_object_add_uint (&node, "count", count);
1423
1424  for (i = 0; i < count; i++)
1425    {
1426      td = &mp->thread_data[i];
1427      vat_json_object_add_uint (&node, "id", ntohl (td->id));
1428      vat_json_object_add_string_copy (&node, "name", td->name);
1429      vat_json_object_add_string_copy (&node, "type", td->type);
1430      vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1431      vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1432      vat_json_object_add_int (&node, "core", ntohl (td->id));
1433      vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1434    }
1435
1436  vat_json_print (vam->ofp, &node);
1437  vat_json_free (&node);
1438
1439  vam->retval = retval;
1440  vam->result_ready = 1;
1441}
1442
1443static int
1444api_show_threads (vat_main_t * vam)
1445{
1446  vl_api_show_threads_t *mp;
1447  int ret;
1448
1449  print (vam->ofp,
1450	 "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1451	 "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1452
1453  M (SHOW_THREADS, mp);
1454
1455  S (mp);
1456  W (ret);
1457  return ret;
1458}
1459
1460static void
1461vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1462{
1463  u32 n_macs = ntohl (mp->n_macs);
1464  errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1465	  ntohl (mp->pid), mp->client_index, n_macs);
1466  int i;
1467  for (i = 0; i < n_macs; i++)
1468    {
1469      vl_api_mac_entry_t *mac = &mp->mac[i];
1470      errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1471	      i + 1, ntohl (mac->sw_if_index),
1472	      format_ethernet_address, mac->mac_addr, mac->action);
1473      if (i == 1000)
1474	break;
1475    }
1476}
1477
1478static void
1479vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1480{
1481  /* JSON output not supported */
1482}
1483
1484#define vl_api_bridge_domain_details_t_endian vl_noop_handler
1485#define vl_api_bridge_domain_details_t_print vl_noop_handler
1486
1487/*
1488 * Special-case: build the bridge domain table, maintain
1489 * the next bd id vbl.
1490 */
1491static void vl_api_bridge_domain_details_t_handler
1492  (vl_api_bridge_domain_details_t * mp)
1493{
1494  vat_main_t *vam = &vat_main;
1495  u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1496  int i;
1497
1498  print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1499	 " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1500
1501  print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1502	 ntohl (mp->bd_id), mp->learn, mp->forward,
1503	 mp->flood, ntohl (mp->bvi_sw_if_index),
1504	 ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1505
1506  if (n_sw_ifs)
1507    {
1508      vl_api_bridge_domain_sw_if_t *sw_ifs;
1509      print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1510	     "Interface Name");
1511
1512      sw_ifs = mp->sw_if_details;
1513      for (i = 0; i < n_sw_ifs; i++)
1514	{
1515	  u8 *sw_if_name = 0;
1516	  u32 sw_if_index;
1517	  hash_pair_t *p;
1518
1519	  sw_if_index = ntohl (sw_ifs->sw_if_index);
1520
1521	  /* *INDENT-OFF* */
1522	  hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1523			     ({
1524			       if ((u32) p->value[0] == sw_if_index)
1525				 {
1526				   sw_if_name = (u8 *)(p->key);
1527				   break;
1528				 }
1529			     }));
1530	  /* *INDENT-ON* */
1531	  print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1532		 sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1533		 "sw_if_index not found!");
1534
1535	  sw_ifs++;
1536	}
1537    }
1538}
1539
1540static void vl_api_bridge_domain_details_t_handler_json
1541  (vl_api_bridge_domain_details_t * mp)
1542{
1543  vat_main_t *vam = &vat_main;
1544  vat_json_node_t *node, *array = NULL;
1545  u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1546
1547  if (VAT_JSON_ARRAY != vam->json_tree.type)
1548    {
1549      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1550      vat_json_init_array (&vam->json_tree);
1551    }
1552  node = vat_json_array_add (&vam->json_tree);
1553
1554  vat_json_init_object (node);
1555  vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1556  vat_json_object_add_uint (node, "flood", mp->flood);
1557  vat_json_object_add_uint (node, "forward", mp->forward);
1558  vat_json_object_add_uint (node, "learn", mp->learn);
1559  vat_json_object_add_uint (node, "bvi_sw_if_index",
1560			    ntohl (mp->bvi_sw_if_index));
1561  vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1562  array = vat_json_object_add (node, "sw_if");
1563  vat_json_init_array (array);
1564
1565
1566
1567  if (n_sw_ifs)
1568    {
1569      vl_api_bridge_domain_sw_if_t *sw_ifs;
1570      int i;
1571
1572      sw_ifs = mp->sw_if_details;
1573      for (i = 0; i < n_sw_ifs; i++)
1574	{
1575	  node = vat_json_array_add (array);
1576	  vat_json_init_object (node);
1577	  vat_json_object_add_uint (node, "sw_if_index",
1578				    ntohl (sw_ifs->sw_if_index));
1579	  vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1580	  sw_ifs++;
1581	}
1582    }
1583}
1584
1585static void vl_api_control_ping_reply_t_handler
1586  (vl_api_control_ping_reply_t * mp)
1587{
1588  vat_main_t *vam = &vat_main;
1589  i32 retval = ntohl (mp->retval);
1590  if (vam->async_mode)
1591    {
1592      vam->async_errors += (retval < 0);
1593    }
1594  else
1595    {
1596      vam->retval = retval;
1597      vam->result_ready = 1;
1598    }
1599  if (vam->socket_client_main)
1600    vam->socket_client_main->control_pings_outstanding--;
1601}
1602
1603static void vl_api_control_ping_reply_t_handler_json
1604  (vl_api_control_ping_reply_t * mp)
1605{
1606  vat_main_t *vam = &vat_main;
1607  i32 retval = ntohl (mp->retval);
1608
1609  if (VAT_JSON_NONE != vam->json_tree.type)
1610    {
1611      vat_json_print (vam->ofp, &vam->json_tree);
1612      vat_json_free (&vam->json_tree);
1613      vam->json_tree.type = VAT_JSON_NONE;
1614    }
1615  else
1616    {
1617      /* just print [] */
1618      vat_json_init_array (&vam->json_tree);
1619      vat_json_print (vam->ofp, &vam->json_tree);
1620      vam->json_tree.type = VAT_JSON_NONE;
1621    }
1622
1623  vam->retval = retval;
1624  vam->result_ready = 1;
1625}
1626
1627static void
1628  vl_api_bridge_domain_set_mac_age_reply_t_handler
1629  (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1630{
1631  vat_main_t *vam = &vat_main;
1632  i32 retval = ntohl (mp->retval);
1633  if (vam->async_mode)
1634    {
1635      vam->async_errors += (retval < 0);
1636    }
1637  else
1638    {
1639      vam->retval = retval;
1640      vam->result_ready = 1;
1641    }
1642}
1643
1644static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1645  (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1646{
1647  vat_main_t *vam = &vat_main;
1648  vat_json_node_t node;
1649
1650  vat_json_init_object (&node);
1651  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1652
1653  vat_json_print (vam->ofp, &node);
1654  vat_json_free (&node);
1655
1656  vam->retval = ntohl (mp->retval);
1657  vam->result_ready = 1;
1658}
1659
1660static void
1661vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1662{
1663  vat_main_t *vam = &vat_main;
1664  i32 retval = ntohl (mp->retval);
1665  if (vam->async_mode)
1666    {
1667      vam->async_errors += (retval < 0);
1668    }
1669  else
1670    {
1671      vam->retval = retval;
1672      vam->result_ready = 1;
1673    }
1674}
1675
1676static void vl_api_l2_flags_reply_t_handler_json
1677  (vl_api_l2_flags_reply_t * mp)
1678{
1679  vat_main_t *vam = &vat_main;
1680  vat_json_node_t node;
1681
1682  vat_json_init_object (&node);
1683  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684  vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1685			    ntohl (mp->resulting_feature_bitmap));
1686
1687  vat_json_print (vam->ofp, &node);
1688  vat_json_free (&node);
1689
1690  vam->retval = ntohl (mp->retval);
1691  vam->result_ready = 1;
1692}
1693
1694static void vl_api_bridge_flags_reply_t_handler
1695  (vl_api_bridge_flags_reply_t * mp)
1696{
1697  vat_main_t *vam = &vat_main;
1698  i32 retval = ntohl (mp->retval);
1699  if (vam->async_mode)
1700    {
1701      vam->async_errors += (retval < 0);
1702    }
1703  else
1704    {
1705      vam->retval = retval;
1706      vam->result_ready = 1;
1707    }
1708}
1709
1710static void vl_api_bridge_flags_reply_t_handler_json
1711  (vl_api_bridge_flags_reply_t * mp)
1712{
1713  vat_main_t *vam = &vat_main;
1714  vat_json_node_t node;
1715
1716  vat_json_init_object (&node);
1717  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718  vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1719			    ntohl (mp->resulting_feature_bitmap));
1720
1721  vat_json_print (vam->ofp, &node);
1722  vat_json_free (&node);
1723
1724  vam->retval = ntohl (mp->retval);
1725  vam->result_ready = 1;
1726}
1727
1728static void
1729vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1730{
1731  vat_main_t *vam = &vat_main;
1732  i32 retval = ntohl (mp->retval);
1733  if (vam->async_mode)
1734    {
1735      vam->async_errors += (retval < 0);
1736    }
1737  else
1738    {
1739      vam->retval = retval;
1740      vam->sw_if_index = ntohl (mp->sw_if_index);
1741      vam->result_ready = 1;
1742    }
1743
1744}
1745
1746static void vl_api_tap_create_v2_reply_t_handler_json
1747  (vl_api_tap_create_v2_reply_t * mp)
1748{
1749  vat_main_t *vam = &vat_main;
1750  vat_json_node_t node;
1751
1752  vat_json_init_object (&node);
1753  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1754  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1755
1756  vat_json_print (vam->ofp, &node);
1757  vat_json_free (&node);
1758
1759  vam->retval = ntohl (mp->retval);
1760  vam->result_ready = 1;
1761
1762}
1763
1764static void
1765vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1766{
1767  vat_main_t *vam = &vat_main;
1768  i32 retval = ntohl (mp->retval);
1769  if (vam->async_mode)
1770    {
1771      vam->async_errors += (retval < 0);
1772    }
1773  else
1774    {
1775      vam->retval = retval;
1776      vam->result_ready = 1;
1777    }
1778}
1779
1780static void vl_api_tap_delete_v2_reply_t_handler_json
1781  (vl_api_tap_delete_v2_reply_t * mp)
1782{
1783  vat_main_t *vam = &vat_main;
1784  vat_json_node_t node;
1785
1786  vat_json_init_object (&node);
1787  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788
1789  vat_json_print (vam->ofp, &node);
1790  vat_json_free (&node);
1791
1792  vam->retval = ntohl (mp->retval);
1793  vam->result_ready = 1;
1794}
1795
1796static void
1797vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1798					  mp)
1799{
1800  vat_main_t *vam = &vat_main;
1801  i32 retval = ntohl (mp->retval);
1802  if (vam->async_mode)
1803    {
1804      vam->async_errors += (retval < 0);
1805    }
1806  else
1807    {
1808      vam->retval = retval;
1809      vam->sw_if_index = ntohl (mp->sw_if_index);
1810      vam->result_ready = 1;
1811    }
1812}
1813
1814static void vl_api_virtio_pci_create_reply_t_handler_json
1815  (vl_api_virtio_pci_create_reply_t * mp)
1816{
1817  vat_main_t *vam = &vat_main;
1818  vat_json_node_t node;
1819
1820  vat_json_init_object (&node);
1821  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1822  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1823
1824  vat_json_print (vam->ofp, &node);
1825  vat_json_free (&node);
1826
1827  vam->retval = ntohl (mp->retval);
1828  vam->result_ready = 1;
1829
1830}
1831
1832static void
1833vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1834					  mp)
1835{
1836  vat_main_t *vam = &vat_main;
1837  i32 retval = ntohl (mp->retval);
1838  if (vam->async_mode)
1839    {
1840      vam->async_errors += (retval < 0);
1841    }
1842  else
1843    {
1844      vam->retval = retval;
1845      vam->result_ready = 1;
1846    }
1847}
1848
1849static void vl_api_virtio_pci_delete_reply_t_handler_json
1850  (vl_api_virtio_pci_delete_reply_t * mp)
1851{
1852  vat_main_t *vam = &vat_main;
1853  vat_json_node_t node;
1854
1855  vat_json_init_object (&node);
1856  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1857
1858  vat_json_print (vam->ofp, &node);
1859  vat_json_free (&node);
1860
1861  vam->retval = ntohl (mp->retval);
1862  vam->result_ready = 1;
1863}
1864
1865static void
1866vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1867{
1868  vat_main_t *vam = &vat_main;
1869  i32 retval = ntohl (mp->retval);
1870
1871  if (vam->async_mode)
1872    {
1873      vam->async_errors += (retval < 0);
1874    }
1875  else
1876    {
1877      vam->retval = retval;
1878      vam->sw_if_index = ntohl (mp->sw_if_index);
1879      vam->result_ready = 1;
1880    }
1881}
1882
1883static void vl_api_bond_create_reply_t_handler_json
1884  (vl_api_bond_create_reply_t * mp)
1885{
1886  vat_main_t *vam = &vat_main;
1887  vat_json_node_t node;
1888
1889  vat_json_init_object (&node);
1890  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1891  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1892
1893  vat_json_print (vam->ofp, &node);
1894  vat_json_free (&node);
1895
1896  vam->retval = ntohl (mp->retval);
1897  vam->result_ready = 1;
1898}
1899
1900static void
1901vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1902{
1903  vat_main_t *vam = &vat_main;
1904  i32 retval = ntohl (mp->retval);
1905
1906  if (vam->async_mode)
1907    {
1908      vam->async_errors += (retval < 0);
1909    }
1910  else
1911    {
1912      vam->retval = retval;
1913      vam->result_ready = 1;
1914    }
1915}
1916
1917static void vl_api_bond_delete_reply_t_handler_json
1918  (vl_api_bond_delete_reply_t * mp)
1919{
1920  vat_main_t *vam = &vat_main;
1921  vat_json_node_t node;
1922
1923  vat_json_init_object (&node);
1924  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1925
1926  vat_json_print (vam->ofp, &node);
1927  vat_json_free (&node);
1928
1929  vam->retval = ntohl (mp->retval);
1930  vam->result_ready = 1;
1931}
1932
1933static void
1934vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1935{
1936  vat_main_t *vam = &vat_main;
1937  i32 retval = ntohl (mp->retval);
1938
1939  if (vam->async_mode)
1940    {
1941      vam->async_errors += (retval < 0);
1942    }
1943  else
1944    {
1945      vam->retval = retval;
1946      vam->result_ready = 1;
1947    }
1948}
1949
1950static void vl_api_bond_enslave_reply_t_handler_json
1951  (vl_api_bond_enslave_reply_t * mp)
1952{
1953  vat_main_t *vam = &vat_main;
1954  vat_json_node_t node;
1955
1956  vat_json_init_object (&node);
1957  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1958
1959  vat_json_print (vam->ofp, &node);
1960  vat_json_free (&node);
1961
1962  vam->retval = ntohl (mp->retval);
1963  vam->result_ready = 1;
1964}
1965
1966static void
1967vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1968					  mp)
1969{
1970  vat_main_t *vam = &vat_main;
1971  i32 retval = ntohl (mp->retval);
1972
1973  if (vam->async_mode)
1974    {
1975      vam->async_errors += (retval < 0);
1976    }
1977  else
1978    {
1979      vam->retval = retval;
1980      vam->result_ready = 1;
1981    }
1982}
1983
1984static void vl_api_bond_detach_slave_reply_t_handler_json
1985  (vl_api_bond_detach_slave_reply_t * mp)
1986{
1987  vat_main_t *vam = &vat_main;
1988  vat_json_node_t node;
1989
1990  vat_json_init_object (&node);
1991  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1992
1993  vat_json_print (vam->ofp, &node);
1994  vat_json_free (&node);
1995
1996  vam->retval = ntohl (mp->retval);
1997  vam->result_ready = 1;
1998}
1999
2000static int
2001api_sw_interface_set_bond_weight (vat_main_t * vam)
2002{
2003  unformat_input_t *i = vam->input;
2004  vl_api_sw_interface_set_bond_weight_t *mp;
2005  u32 sw_if_index = ~0;
2006  u32 weight = 0;
2007  u8 weight_enter = 0;
2008  int ret;
2009
2010  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2011    {
2012      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2013	;
2014      else if (unformat (i, "sw_if_index %d", &sw_if_index))
2015	;
2016      else if (unformat (i, "weight %u", &weight))
2017	weight_enter = 1;
2018      else
2019	break;
2020    }
2021
2022  if (sw_if_index == ~0)
2023    {
2024      errmsg ("missing interface name or sw_if_index");
2025      return -99;
2026    }
2027  if (weight_enter == 0)
2028    {
2029      errmsg ("missing valid weight");
2030      return -99;
2031    }
2032
2033  /* Construct the API message */
2034  M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2035  mp->sw_if_index = ntohl (sw_if_index);
2036  mp->weight = ntohl (weight);
2037
2038  S (mp);
2039  W (ret);
2040  return ret;
2041}
2042
2043static void vl_api_sw_interface_bond_details_t_handler
2044  (vl_api_sw_interface_bond_details_t * mp)
2045{
2046  vat_main_t *vam = &vat_main;
2047
2048  print (vam->ofp,
2049	 "%-16s %-12d %-12U %-13U %-14u %-14u",
2050	 mp->interface_name, ntohl (mp->sw_if_index),
2051	 format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2052	 ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2053}
2054
2055static void vl_api_sw_interface_bond_details_t_handler_json
2056  (vl_api_sw_interface_bond_details_t * mp)
2057{
2058  vat_main_t *vam = &vat_main;
2059  vat_json_node_t *node = NULL;
2060
2061  if (VAT_JSON_ARRAY != vam->json_tree.type)
2062    {
2063      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2064      vat_json_init_array (&vam->json_tree);
2065    }
2066  node = vat_json_array_add (&vam->json_tree);
2067
2068  vat_json_init_object (node);
2069  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2070  vat_json_object_add_string_copy (node, "interface_name",
2071				   mp->interface_name);
2072  vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2073  vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2074  vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2075  vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2076}
2077
2078static int
2079api_sw_interface_bond_dump (vat_main_t * vam)
2080{
2081  vl_api_sw_interface_bond_dump_t *mp;
2082  vl_api_control_ping_t *mp_ping;
2083  int ret;
2084
2085  print (vam->ofp,
2086	 "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2087	 "interface name", "sw_if_index", "mode", "load balance",
2088	 "active slaves", "slaves");
2089
2090  /* Get list of bond interfaces */
2091  M (SW_INTERFACE_BOND_DUMP, mp);
2092  S (mp);
2093
2094  /* Use a control ping for synchronization */
2095  MPING (CONTROL_PING, mp_ping);
2096  S (mp_ping);
2097
2098  W (ret);
2099  return ret;
2100}
2101
2102static void vl_api_sw_interface_slave_details_t_handler
2103  (vl_api_sw_interface_slave_details_t * mp)
2104{
2105  vat_main_t *vam = &vat_main;
2106
2107  print (vam->ofp,
2108	 "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2109	 ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2110	 ntohl (mp->weight), mp->is_local_numa);
2111}
2112
2113static void vl_api_sw_interface_slave_details_t_handler_json
2114  (vl_api_sw_interface_slave_details_t * mp)
2115{
2116  vat_main_t *vam = &vat_main;
2117  vat_json_node_t *node = NULL;
2118
2119  if (VAT_JSON_ARRAY != vam->json_tree.type)
2120    {
2121      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2122      vat_json_init_array (&vam->json_tree);
2123    }
2124  node = vat_json_array_add (&vam->json_tree);
2125
2126  vat_json_init_object (node);
2127  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2128  vat_json_object_add_string_copy (node, "interface_name",
2129				   mp->interface_name);
2130  vat_json_object_add_uint (node, "passive", mp->is_passive);
2131  vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2132  vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2133  vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2134}
2135
2136static int
2137api_sw_interface_slave_dump (vat_main_t * vam)
2138{
2139  unformat_input_t *i = vam->input;
2140  vl_api_sw_interface_slave_dump_t *mp;
2141  vl_api_control_ping_t *mp_ping;
2142  u32 sw_if_index = ~0;
2143  u8 sw_if_index_set = 0;
2144  int ret;
2145
2146  /* Parse args required to build the message */
2147  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2148    {
2149      if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2150	sw_if_index_set = 1;
2151      else if (unformat (i, "sw_if_index %d", &sw_if_index))
2152	sw_if_index_set = 1;
2153      else
2154	break;
2155    }
2156
2157  if (sw_if_index_set == 0)
2158    {
2159      errmsg ("missing vpp interface name. ");
2160      return -99;
2161    }
2162
2163  print (vam->ofp,
2164	 "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2165	 "slave interface name", "sw_if_index", "passive", "long_timeout",
2166	 "weight", "local numa");
2167
2168  /* Get list of bond interfaces */
2169  M (SW_INTERFACE_SLAVE_DUMP, mp);
2170  mp->sw_if_index = ntohl (sw_if_index);
2171  S (mp);
2172
2173  /* Use a control ping for synchronization */
2174  MPING (CONTROL_PING, mp_ping);
2175  S (mp_ping);
2176
2177  W (ret);
2178  return ret;
2179}
2180
2181static void vl_api_mpls_tunnel_add_del_reply_t_handler
2182  (vl_api_mpls_tunnel_add_del_reply_t * mp)
2183{
2184  vat_main_t *vam = &vat_main;
2185  i32 retval = ntohl (mp->retval);
2186  if (vam->async_mode)
2187    {
2188      vam->async_errors += (retval < 0);
2189    }
2190  else
2191    {
2192      vam->retval = retval;
2193      vam->sw_if_index = ntohl (mp->sw_if_index);
2194      vam->result_ready = 1;
2195    }
2196  vam->regenerate_interface_table = 1;
2197}
2198
2199static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2200  (vl_api_mpls_tunnel_add_del_reply_t * mp)
2201{
2202  vat_main_t *vam = &vat_main;
2203  vat_json_node_t node;
2204
2205  vat_json_init_object (&node);
2206  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2207  vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2208			    ntohl (mp->sw_if_index));
2209
2210  vat_json_print (vam->ofp, &node);
2211  vat_json_free (&node);
2212
2213  vam->retval = ntohl (mp->retval);
2214  vam->result_ready = 1;
2215}
2216
2217static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2218  (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2219{
2220  vat_main_t *vam = &vat_main;
2221  i32 retval = ntohl (mp->retval);
2222  if (vam->async_mode)
2223    {
2224      vam->async_errors += (retval < 0);
2225    }
2226  else
2227    {
2228      vam->retval = retval;
2229      vam->sw_if_index = ntohl (mp->sw_if_index);
2230      vam->result_ready = 1;
2231    }
2232}
2233
2234static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2235  (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2236{
2237  vat_main_t *vam = &vat_main;
2238  vat_json_node_t node;
2239
2240  vat_json_init_object (&node);
2241  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2242  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2243
2244  vat_json_print (vam->ofp, &node);
2245  vat_json_free (&node);
2246
2247  vam->retval = ntohl (mp->retval);
2248  vam->result_ready = 1;
2249}
2250
2251static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2252  (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2253{
2254  vat_main_t *vam = &vat_main;
2255  i32 retval = ntohl (mp->retval);
2256  if (vam->async_mode)
2257    {
2258      vam->async_errors += (retval < 0);
2259    }
2260  else
2261    {
2262      vam->retval = retval;
2263      vam->result_ready = 1;
2264    }
2265}
2266
2267static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2268  (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2269{
2270  vat_main_t *vam = &vat_main;
2271  vat_json_node_t node;
2272
2273  vat_json_init_object (&node);
2274  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2275  vat_json_object_add_uint (&node, "fwd_entry_index",
2276			    clib_net_to_host_u32 (mp->fwd_entry_index));
2277
2278  vat_json_print (vam->ofp, &node);
2279  vat_json_free (&node);
2280
2281  vam->retval = ntohl (mp->retval);
2282  vam->result_ready = 1;
2283}
2284
2285u8 *
2286format_lisp_transport_protocol (u8 * s, va_list * args)
2287{
2288  u32 proto = va_arg (*args, u32);
2289
2290  switch (proto)
2291    {
2292    case 1:
2293      return format (s, "udp");
2294    case 2:
2295      return format (s, "api");
2296    default:
2297      return 0;
2298    }
2299  return 0;
2300}
2301
2302static void vl_api_one_get_transport_protocol_reply_t_handler
2303  (vl_api_one_get_transport_protocol_reply_t * mp)
2304{
2305  vat_main_t *vam = &vat_main;
2306  i32 retval = ntohl (mp->retval);
2307  if (vam->async_mode)
2308    {
2309      vam->async_errors += (retval < 0);
2310    }
2311  else
2312    {
2313      u32 proto = mp->protocol;
2314      print (vam->ofp, "Transport protocol: %U",
2315	     format_lisp_transport_protocol, proto);
2316      vam->retval = retval;
2317      vam->result_ready = 1;
2318    }
2319}
2320
2321static void vl_api_one_get_transport_protocol_reply_t_handler_json
2322  (vl_api_one_get_transport_protocol_reply_t * mp)
2323{
2324  vat_main_t *vam = &vat_main;
2325  vat_json_node_t node;
2326  u8 *s;
2327
2328  s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2329  vec_add1 (s, 0);
2330
2331  vat_json_init_object (&node);
2332  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2333  vat_json_object_add_string_copy (&node, "transport-protocol", s);
2334
2335  vec_free (s);
2336  vat_json_print (vam->ofp, &node);
2337  vat_json_free (&node);
2338
2339  vam->retval = ntohl (mp->retval);
2340  vam->result_ready = 1;
2341}
2342
2343static void vl_api_one_add_del_locator_set_reply_t_handler
2344  (vl_api_one_add_del_locator_set_reply_t * mp)
2345{
2346  vat_main_t *vam = &vat_main;
2347  i32 retval = ntohl (mp->retval);
2348  if (vam->async_mode)
2349    {
2350      vam->async_errors += (retval < 0);
2351    }
2352  else
2353    {
2354      vam->retval = retval;
2355      vam->result_ready = 1;
2356    }
2357}
2358
2359static void vl_api_one_add_del_locator_set_reply_t_handler_json
2360  (vl_api_one_add_del_locator_set_reply_t * mp)
2361{
2362  vat_main_t *vam = &vat_main;
2363  vat_json_node_t node;
2364
2365  vat_json_init_object (&node);
2366  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2367  vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2368
2369  vat_json_print (vam->ofp, &node);
2370  vat_json_free (&node);
2371
2372  vam->retval = ntohl (mp->retval);
2373  vam->result_ready = 1;
2374}
2375
2376static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2377  (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2378{
2379  vat_main_t *vam = &vat_main;
2380  i32 retval = ntohl (mp->retval);
2381  if (vam->async_mode)
2382    {
2383      vam->async_errors += (retval < 0);
2384    }
2385  else
2386    {
2387      vam->retval = retval;
2388      vam->sw_if_index = ntohl (mp->sw_if_index);
2389      vam->result_ready = 1;
2390    }
2391  vam->regenerate_interface_table = 1;
2392}
2393
2394static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2395  (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2396{
2397  vat_main_t *vam = &vat_main;
2398  vat_json_node_t node;
2399
2400  vat_json_init_object (&node);
2401  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2402  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2403
2404  vat_json_print (vam->ofp, &node);
2405  vat_json_free (&node);
2406
2407  vam->retval = ntohl (mp->retval);
2408  vam->result_ready = 1;
2409}
2410
2411static void vl_api_vxlan_offload_rx_reply_t_handler
2412  (vl_api_vxlan_offload_rx_reply_t * mp)
2413{
2414  vat_main_t *vam = &vat_main;
2415  i32 retval = ntohl (mp->retval);
2416  if (vam->async_mode)
2417    {
2418      vam->async_errors += (retval < 0);
2419    }
2420  else
2421    {
2422      vam->retval = retval;
2423      vam->result_ready = 1;
2424    }
2425}
2426
2427static void vl_api_vxlan_offload_rx_reply_t_handler_json
2428  (vl_api_vxlan_offload_rx_reply_t * mp)
2429{
2430  vat_main_t *vam = &vat_main;
2431  vat_json_node_t node;
2432
2433  vat_json_init_object (&node);
2434  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2435
2436  vat_json_print (vam->ofp, &node);
2437  vat_json_free (&node);
2438
2439  vam->retval = ntohl (mp->retval);
2440  vam->result_ready = 1;
2441}
2442
2443static void vl_api_geneve_add_del_tunnel_reply_t_handler
2444  (vl_api_geneve_add_del_tunnel_reply_t * mp)
2445{
2446  vat_main_t *vam = &vat_main;
2447  i32 retval = ntohl (mp->retval);
2448  if (vam->async_mode)
2449    {
2450      vam->async_errors += (retval < 0);
2451    }
2452  else
2453    {
2454      vam->retval = retval;
2455      vam->sw_if_index = ntohl (mp->sw_if_index);
2456      vam->result_ready = 1;
2457    }
2458}
2459
2460static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2461  (vl_api_geneve_add_del_tunnel_reply_t * mp)
2462{
2463  vat_main_t *vam = &vat_main;
2464  vat_json_node_t node;
2465
2466  vat_json_init_object (&node);
2467  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2468  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2469
2470  vat_json_print (vam->ofp, &node);
2471  vat_json_free (&node);
2472
2473  vam->retval = ntohl (mp->retval);
2474  vam->result_ready = 1;
2475}
2476
2477static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2478  (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2479{
2480  vat_main_t *vam = &vat_main;
2481  i32 retval = ntohl (mp->retval);
2482  if (vam->async_mode)
2483    {
2484      vam->async_errors += (retval < 0);
2485    }
2486  else
2487    {
2488      vam->retval = retval;
2489      vam->sw_if_index = ntohl (mp->sw_if_index);
2490      vam->result_ready = 1;
2491    }
2492  vam->regenerate_interface_table = 1;
2493}
2494
2495static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2496  (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2497{
2498  vat_main_t *vam = &vat_main;
2499  vat_json_node_t node;
2500
2501  vat_json_init_object (&node);
2502  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2503  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2504
2505  vat_json_print (vam->ofp, &node);
2506  vat_json_free (&node);
2507
2508  vam->retval = ntohl (mp->retval);
2509  vam->result_ready = 1;
2510}
2511
2512static void vl_api_gre_tunnel_add_del_reply_t_handler
2513  (vl_api_gre_tunnel_add_del_reply_t * mp)
2514{
2515  vat_main_t *vam = &vat_main;
2516  i32 retval = ntohl (mp->retval);
2517  if (vam->async_mode)
2518    {
2519      vam->async_errors += (retval < 0);
2520    }
2521  else
2522    {
2523      vam->retval = retval;
2524      vam->sw_if_index = ntohl (mp->sw_if_index);
2525      vam->result_ready = 1;
2526    }
2527}
2528
2529static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2530  (vl_api_gre_tunnel_add_del_reply_t * mp)
2531{
2532  vat_main_t *vam = &vat_main;
2533  vat_json_node_t node;
2534
2535  vat_json_init_object (&node);
2536  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2537  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2538
2539  vat_json_print (vam->ofp, &node);
2540  vat_json_free (&node);
2541
2542  vam->retval = ntohl (mp->retval);
2543  vam->result_ready = 1;
2544}
2545
2546static void vl_api_create_vhost_user_if_reply_t_handler
2547  (vl_api_create_vhost_user_if_reply_t * mp)
2548{
2549  vat_main_t *vam = &vat_main;
2550  i32 retval = ntohl (mp->retval);
2551  if (vam->async_mode)
2552    {
2553      vam->async_errors += (retval < 0);
2554    }
2555  else
2556    {
2557      vam->retval = retval;
2558      vam->sw_if_index = ntohl (mp->sw_if_index);
2559      vam->result_ready = 1;
2560    }
2561  vam->regenerate_interface_table = 1;
2562}
2563
2564static void vl_api_create_vhost_user_if_reply_t_handler_json
2565  (vl_api_create_vhost_user_if_reply_t * mp)
2566{
2567  vat_main_t *vam = &vat_main;
2568  vat_json_node_t node;
2569
2570  vat_json_init_object (&node);
2571  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2572  vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2573
2574  vat_json_print (vam->ofp, &node);
2575  vat_json_free (&node);
2576
2577  vam->retval = ntohl (mp->retval);
2578  vam->result_ready = 1;
2579}
2580
2581static void vl_api_ip_address_details_t_handler
2582  (vl_api_ip_address_details_t * mp)
2583{
2584  vat_main_t *vam = &vat_main;
2585  static ip_address_details_t empty_ip_address_details = { {0} };
2586  ip_address_details_t *address = NULL;
2587  ip_details_t *current_ip_details = NULL;
2588  ip_details_t *details = NULL;
2589
2590  details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2591
2592  if (!details || vam->current_sw_if_index >= vec_len (details)
2593      || !details[vam->current_sw_if_index].present)
2594    {
2595      errmsg ("ip address details arrived but not stored");
2596      errmsg ("ip_dump should be called first");
2597      return;
2598    }
2599
2600  current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2601
2602#define addresses (current_ip_details->addr)
2603
2604  vec_validate_init_empty (addresses, vec_len (addresses),
2605			   empty_ip_address_details);
2606
2607  address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2608
2609  clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2610  address->prefix_length = mp->prefix.len;
2611#undef addresses
2612}
2613
2614static void vl_api_ip_address_details_t_handler_json
2615  (vl_api_ip_address_details_t * mp)
2616{
2617  vat_main_t *vam = &vat_main;
2618  vat_json_node_t *node = NULL;
2619
2620  if (VAT_JSON_ARRAY != vam->json_tree.type)
2621    {
2622      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2623      vat_json_init_array (&vam->json_tree);
2624    }
2625  node = vat_json_array_add (&vam->json_tree);
2626
2627  vat_json_init_object (node);
2628  vat_json_object_add_prefix (node, &mp->prefix);
2629}
2630
2631static void
2632vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2633{
2634  vat_main_t *vam = &vat_main;
2635  static ip_details_t empty_ip_details = { 0 };
2636  ip_details_t *ip = NULL;
2637  u32 sw_if_index = ~0;
2638
2639  sw_if_index = ntohl (mp->sw_if_index);
2640
2641  vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2642			   sw_if_index, empty_ip_details);
2643
2644  ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2645			 sw_if_index);
2646
2647  ip->present = 1;
2648}
2649
2650static void
2651vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2652{
2653  vat_main_t *vam = &vat_main;
2654
2655  if (VAT_JSON_ARRAY != vam->json_tree.type)
2656    {
2657      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2658      vat_json_init_array (&vam->json_tree);
2659    }
2660  vat_json_array_add_uint (&vam->json_tree,
2661			   clib_net_to_host_u32 (mp->sw_if_index));
2662}
2663
2664static void vl_api_get_first_msg_id_reply_t_handler
2665  (vl_api_get_first_msg_id_reply_t * mp)
2666{
2667  vat_main_t *vam = &vat_main;
2668  i32 retval = ntohl (mp->retval);
2669
2670  if (vam->async_mode)
2671    {
2672      vam->async_errors += (retval < 0);
2673    }
2674  else
2675    {
2676      vam->retval = retval;
2677      vam->result_ready = 1;
2678    }
2679  if (retval >= 0)
2680    {
2681      errmsg ("first message id %d", ntohs (mp->first_msg_id));
2682    }
2683}
2684
2685static void vl_api_get_first_msg_id_reply_t_handler_json
2686  (vl_api_get_first_msg_id_reply_t * mp)
2687{
2688  vat_main_t *vam = &vat_main;
2689  vat_json_node_t node;
2690
2691  vat_json_init_object (&node);
2692  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2693  vat_json_object_add_uint (&node, "first_msg_id",
2694			    (uint) ntohs (mp->first_msg_id));
2695
2696  vat_json_print (vam->ofp, &node);
2697  vat_json_free (&node);
2698
2699  vam->retval = ntohl (mp->retval);
2700  vam->result_ready = 1;
2701}
2702
2703static void vl_api_get_node_graph_reply_t_handler
2704  (vl_api_get_node_graph_reply_t * mp)
2705{
2706  vat_main_t *vam = &vat_main;
2707  i32 retval = ntohl (mp->retval);
2708  u8 *pvt_copy, *reply;
2709  void *oldheap;
2710  vlib_node_t *node;
2711  int i;
2712
2713  if (vam->async_mode)
2714    {
2715      vam->async_errors += (retval < 0);
2716    }
2717  else
2718    {
2719      vam->retval = retval;
2720      vam->result_ready = 1;
2721    }
2722
2723  /* "Should never happen..." */
2724  if (retval != 0)
2725    return;
2726
2727  reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2728  pvt_copy = vec_dup (reply);
2729
2730  /* Toss the shared-memory original... */
2731  oldheap = vl_msg_push_heap ();
2732
2733  vec_free (reply);
2734
2735  vl_msg_pop_heap (oldheap);
2736
2737  if (vam->graph_nodes)
2738    {
2739      hash_free (vam->graph_node_index_by_name);
2740
2741      for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2742	{
2743	  node = vam->graph_nodes[0][i];
2744	  vec_free (node->name);
2745	  vec_free (node->next_nodes);
2746	  vec_free (node);
2747	}
2748      vec_free (vam->graph_nodes[0]);
2749      vec_free (vam->graph_nodes);
2750    }
2751
2752  vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2753  vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2754  vec_free (pvt_copy);
2755
2756  for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2757    {
2758      node = vam->graph_nodes[0][i];
2759      hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2760    }
2761}
2762
2763static void vl_api_get_node_graph_reply_t_handler_json
2764  (vl_api_get_node_graph_reply_t * mp)
2765{
2766  vat_main_t *vam = &vat_main;
2767  void *oldheap;
2768  vat_json_node_t node;
2769  u8 *reply;
2770
2771  /* $$$$ make this real? */
2772  vat_json_init_object (&node);
2773  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2774  vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2775
2776  reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2777
2778  /* Toss the shared-memory original... */
2779  oldheap = vl_msg_push_heap ();
2780
2781  vec_free (reply);
2782
2783  vl_msg_pop_heap (oldheap);
2784
2785  vat_json_print (vam->ofp, &node);
2786  vat_json_free (&node);
2787
2788  vam->retval = ntohl (mp->retval);
2789  vam->result_ready = 1;
2790}
2791
2792static void
2793vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2794{
2795  vat_main_t *vam = &vat_main;
2796  u8 *s = 0;
2797
2798  if (mp->local)
2799    {
2800      s = format (s, "%=16d%=16d%=16d",
2801		  ntohl (mp->sw_if_index), mp->priority, mp->weight);
2802    }
2803  else
2804    {
2805      s = format (s, "%=16U%=16d%=16d",
2806		  format_ip46_address,
2807		  mp->ip_address, mp->priority, mp->weight);
2808    }
2809
2810  print (vam->ofp, "%v", s);
2811  vec_free (s);
2812}
2813
2814static void
2815vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2816{
2817  vat_main_t *vam = &vat_main;
2818  vat_json_node_t *node = NULL;
2819  struct in6_addr ip6;
2820  struct in_addr ip4;
2821
2822  if (VAT_JSON_ARRAY != vam->json_tree.type)
2823    {
2824      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2825      vat_json_init_array (&vam->json_tree);
2826    }
2827  node = vat_json_array_add (&vam->json_tree);
2828  vat_json_init_object (node);
2829
2830  vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2831  vat_json_object_add_uint (node, "priority", mp->priority);
2832  vat_json_object_add_uint (node, "weight", mp->weight);
2833
2834  if (mp->local)
2835    vat_json_object_add_uint (node, "sw_if_index",
2836			      clib_net_to_host_u32 (mp->sw_if_index));
2837  else
2838    {
2839      if (mp->ip_address.af)
2840	{
2841	  clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
2842	  vat_json_object_add_ip6 (node, "address", ip6);
2843	}
2844      else
2845	{
2846	  clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
2847	  vat_json_object_add_ip4 (node, "address", ip4);
2848	}
2849    }
2850}
2851
2852static void
2853vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2854					  mp)
2855{
2856  vat_main_t *vam = &vat_main;
2857  u8 *ls_name = 0;
2858
2859  ls_name = format (0, "%s", mp->ls_name);
2860
2861  print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2862	 ls_name);
2863  vec_free (ls_name);
2864}
2865
2866static void
2867  vl_api_one_locator_set_details_t_handler_json
2868  (vl_api_one_locator_set_details_t * mp)
2869{
2870  vat_main_t *vam = &vat_main;
2871  vat_json_node_t *node = 0;
2872  u8 *ls_name = 0;
2873
2874  ls_name = format (0, "%s", mp->ls_name);
2875  vec_add1 (ls_name, 0);
2876
2877  if (VAT_JSON_ARRAY != vam->json_tree.type)
2878    {
2879      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2880      vat_json_init_array (&vam->json_tree);
2881    }
2882  node = vat_json_array_add (&vam->json_tree);
2883
2884  vat_json_init_object (node);
2885  vat_json_object_add_string_copy (node, "ls_name", ls_name);
2886  vat_json_object_add_uint (node, "ls_index",
2887			    clib_net_to_host_u32 (mp->ls_index));
2888  vec_free (ls_name);
2889}
2890
2891typedef struct
2892{
2893  u32 spi;
2894  u8 si;
2895} __attribute__ ((__packed__)) lisp_nsh_api_t;
2896
2897uword
2898unformat_nsh_address (unformat_input_t * input, va_list * args)
2899{
2900  lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2901  return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2902}
2903
2904u8 *
2905format_nsh_address_vat (u8 * s, va_list * args)
2906{
2907  nsh_t *a = va_arg (*args, nsh_t *);
2908  return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2909}
2910
2911static u8 *
2912format_lisp_flat_eid (u8 * s, va_list * args)
2913{
2914  vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
2915
2916  switch (eid->type)
2917    {
2918    case EID_TYPE_API_PREFIX:
2919      if (eid->address.prefix.address.af)
2920	return format (s, "%U/%d", format_ip6_address,
2921		       eid->address.prefix.address.un.ip6,
2922		       eid->address.prefix.len);
2923      return format (s, "%U/%d", format_ip4_address,
2924		     eid->address.prefix.address.un.ip4,
2925		     eid->address.prefix.len);
2926    case EID_TYPE_API_MAC:
2927      return format (s, "%U", format_ethernet_address, eid->address.mac);
2928    case EID_TYPE_API_NSH:
2929      return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
2930    }
2931  return 0;
2932}
2933
2934static u8 *
2935format_lisp_eid_vat (u8 * s, va_list * args)
2936{
2937  vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
2938  vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
2939  u8 is_src_dst = (u8) va_arg (*args, int);
2940
2941  if (is_src_dst)
2942    s = format (s, "%U|", format_lisp_flat_eid, seid);
2943
2944  s = format (s, "%U", format_lisp_flat_eid, deid);
2945
2946  return s;
2947}
2948
2949static void
2950vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2951{
2952  vat_main_t *vam = &vat_main;
2953  u8 *s = 0, *eid = 0;
2954
2955  if (~0 == mp->locator_set_index)
2956    s = format (0, "action: %d", mp->action);
2957  else
2958    s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2959
2960  eid = format (0, "%U", format_lisp_eid_vat,
2961		mp->deid, mp->seid, mp->is_src_dst);
2962  vec_add1 (eid, 0);
2963
2964  print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2965	 clib_net_to_host_u32 (mp->vni),
2966	 eid,
2967	 mp->is_local ? "local" : "remote",
2968	 s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2969	 clib_net_to_host_u16 (mp->key.id), mp->key.key);
2970
2971  vec_free (s);
2972  vec_free (eid);
2973}
2974
2975static void
2976vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2977					     * mp)
2978{
2979  vat_main_t *vam = &vat_main;
2980  vat_json_node_t *node = 0;
2981  u8 *eid = 0;
2982
2983  if (VAT_JSON_ARRAY != vam->json_tree.type)
2984    {
2985      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2986      vat_json_init_array (&vam->json_tree);
2987    }
2988  node = vat_json_array_add (&vam->json_tree);
2989
2990  vat_json_init_object (node);
2991  if (~0 == mp->locator_set_index)
2992    vat_json_object_add_uint (node, "action", mp->action);
2993  else
2994    vat_json_object_add_uint (node, "locator_set_index",
2995			      clib_net_to_host_u32 (mp->locator_set_index));
2996
2997  vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2998  if (mp->deid.type == 3)
2999    {
3000      vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3001      vat_json_init_object (nsh_json);
3002      lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) & mp->deid.address.nsh;
3003      vat_json_object_add_uint (nsh_json, "spi",
3004				clib_net_to_host_u32 (nsh->spi));
3005      vat_json_object_add_uint (nsh_json, "si", nsh->si);
3006    }
3007  else
3008    {
3009      eid = format (0, "%U", format_lisp_eid_vat,
3010		    mp->deid, mp->seid, mp->is_src_dst);
3011      vec_add1 (eid, 0);
3012      vat_json_object_add_string_copy (node, "eid", eid);
3013      vec_free (eid);
3014    }
3015  vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3016  vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3017  vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3018
3019  if (mp->key.id)
3020    {
3021      vat_json_object_add_uint (node, "key_id",
3022				clib_net_to_host_u16 (mp->key.id));
3023      vat_json_object_add_string_copy (node, "key", mp->key.key);
3024    }
3025}
3026
3027static void
3028vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3029{
3030  vat_main_t *vam = &vat_main;
3031  u8 *seid = 0, *deid = 0;
3032  ip46_address_t lloc, rloc;
3033
3034  deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
3035
3036  seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
3037
3038  vec_add1 (deid, 0);
3039  vec_add1 (seid, 0);
3040
3041  if (mp->lloc.af)
3042    {
3043      clib_memcpy (&lloc.ip6, mp->lloc.un.ip6, 16);
3044      clib_memcpy (&rloc.ip6, mp->rloc.un.ip6, 16);
3045    }
3046  else
3047    {
3048      clib_memcpy (&lloc.ip4, mp->lloc.un.ip4, 4);
3049      clib_memcpy (&rloc.ip4, mp->rloc.un.ip4, 4);
3050    }
3051
3052
3053  print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3054	 clib_net_to_host_u32 (mp->vni),
3055	 seid, deid,
3056	 format_ip46_address, lloc,
3057	 format_ip46_address, rloc,
3058	 clib_net_to_host_u32 (mp->pkt_count),
3059	 clib_net_to_host_u32 (mp->bytes));
3060
3061  vec_free (deid);
3062  vec_free (seid);
3063}
3064
3065static void
3066vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3067{
3068  struct in6_addr ip6;
3069  struct in_addr ip4;
3070  vat_main_t *vam = &vat_main;
3071  vat_json_node_t *node = 0;
3072  u8 *deid = 0, *seid = 0;
3073
3074  if (VAT_JSON_ARRAY != vam->json_tree.type)
3075    {
3076      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3077      vat_json_init_array (&vam->json_tree);
3078    }
3079  node = vat_json_array_add (&vam->json_tree);
3080
3081  vat_json_init_object (node);
3082  deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
3083
3084  seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
3085
3086  vec_add1 (deid, 0);
3087  vec_add1 (seid, 0);
3088
3089  vat_json_object_add_string_copy (node, "seid", seid);
3090  vat_json_object_add_string_copy (node, "deid", deid);
3091  vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3092
3093  if (mp->lloc.af)
3094    {
3095      clib_memcpy (&ip6, mp->lloc.un.ip6, sizeof (ip6));
3096      vat_json_object_add_ip6 (node, "lloc", ip6);
3097      clib_memcpy (&ip6, mp->rloc.un.ip6, sizeof (ip6));
3098      vat_json_object_add_ip6 (node, "rloc", ip6);
3099
3100    }
3101  else
3102    {
3103      clib_memcpy (&ip4, mp->lloc.un.ip4, sizeof (ip4));
3104      vat_json_object_add_ip4 (node, "lloc", ip4);
3105      clib_memcpy (&ip4, mp->rloc.un.ip4, sizeof (ip4));
3106      vat_json_object_add_ip4 (node, "rloc", ip4);
3107    }
3108  vat_json_object_add_uint (node, "pkt_count",
3109			    clib_net_to_host_u32 (mp->pkt_count));
3110  vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3111
3112  vec_free (deid);
3113  vec_free (seid);
3114}
3115
3116static void
3117  vl_api_one_eid_table_map_details_t_handler
3118  (vl_api_one_eid_table_map_details_t * mp)
3119{
3120  vat_main_t *vam = &vat_main;
3121
3122  u8 *line = format (0, "%=10d%=10d",
3123		     clib_net_to_host_u32 (mp->vni),
3124		     clib_net_to_host_u32 (mp->dp_table));
3125  print (vam->ofp, "%v", line);
3126  vec_free (line);
3127}
3128
3129static void
3130  vl_api_one_eid_table_map_details_t_handler_json
3131  (vl_api_one_eid_table_map_details_t * mp)
3132{
3133  vat_main_t *vam = &vat_main;
3134  vat_json_node_t *node = NULL;
3135
3136  if (VAT_JSON_ARRAY != vam->json_tree.type)
3137    {
3138      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3139      vat_json_init_array (&vam->json_tree);
3140    }
3141  node = vat_json_array_add (&vam->json_tree);
3142  vat_json_init_object (node);
3143  vat_json_object_add_uint (node, "dp_table",
3144			    clib_net_to_host_u32 (mp->dp_table));
3145  vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3146}
3147
3148static void
3149  vl_api_one_eid_table_vni_details_t_handler
3150  (vl_api_one_eid_table_vni_details_t * mp)
3151{
3152  vat_main_t *vam = &vat_main;
3153
3154  u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3155  print (vam->ofp, "%v", line);
3156  vec_free (line);
3157}
3158
3159static void
3160  vl_api_one_eid_table_vni_details_t_handler_json
3161  (vl_api_one_eid_table_vni_details_t * mp)
3162{
3163  vat_main_t *vam = &vat_main;
3164  vat_json_node_t *node = NULL;
3165
3166  if (VAT_JSON_ARRAY != vam->json_tree.type)
3167    {
3168      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3169      vat_json_init_array (&vam->json_tree);
3170    }
3171  node = vat_json_array_add (&vam->json_tree);
3172  vat_json_init_object (node);
3173  vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3174}
3175
3176static void
3177  vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3178  (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3179{
3180  vat_main_t *vam = &vat_main;
3181  int retval = clib_net_to_host_u32 (mp->retval);
3182
3183  vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3184  print (vam->ofp, "fallback threshold value: %d", mp->value);
3185
3186  vam->retval = retval;
3187  vam->result_ready = 1;
3188}
3189
3190static void
3191  vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3192  (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3193{
3194  vat_main_t *vam = &vat_main;
3195  vat_json_node_t _node, *node = &_node;
3196  int retval = clib_net_to_host_u32 (mp->retval);
3197
3198  vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3199  vat_json_init_object (node);
3200  vat_json_object_add_uint (node, "value", mp->value);
3201
3202  vat_json_print (vam->ofp, node);
3203  vat_json_free (node);
3204
3205  vam->retval = retval;
3206  vam->result_ready = 1;
3207}
3208
3209static void
3210  vl_api_show_one_map_register_state_reply_t_handler
3211  (vl_api_show_one_map_register_state_reply_t * mp)
3212{
3213  vat_main_t *vam = &vat_main;
3214  int retval = clib_net_to_host_u32 (mp->retval);
3215
3216  print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3217
3218  vam->retval = retval;
3219  vam->result_ready = 1;
3220}
3221
3222static void
3223  vl_api_show_one_map_register_state_reply_t_handler_json
3224  (vl_api_show_one_map_register_state_reply_t * mp)
3225{
3226  vat_main_t *vam = &vat_main;
3227  vat_json_node_t _node, *node = &_node;
3228  int retval = clib_net_to_host_u32 (mp->retval);
3229
3230  u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3231
3232  vat_json_init_object (node);
3233  vat_json_object_add_string_copy (node, "state", s);
3234
3235  vat_json_print (vam->ofp, node);
3236  vat_json_free (node);
3237
3238  vam->retval = retval;
3239  vam->result_ready = 1;
3240  vec_free (s);
3241}
3242
3243static void
3244  vl_api_show_one_rloc_probe_state_reply_t_handler
3245  (vl_api_show_one_rloc_probe_state_reply_t * mp)
3246{
3247  vat_main_t *vam = &vat_main;
3248  int retval = clib_net_to_host_u32 (mp->retval);
3249
3250  if (retval)
3251    goto end;
3252
3253  print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3254end:
3255  vam->retval = retval;
3256  vam->result_ready = 1;
3257}
3258
3259static void
3260  vl_api_show_one_rloc_probe_state_reply_t_handler_json
3261  (vl_api_show_one_rloc_probe_state_reply_t * mp)
3262{
3263  vat_main_t *vam = &vat_main;
3264  vat_json_node_t _node, *node = &_node;
3265  int retval = clib_net_to_host_u32 (mp->retval);
3266
3267  u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3268  vat_json_init_object (node);
3269  vat_json_object_add_string_copy (node, "state", s);
3270
3271  vat_json_print (vam->ofp, node);
3272  vat_json_free (node);
3273
3274  vam->retval = retval;
3275  vam->result_ready = 1;
3276  vec_free (s);
3277}
3278
3279static void
3280  vl_api_show_one_stats_enable_disable_reply_t_handler
3281  (vl_api_show_one_stats_enable_disable_reply_t * mp)
3282{
3283  vat_main_t *vam = &vat_main;
3284  int retval = clib_net_to_host_u32 (mp->retval);
3285
3286  if (retval)
3287    goto end;
3288
3289  print (vam->ofp, "%s", mp->is_enable ? "enabled" : "disabled");
3290end:
3291  vam->retval = retval;
3292  vam->result_ready = 1;
3293}
3294
3295static void
3296  vl_api_show_one_stats_enable_disable_reply_t_handler_json
3297  (vl_api_show_one_stats_enable_disable_reply_t * mp)
3298{
3299  vat_main_t *vam = &vat_main;
3300  vat_json_node_t _node, *node = &_node;
3301  int retval = clib_net_to_host_u32 (mp->retval);
3302
3303  u8 *s = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
3304  vat_json_init_object (node);
3305  vat_json_object_add_string_copy (node, "state", s);
3306
3307  vat_json_print (vam->ofp, node);
3308  vat_json_free (node);
3309
3310  vam->retval = retval;
3311  vam->result_ready = 1;
3312  vec_free (s);
3313}
3314
3315static void
3316api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3317{
3318  e->dp_table = clib_net_to_host_u32 (e->dp_table);
3319  e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3320  e->vni = clib_net_to_host_u32 (e->vni);
3321}
3322
3323static void
3324  gpe_fwd_entries_get_reply_t_net_to_host
3325  (vl_api_gpe_fwd_entries_get_reply_t * mp)
3326{
3327  u32 i;
3328
3329  mp->count = clib_net_to_host_u32 (mp->count);
3330  for (i = 0; i < mp->count; i++)
3331    {
3332      api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3333    }
3334}
3335
3336static u8 *
3337format_gpe_encap_mode (u8 * s, va_list * args)
3338{
3339  u32 mode = va_arg (*args, u32);
3340
3341  switch (mode)
3342    {
3343    case 0:
3344      return format (s, "lisp");
3345    case 1:
3346      return format (s, "vxlan");
3347    }
3348  return 0;
3349}
3350
3351static void
3352  vl_api_gpe_get_encap_mode_reply_t_handler
3353  (vl_api_gpe_get_encap_mode_reply_t * mp)
3354{
3355  vat_main_t *vam = &vat_main;
3356
3357  print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3358  vam->retval = ntohl (mp->retval);
3359  vam->result_ready = 1;
3360}
3361
3362static void
3363  vl_api_gpe_get_encap_mode_reply_t_handler_json
3364  (vl_api_gpe_get_encap_mode_reply_t * mp)
3365{
3366  vat_main_t *vam = &vat_main;
3367  vat_json_node_t node;
3368
3369  u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3370  vec_add1 (encap_mode, 0);
3371
3372  vat_json_init_object (&node);
3373  vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3374
3375  vec_free (encap_mode);
3376  vat_json_print (vam->ofp, &node);
3377  vat_json_free (&node);
3378
3379  vam->retval = ntohl (mp->retval);
3380  vam->result_ready = 1;
3381}
3382
3383static void
3384  vl_api_gpe_fwd_entry_path_details_t_handler
3385  (vl_api_gpe_fwd_entry_path_details_t * mp)
3386{
3387  vat_main_t *vam = &vat_main;
3388  u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3389
3390  if (mp->lcl_loc.addr.af)
3391    format_ip_address_fcn = format_ip6_address;
3392  else
3393    format_ip_address_fcn = format_ip4_address;
3394
3395  print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3396	 format_ip_address_fcn, &mp->lcl_loc.addr.un,
3397	 format_ip_address_fcn, &mp->rmt_loc.addr.un);
3398}
3399
3400static void
3401lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3402{
3403  struct in6_addr ip6;
3404  struct in_addr ip4;
3405
3406  if (loc->addr.af)
3407    {
3408      clib_memcpy (&ip6, loc->addr.un.ip6, sizeof (ip6));
3409      vat_json_object_add_ip6 (n, "address", ip6);
3410    }
3411  else
3412    {
3413      clib_memcpy (&ip4, loc->addr.un.ip4, sizeof (ip4));
3414      vat_json_object_add_ip4 (n, "address", ip4);
3415    }
3416  vat_json_object_add_uint (n, "weight", loc->weight);
3417}
3418
3419static void
3420  vl_api_gpe_fwd_entry_path_details_t_handler_json
3421  (vl_api_gpe_fwd_entry_path_details_t * mp)
3422{
3423  vat_main_t *vam = &vat_main;
3424  vat_json_node_t *node = NULL;
3425  vat_json_node_t *loc_node;
3426
3427  if (VAT_JSON_ARRAY != vam->json_tree.type)
3428    {
3429      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3430      vat_json_init_array (&vam->json_tree);
3431    }
3432  node = vat_json_array_add (&vam->json_tree);
3433  vat_json_init_object (node);
3434
3435  loc_node = vat_json_object_add (node, "local_locator");
3436  vat_json_init_object (loc_node);
3437  lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3438
3439  loc_node = vat_json_object_add (node, "remote_locator");
3440  vat_json_init_object (loc_node);
3441  lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3442}
3443
3444static void
3445  vl_api_gpe_fwd_entries_get_reply_t_handler
3446  (vl_api_gpe_fwd_entries_get_reply_t * mp)
3447{
3448  vat_main_t *vam = &vat_main;
3449  u32 i;
3450  int retval = clib_net_to_host_u32 (mp->retval);
3451  vl_api_gpe_fwd_entry_t *e;
3452
3453  if (retval)
3454    goto end;
3455
3456  gpe_fwd_entries_get_reply_t_net_to_host (mp);
3457
3458  for (i = 0; i < mp->count; i++)
3459    {
3460      e = &mp->entries[i];
3461      print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3462	     format_lisp_flat_eid, e->leid, format_lisp_flat_eid, e->reid);
3463    }
3464
3465end:
3466  vam->retval = retval;
3467  vam->result_ready = 1;
3468}
3469
3470static void
3471  vl_api_gpe_fwd_entries_get_reply_t_handler_json
3472  (vl_api_gpe_fwd_entries_get_reply_t * mp)
3473{
3474  u8 *s = 0;
3475  vat_main_t *vam = &vat_main;
3476  vat_json_node_t *e = 0, root;
3477  u32 i;
3478  int retval = clib_net_to_host_u32 (mp->retval);
3479  vl_api_gpe_fwd_entry_t *fwd;
3480
3481  if (retval)
3482    goto end;
3483
3484  gpe_fwd_entries_get_reply_t_net_to_host (mp);
3485  vat_json_init_array (&root);
3486
3487  for (i = 0; i < mp->count; i++)
3488    {
3489      e = vat_json_array_add (&root);
3490      fwd = &mp->entries[i];
3491
3492      vat_json_init_object (e);
3493      vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3494      vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3495      vat_json_object_add_int (e, "vni", fwd->vni);
3496      vat_json_object_add_int (e, "action", fwd->action);
3497
3498      s = format (0, "%U", format_lisp_flat_eid, fwd->leid);
3499      vec_add1 (s, 0);
3500      vat_json_object_add_string_copy (e, "leid", s);
3501      vec_free (s);
3502
3503      s = format (0, "%U", format_lisp_flat_eid, fwd->reid);
3504      vec_add1 (s, 0);
3505      vat_json_object_add_string_copy (e, "reid", s);
3506      vec_free (s);
3507    }
3508
3509  vat_json_print (vam->ofp, &root);
3510  vat_json_free (&root);
3511
3512end:
3513  vam->retval = retval;
3514  vam->result_ready = 1;
3515}
3516
3517static void
3518  vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3519  (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3520{
3521  vat_main_t *vam = &vat_main;
3522  u32 i, n;
3523  int retval = clib_net_to_host_u32 (mp->retval);
3524  vl_api_gpe_native_fwd_rpath_t *r;
3525
3526  if (retval)
3527    goto end;
3528
3529  n = clib_net_to_host_u32 (mp->count);
3530
3531  for (i = 0; i < n; i++)
3532    {
3533      r = &mp->entries[i];
3534      print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3535	     clib_net_to_host_u32 (r->fib_index),
3536	     clib_net_to_host_u32 (r->nh_sw_if_index),
3537	     r->nh_addr.af ? format_ip6_address : format_ip4_address,
3538	     r->nh_addr.un);
3539    }
3540
3541end:
3542  vam->retval = retval;
3543  vam->result_ready = 1;
3544}
3545
3546static void
3547  vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3548  (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3549{
3550  vat_main_t *vam = &vat_main;
3551  vat_json_node_t root, *e;
3552  u32 i, n;
3553  int retval = clib_net_to_host_u32 (mp->retval);
3554  vl_api_gpe_native_fwd_rpath_t *r;
3555  u8 *s;
3556
3557  if (retval)
3558    goto end;
3559
3560  n = clib_net_to_host_u32 (mp->count);
3561  vat_json_init_array (&root);
3562
3563  for (i = 0; i < n; i++)
3564    {
3565      e = vat_json_array_add (&root);
3566      vat_json_init_object (e);
3567      r = &mp->entries[i];
3568      s =
3569	format (0, "%U",
3570		r->nh_addr.af ? format_ip6_address : format_ip4_address,
3571		r->nh_addr.un);
3572      vec_add1 (s, 0);
3573      vat_json_object_add_string_copy (e, "ip4", s);
3574      vec_free (s);
3575
3576      vat_json_object_add_uint (e, "fib_index",
3577				clib_net_to_host_u32 (r->fib_index));
3578      vat_json_object_add_uint (e, "nh_sw_if_index",
3579				clib_net_to_host_u32 (r->nh_sw_if_index));
3580    }
3581
3582  vat_json_print (vam->ofp, &root);
3583  vat_json_free (&root);
3584
3585end:
3586  vam->retval = retval;
3587  vam->result_ready = 1;
3588}
3589
3590static void
3591  vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3592  (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3593{
3594  vat_main_t *vam = &vat_main;
3595  u32 i, n;
3596  int retval = clib_net_to_host_u32 (mp->retval);
3597
3598  if (retval)
3599    goto end;
3600
3601  n = clib_net_to_host_u32 (mp->count);
3602
3603  for (i = 0; i < n; i++)
3604    print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3605
3606end:
3607  vam->retval = retval;
3608  vam->result_ready = 1;
3609}
3610
3611static void
3612  vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3613  (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3614{
3615  vat_main_t *vam = &vat_main;
3616  vat_json_node_t root;
3617  u32 i, n;
3618  int retval = clib_net_to_host_u32 (mp->retval);
3619
3620  if (retval)
3621    goto end;
3622
3623  n = clib_net_to_host_u32 (mp->count);
3624  vat_json_init_array (&root);
3625
3626  for (i = 0; i < n; i++)
3627    vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3628
3629  vat_json_print (vam->ofp, &root);
3630  vat_json_free (&root);
3631
3632end:
3633  vam->retval = retval;
3634  vam->result_ready = 1;
3635}
3636
3637static void
3638  vl_api_one_ndp_entries_get_reply_t_handler
3639  (vl_api_one_ndp_entries_get_reply_t * mp)
3640{
3641  vat_main_t *vam = &vat_main;
3642  u32 i, n;
3643  int retval = clib_net_to_host_u32 (mp->retval);
3644
3645  if (retval)
3646    goto end;
3647
3648  n = clib_net_to_host_u32 (mp->count);
3649
3650  for (i = 0; i < n; i++)
3651    print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3652	   format_ethernet_address, mp->entries[i].mac);
3653
3654end:
3655  vam->retval = retval;
3656  vam->result_ready = 1;
3657}
3658
3659static void
3660  vl_api_one_ndp_entries_get_reply_t_handler_json
3661  (vl_api_one_ndp_entries_get_reply_t * mp)
3662{
3663  u8 *s = 0;
3664  vat_main_t *vam = &vat_main;
3665  vat_json_node_t *e = 0, root;
3666  u32 i, n;
3667  int retval = clib_net_to_host_u32 (mp->retval);
3668  vl_api_one_ndp_entry_t *arp_entry;
3669
3670  if (retval)
3671    goto end;
3672
3673  n = clib_net_to_host_u32 (mp->count);
3674  vat_json_init_array (&root);
3675
3676  for (i = 0; i < n; i++)
3677    {
3678      e = vat_json_array_add (&root);
3679      arp_entry = &mp->entries[i];
3680
3681      vat_json_init_object (e);
3682      s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3683      vec_add1 (s, 0);
3684
3685      vat_json_object_add_string_copy (e, "mac", s);
3686      vec_free (s);
3687
3688      s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3689      vec_add1 (s, 0);
3690      vat_json_object_add_string_copy (e, "ip6", s);
3691      vec_free (s);
3692    }
3693
3694  vat_json_print (vam->ofp, &root);
3695  vat_json_free (&root);
3696
3697end:
3698  vam->retval = retval;
3699  vam->result_ready = 1;
3700}
3701
3702static void
3703  vl_api_one_l2_arp_entries_get_reply_t_handler
3704  (vl_api_one_l2_arp_entries_get_reply_t * mp)
3705{
3706  vat_main_t *vam = &vat_main;
3707  u32 i, n;
3708  int retval = clib_net_to_host_u32 (mp->retval);
3709
3710  if (retval)
3711    goto end;
3712
3713  n = clib_net_to_host_u32 (mp->count);
3714
3715  for (i = 0; i < n; i++)
3716    print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3717	   format_ethernet_address, mp->entries[i].mac);
3718
3719end:
3720  vam->retval = retval;
3721  vam->result_ready = 1;
3722}
3723
3724static void
3725  vl_api_one_l2_arp_entries_get_reply_t_handler_json
3726  (vl_api_one_l2_arp_entries_get_reply_t * mp)
3727{
3728  u8 *s = 0;
3729  vat_main_t *vam = &vat_main;
3730  vat_json_node_t *e = 0, root;
3731  u32 i, n;
3732  int retval = clib_net_to_host_u32 (mp->retval);
3733  vl_api_one_l2_arp_entry_t *arp_entry;
3734
3735  if (retval)
3736    goto end;
3737
3738  n = clib_net_to_host_u32 (mp->count);
3739  vat_json_init_array (&root);
3740
3741  for (i = 0; i < n; i++)
3742    {
3743      e = vat_json_array_add (&root);
3744      arp_entry = &mp->entries[i];
3745
3746      vat_json_init_object (e);
3747      s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3748      vec_add1 (s, 0);
3749
3750      vat_json_object_add_string_copy (e, "mac", s);
3751      vec_free (s);
3752
3753      s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3754      vec_add1 (s, 0);
3755      vat_json_object_add_string_copy (e, "ip4", s);
3756      vec_free (s);
3757    }
3758
3759  vat_json_print (vam->ofp, &root);
3760  vat_json_free (&root);
3761
3762end:
3763  vam->retval = retval;
3764  vam->result_ready = 1;
3765}
3766
3767static void
3768vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3769{
3770  vat_main_t *vam = &vat_main;
3771  u32 i, n;
3772  int retval = clib_net_to_host_u32 (mp->retval);
3773
3774  if (retval)
3775    goto end;
3776
3777  n = clib_net_to_host_u32 (mp->count);
3778
3779  for (i = 0; i < n; i++)
3780    {
3781      print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3782    }
3783
3784end:
3785  vam->retval = retval;
3786  vam->result_ready = 1;
3787}
3788
3789static void
3790  vl_api_one_ndp_bd_get_reply_t_handler_json
3791  (vl_api_one_ndp_bd_get_reply_t * mp)
3792{
3793  vat_main_t *vam = &vat_main;
3794  vat_json_node_t root;
3795  u32 i, n;
3796  int retval = clib_net_to_host_u32 (mp->retval);
3797
3798  if (retval)
3799    goto end;
3800
3801  n = clib_net_to_host_u32 (mp->count);
3802  vat_json_init_array (&root);
3803
3804  for (i = 0; i < n; i++)
3805    {
3806      vat_json_array_add_uint (&root,
3807			       clib_net_to_host_u32 (mp->bridge_domains[i]));
3808    }
3809
3810  vat_json_print (vam->ofp, &root);
3811  vat_json_free (&root);
3812
3813end:
3814  vam->retval = retval;
3815  vam->result_ready = 1;
3816}
3817
3818static void
3819  vl_api_one_l2_arp_bd_get_reply_t_handler
3820  (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821{
3822  vat_main_t *vam = &vat_main;
3823  u32 i, n;
3824  int retval = clib_net_to_host_u32 (mp->retval);
3825
3826  if (retval)
3827    goto end;
3828
3829  n = clib_net_to_host_u32 (mp->count);
3830
3831  for (i = 0; i < n; i++)
3832    {
3833      print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3834    }
3835
3836end:
3837  vam->retval = retval;
3838  vam->result_ready = 1;
3839}
3840
3841static void
3842  vl_api_one_l2_arp_bd_get_reply_t_handler_json
3843  (vl_api_one_l2_arp_bd_get_reply_t * mp)
3844{
3845  vat_main_t *vam = &vat_main;
3846  vat_json_node_t root;
3847  u32 i, n;
3848  int retval = clib_net_to_host_u32 (mp->retval);
3849
3850  if (retval)
3851    goto end;
3852
3853  n = clib_net_to_host_u32 (mp->count);
3854  vat_json_init_array (&root);
3855
3856  for (i = 0; i < n; i++)
3857    {
3858      vat_json_array_add_uint (&root,
3859			       clib_net_to_host_u32 (mp->bridge_domains[i]));
3860    }
3861
3862  vat_json_print (vam->ofp, &root);
3863  vat_json_free (&root);
3864
3865end:
3866  vam->retval = retval;
3867  vam->result_ready = 1;
3868}
3869
3870static void
3871  vl_api_one_adjacencies_get_reply_t_handler
3872  (vl_api_one_adjacencies_get_reply_t * mp)
3873{
3874  vat_main_t *vam = &vat_main;
3875  u32 i, n;
3876  int retval = clib_net_to_host_u32 (mp->retval);
3877  vl_api_one_adjacency_t *a;
3878
3879  if (retval)
3880    goto end;
3881
3882  n = clib_net_to_host_u32 (mp->count);
3883
3884  for (i = 0; i < n; i++)
3885    {
3886      a = &mp->adjacencies[i];
3887      print (vam->ofp, "%U %40U",
3888	     format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
3889    }
3890
3891end:
3892  vam->retval = retval;
3893  vam->result_ready = 1;
3894}
3895
3896static void
3897  vl_api_one_adjacencies_get_reply_t_handler_json
3898  (vl_api_one_adjacencies_get_reply_t * mp)
3899{
3900  u8 *s = 0;
3901  vat_main_t *vam = &vat_main;
3902  vat_json_node_t *e = 0, root;
3903  u32 i, n;
3904  int retval = clib_net_to_host_u32 (mp->retval);
3905  vl_api_one_adjacency_t *a;
3906
3907  if (retval)
3908    goto end;
3909
3910  n = clib_net_to_host_u32 (mp->count);
3911  vat_json_init_array (&root);
3912
3913  for (i = 0; i < n; i++)
3914    {
3915      e = vat_json_array_add (&root);
3916      a = &mp->adjacencies[i];
3917
3918      vat_json_init_object (e);
3919      s = format (0, "%U", format_lisp_flat_eid, a->leid);
3920      vec_add1 (s, 0);
3921      vat_json_object_add_string_copy (e, "leid", s);
3922      vec_free (s);
3923
3924      s = format (0, "%U", format_lisp_flat_eid, a->reid);
3925      vec_add1 (s, 0);
3926      vat_json_object_add_string_copy (e, "reid", s);
3927      vec_free (s);
3928    }
3929
3930  vat_json_print (vam->ofp, &root);
3931  vat_json_free (&root);
3932
3933end:
3934  vam->retval = retval;
3935  vam->result_ready = 1;
3936}
3937
3938static void
3939vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3940{
3941  vat_main_t *vam = &vat_main;
3942
3943  print (vam->ofp, "%=20U",
3944	 mp->ip_address.af ? format_ip6_address : format_ip4_address,
3945	 mp->ip_address.un);
3946}
3947
3948static void
3949  vl_api_one_map_server_details_t_handler_json
3950  (vl_api_one_map_server_details_t * mp)
3951{
3952  vat_main_t *vam = &vat_main;
3953  vat_json_node_t *node = NULL;
3954  struct in6_addr ip6;
3955  struct in_addr ip4;
3956
3957  if (VAT_JSON_ARRAY != vam->json_tree.type)
3958    {
3959      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3960      vat_json_init_array (&vam->json_tree);
3961    }
3962  node = vat_json_array_add (&vam->json_tree);
3963
3964  vat_json_init_object (node);
3965  if (mp->ip_address.af)
3966    {
3967      clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
3968      vat_json_object_add_ip6 (node, "map-server", ip6);
3969    }
3970  else
3971    {
3972      clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
3973      vat_json_object_add_ip4 (node, "map-server", ip4);
3974    }
3975}
3976
3977static void
3978vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3979					   * mp)
3980{
3981  vat_main_t *vam = &vat_main;
3982
3983  print (vam->ofp, "%=20U",
3984	 mp->ip_address.af ? format_ip6_address : format_ip4_address,
3985	 mp->ip_address.un);
3986}
3987
3988static void
3989  vl_api_one_map_resolver_details_t_handler_json
3990  (vl_api_one_map_resolver_details_t * mp)
3991{
3992  vat_main_t *vam = &vat_main;
3993  vat_json_node_t *node = NULL;
3994  struct in6_addr ip6;
3995  struct in_addr ip4;
3996
3997  if (VAT_JSON_ARRAY != vam->json_tree.type)
3998    {
3999      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4000      vat_json_init_array (&vam->json_tree);
4001    }
4002  node = vat_json_array_add (&vam->json_tree);
4003
4004  vat_json_init_object (node);
4005  if (mp->ip_address.af)
4006    {
4007      clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4008      vat_json_object_add_ip6 (node, "map resolver", ip6);
4009    }
4010  else
4011    {
4012      clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4013      vat_json_object_add_ip4 (node, "map resolver", ip4);
4014    }
4015}
4016
4017static void
4018vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4019{
4020  vat_main_t *vam = &vat_main;
4021  i32 retval = ntohl (mp->retval);
4022
4023  if (0 <= retval)
4024    {
4025      print (vam->ofp, "feature: %s\ngpe: %s",
4026	     mp->feature_status ? "enabled" : "disabled",
4027	     mp->gpe_status ? "enabled" : "disabled");
4028    }
4029
4030  vam->retval = retval;
4031  vam->result_ready = 1;
4032}
4033
4034static void
4035  vl_api_show_one_status_reply_t_handler_json
4036  (vl_api_show_one_status_reply_t * mp)
4037{
4038  vat_main_t *vam = &vat_main;
4039  vat_json_node_t node;
4040  u8 *gpe_status = NULL;
4041  u8 *feature_status = NULL;
4042
4043  gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4044  feature_status = format (0, "%s",
4045			   mp->feature_status ? "enabled" : "disabled");
4046  vec_add1 (gpe_status, 0);
4047  vec_add1 (feature_status, 0);
4048
4049  vat_json_init_object (&node);
4050  vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4051  vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4052
4053  vec_free (gpe_status);
4054  vec_free (feature_status);
4055
4056  vat_json_print (vam->ofp, &node);
4057  vat_json_free (&node);
4058
4059  vam->retval = ntohl (mp->retval);
4060  vam->result_ready = 1;
4061}
4062
4063static void
4064  vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4065  (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4066{
4067  vat_main_t *vam = &vat_main;
4068  i32 retval = ntohl (mp->retval);
4069
4070  if (retval >= 0)
4071    {
4072      print (vam->ofp, "%=20s", mp->locator_set_name);
4073    }
4074
4075  vam->retval = retval;
4076  vam->result_ready = 1;
4077}
4078
4079static void
4080  vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4081  (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4082{
4083  vat_main_t *vam = &vat_main;
4084  vat_json_node_t *node = NULL;
4085
4086  if (VAT_JSON_ARRAY != vam->json_tree.type)
4087    {
4088      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4089      vat_json_init_array (&vam->json_tree);
4090    }
4091  node = vat_json_array_add (&vam->json_tree);
4092
4093  vat_json_init_object (node);
4094  vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4095
4096  vat_json_print (vam->ofp, node);
4097  vat_json_free (node);
4098
4099  vam->retval = ntohl (mp->retval);
4100  vam->result_ready = 1;
4101}
4102
4103static u8 *
4104format_lisp_map_request_mode (u8 * s, va_list * args)
4105{
4106  u32 mode = va_arg (*args, u32);
4107
4108  switch (mode)
4109    {
4110    case 0:
4111      return format (0, "dst-only");
4112    case 1:
4113      return format (0, "src-dst");
4114    }
4115  return 0;
4116}
4117
4118static void
4119  vl_api_show_one_map_request_mode_reply_t_handler
4120  (vl_api_show_one_map_request_mode_reply_t * mp)
4121{
4122  vat_main_t *vam = &vat_main;
4123  i32 retval = ntohl (mp->retval);
4124
4125  if (0 <= retval)
4126    {
4127      u32 mode = mp->mode;
4128      print (vam->ofp, "map_request_mode: %U",
4129	     format_lisp_map_request_mode, mode);
4130    }
4131
4132  vam->retval = retval;
4133  vam->result_ready = 1;
4134}
4135
4136static void
4137  vl_api_show_one_map_request_mode_reply_t_handler_json
4138  (vl_api_show_one_map_request_mode_reply_t * mp)
4139{
4140  vat_main_t *vam = &vat_main;
4141  vat_json_node_t node;
4142  u8 *s = 0;
4143  u32 mode;
4144
4145  mode = mp->mode;
4146  s = format (0, "%U", format_lisp_map_request_mode, mode);
4147  vec_add1 (s, 0);
4148
4149  vat_json_init_object (&node);
4150  vat_json_object_add_string_copy (&node, "map_request_mode", s);
4151  vat_json_print (vam->ofp, &node);
4152  vat_json_free (&node);
4153
4154  vec_free (s);
4155  vam->retval = ntohl (mp->retval);
4156  vam->result_ready = 1;
4157}
4158
4159static void
4160  vl_api_one_show_xtr_mode_reply_t_handler
4161  (vl_api_one_show_xtr_mode_reply_t * mp)
4162{
4163  vat_main_t *vam = &vat_main;
4164  i32 retval = ntohl (mp->retval);
4165
4166  if (0 <= retval)
4167    {
4168      print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4169    }
4170
4171  vam->retval = retval;
4172  vam->result_ready = 1;
4173}
4174
4175static void
4176  vl_api_one_show_xtr_mode_reply_t_handler_json
4177  (vl_api_one_show_xtr_mode_reply_t * mp)
4178{
4179  vat_main_t *vam = &vat_main;
4180  vat_json_node_t node;
4181  u8 *status = 0;
4182
4183  status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4184  vec_add1 (status, 0);
4185
4186  vat_json_init_object (&node);
4187  vat_json_object_add_string_copy (&node, "status", status);
4188
4189  vec_free (status);
4190
4191  vat_json_print (vam->ofp, &node);
4192  vat_json_free (&node);
4193
4194  vam->retval = ntohl (mp->retval);
4195  vam->result_ready = 1;
4196}
4197
4198static void
4199  vl_api_one_show_pitr_mode_reply_t_handler
4200  (vl_api_one_show_pitr_mode_reply_t * mp)
4201{
4202  vat_main_t *vam = &vat_main;
4203  i32 retval = ntohl (mp->retval);
4204
4205  if (0 <= retval)
4206    {
4207      print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4208    }
4209
4210  vam->retval = retval;
4211  vam->result_ready = 1;
4212}
4213
4214static void
4215  vl_api_one_show_pitr_mode_reply_t_handler_json
4216  (vl_api_one_show_pitr_mode_reply_t * mp)
4217{
4218  vat_main_t *vam = &vat_main;
4219  vat_json_node_t node;
4220  u8 *status = 0;
4221
4222  status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4223  vec_add1 (status, 0);
4224
4225  vat_json_init_object (&node);
4226  vat_json_object_add_string_copy (&node, "status", status);
4227
4228  vec_free (status);
4229
4230  vat_json_print (vam->ofp, &node);
4231  vat_json_free (&node);
4232
4233  vam->retval = ntohl (mp->retval);
4234  vam->result_ready = 1;
4235}
4236
4237static void
4238  vl_api_one_show_petr_mode_reply_t_handler
4239  (vl_api_one_show_petr_mode_reply_t * mp)
4240{
4241  vat_main_t *vam = &vat_main;
4242  i32 retval = ntohl (mp->retval);
4243
4244  if (0 <= retval)
4245    {
4246      print (vam->ofp, "%s\n", mp->is_enable ? "enabled" : "disabled");
4247    }
4248
4249  vam->retval = retval;
4250  vam->result_ready = 1;
4251}
4252
4253static void
4254  vl_api_one_show_petr_mode_reply_t_handler_json
4255  (vl_api_one_show_petr_mode_reply_t * mp)
4256{
4257  vat_main_t *vam = &vat_main;
4258  vat_json_node_t node;
4259  u8 *status = 0;
4260
4261  status = format (0, "%s", mp->is_enable ? "enabled" : "disabled");
4262  vec_add1 (status, 0);
4263
4264  vat_json_init_object (&node);
4265  vat_json_object_add_string_copy (&node, "status", status);
4266
4267  vec_free (status);
4268
4269  vat_json_print (vam->ofp, &node);
4270  vat_json_free (&node);
4271
4272  vam->retval = ntohl (mp->retval);
4273  vam->result_ready = 1;
4274}
4275
4276static void
4277  vl_api_show_one_use_petr_reply_t_handler
4278  (vl_api_show_one_use_petr_reply_t * mp)
4279{
4280  vat_main_t *vam = &vat_main;
4281  i32 retval = ntohl (mp->retval);
4282
4283  if (0 <= retval)
4284    {
4285      print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4286      if (mp->status)
4287	{
4288	  print (vam->ofp, "Proxy-ETR address; %U",
4289		 mp->ip_address.af ? format_ip6_address : format_ip4_address,
4290		 mp->ip_address.un);
4291	}
4292    }
4293
4294  vam->retval = retval;
4295  vam->result_ready = 1;
4296}
4297
4298static void
4299  vl_api_show_one_use_petr_reply_t_handler_json
4300  (vl_api_show_one_use_petr_reply_t * mp)
4301{
4302  vat_main_t *vam = &vat_main;
4303  vat_json_node_t node;
4304  u8 *status = 0;
4305  struct in_addr ip4;
4306  struct in6_addr ip6;
4307
4308  status = format (0, "%s", mp->status ? "enabled" : "disabled");
4309  vec_add1 (status, 0);
4310
4311  vat_json_init_object (&node);
4312  vat_json_object_add_string_copy (&node, "status", status);
4313  if (mp->status)
4314    {
4315      if (mp->ip_address.af)
4316	{
4317	  clib_memcpy (&ip6, mp->ip_address.un.ip6, sizeof (ip6));
4318	  vat_json_object_add_ip6 (&node, "address", ip6);
4319	}
4320      else
4321	{
4322	  clib_memcpy (&ip4, mp->ip_address.un.ip4, sizeof (ip4));
4323	  vat_json_object_add_ip4 (&node, "address", ip4);
4324	}
4325    }
4326
4327  vec_free (status);
4328
4329  vat_json_print (vam->ofp, &node);
4330  vat_json_free (&node);
4331
4332  vam->retval = ntohl (mp->retval);
4333  vam->result_ready = 1;
4334}
4335
4336static void
4337  vl_api_show_one_nsh_mapping_reply_t_handler
4338  (vl_api_show_one_nsh_mapping_reply_t * mp)
4339{
4340  vat_main_t *vam = &vat_main;
4341  i32 retval = ntohl (mp->retval);
4342
4343  if (0 <= retval)
4344    {
4345      print (vam->ofp, "%-20s%-16s",
4346	     mp->is_set ? "set" : "not-set",
4347	     mp->is_set ? (char *) mp->locator_set_name : "");
4348    }
4349
4350  vam->retval = retval;
4351  vam->result_ready = 1;
4352}
4353
4354static void
4355  vl_api_show_one_nsh_mapping_reply_t_handler_json
4356  (vl_api_show_one_nsh_mapping_reply_t * mp)
4357{
4358  vat_main_t *vam = &vat_main;
4359  vat_json_node_t node;
4360  u8 *status = 0;
4361
4362  status = format (0, "%s", mp->is_set ? "yes" : "no");
4363  vec_add1 (status, 0);
4364
4365  vat_json_init_object (&node);
4366  vat_json_object_add_string_copy (&node, "is_set", status);
4367  if (mp->is_set)
4368    {
4369      vat_json_object_add_string_copy (&node, "locator_set",
4370				       mp->locator_set_name);
4371    }
4372
4373  vec_free (status);
4374
4375  vat_json_print (vam->ofp, &node);
4376  vat_json_free (&node);
4377
4378  vam->retval = ntohl (mp->retval);
4379  vam->result_ready = 1;
4380}
4381
4382static void
4383  vl_api_show_one_map_register_ttl_reply_t_handler
4384  (vl_api_show_one_map_register_ttl_reply_t * mp)
4385{
4386  vat_main_t *vam = &vat_main;
4387  i32 retval = ntohl (mp->retval);
4388
4389  vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4390
4391  if (0 <= retval)
4392    {
4393      print (vam->ofp, "ttl: %u", mp->ttl);
4394    }
4395
4396  vam->retval = retval;
4397  vam->result_ready = 1;
4398}
4399
4400static void
4401  vl_api_show_one_map_register_ttl_reply_t_handler_json
4402  (vl_api_show_one_map_register_ttl_reply_t * mp)
4403{
4404  vat_main_t *vam = &vat_main;
4405  vat_json_node_t node;
4406
4407  vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4408  vat_json_init_object (&node);
4409  vat_json_object_add_uint (&node, "ttl", mp->ttl);
4410
4411  vat_json_print (vam->ofp, &node);
4412  vat_json_free (&node);
4413
4414  vam->retval = ntohl (mp->retval);
4415  vam->result_ready = 1;
4416}
4417
4418static void
4419vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4420{
4421  vat_main_t *vam = &vat_main;
4422  i32 retval = ntohl (mp->retval);
4423
4424  if (0 <= retval)
4425    {
4426      print (vam->ofp, "%-20s%-16s",
4427	     mp->status ? "enabled" : "disabled",
4428	     mp->status ? (char *) mp->locator_set_name : "");
4429    }
4430
4431  vam->retval = retval;
4432  vam->result_ready = 1;
4433}
4434
4435static void
4436vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4437{
4438  vat_main_t *vam = &vat_main;
4439  vat_json_node_t node;
4440  u8 *status = 0;
4441
4442  status = format (0, "%s", mp->status ? "enabled" : "disabled");
4443  vec_add1 (status, 0);
4444
4445  vat_json_init_object (&node);
4446  vat_json_object_add_string_copy (&node, "status", status);
4447  if (mp->status)
4448    {
4449      vat_json_object_add_string_copy (&node, "locator_set",
4450				       mp->locator_set_name);
4451    }
4452
4453  vec_free (status);
4454
4455  vat_json_print (vam->ofp, &node);
4456  vat_json_free (&node);
4457
4458  vam->retval = ntohl (mp->retval);
4459  vam->result_ready = 1;
4460}
4461
4462static u8 *
4463format_policer_type (u8 * s, va_list * va)
4464{
4465  u32 i = va_arg (*va, u32);
4466
4467  if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4468    s = format (s, "1r2c");
4469  else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4470    s = format (s, "1r3c");
4471  else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4472    s = format (s, "2r3c-2698");
4473  else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4474    s = format (s, "2r3c-4115");
4475  else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4476    s = format (s, "2r3c-mef5cf1");
4477  else
4478    s = format (s, "ILLEGAL");
4479  return s;
4480}
4481
4482static u8 *
4483format_policer_rate_type (u8 * s, va_list * va)
4484{
4485  u32 i = va_arg (*va, u32);
4486
4487  if (i == SSE2_QOS_RATE_KBPS)
4488    s = format (s, "kbps");
4489  else if (i == SSE2_QOS_RATE_PPS)
4490    s = format (s, "pps");
4491  else
4492    s = format (s, "ILLEGAL");
4493  return s;
4494}
4495
4496static u8 *
4497format_policer_round_type (u8 * s, va_list * va)
4498{
4499  u32 i = va_arg (*va, u32);
4500
4501  if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4502    s = format (s, "closest");
4503  else if (i == SSE2_QOS_ROUND_TO_UP)
4504    s = format (s, "up");
4505  else if (i == SSE2_QOS_ROUND_TO_DOWN)
4506    s = format (s, "down");
4507  else
4508    s = format (s, "ILLEGAL");
4509  return s;
4510}
4511
4512static u8 *
4513format_policer_action_type (u8 * s, va_list * va)
4514{
4515  u32 i = va_arg (*va, u32);
4516
4517  if (i == SSE2_QOS_ACTION_DROP)
4518    s = format (s, "drop");
4519  else if (i == SSE2_QOS_ACTION_TRANSMIT)
4520    s = format (s, "transmit");
4521  else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4522    s = format (s, "mark-and-transmit");
4523  else
4524    s = format (s, "ILLEGAL");
4525  return s;
4526}
4527
4528static u8 *
4529format_dscp (u8 * s, va_list * va)
4530{
4531  u32 i = va_arg (*va, u32);
4532  char *t = 0;
4533
4534  switch (i)
4535    {
4536#define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4537      foreach_vnet_dscp
4538#undef _
4539    default:
4540      return format (s, "ILLEGAL");
4541    }
4542  s = format (s, "%s", t);
4543  return s;
4544}
4545
4546static void
4547vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4548{
4549  vat_main_t *vam = &vat_main;
4550  u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4551
4552  if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4553    conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4554  else
4555    conform_dscp_str = format (0, "");
4556
4557  if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4558    exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4559  else
4560    exceed_dscp_str = format (0, "");
4561
4562  if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4563    violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4564  else
4565    violate_dscp_str = format (0, "");
4566
4567  print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4568	 "rate type %U, round type %U, %s rate, %s color-aware, "
4569	 "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4570	 "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4571	 "conform action %U%s, exceed action %U%s, violate action %U%s",
4572	 mp->name,
4573	 format_policer_type, mp->type,
4574	 ntohl (mp->cir),
4575	 ntohl (mp->eir),
4576	 clib_net_to_host_u64 (mp->cb),
4577	 clib_net_to_host_u64 (mp->eb),
4578	 format_policer_rate_type, mp->rate_type,
4579	 format_policer_round_type, mp->round_type,
4580	 mp->single_rate ? "single" : "dual",
4581	 mp->color_aware ? "is" : "not",
4582	 ntohl (mp->cir_tokens_per_period),
4583	 ntohl (mp->pir_tokens_per_period),
4584	 ntohl (mp->scale),
4585	 ntohl (mp->current_limit),
4586	 ntohl (mp->current_bucket),
4587	 ntohl (mp->extended_limit),
4588	 ntohl (mp->extended_bucket),
4589	 clib_net_to_host_u64 (mp->last_update_time),
4590	 format_policer_action_type, mp->conform_action.type,
4591	 conform_dscp_str,
4592	 format_policer_action_type, mp->exceed_action.type,
4593	 exceed_dscp_str,
4594	 format_policer_action_type, mp->violate_action.type,
4595	 violate_dscp_str);
4596
4597  vec_free (conform_dscp_str);
4598  vec_free (exceed_dscp_str);
4599  vec_free (violate_dscp_str);
4600}
4601
4602static void vl_api_policer_details_t_handler_json
4603  (vl_api_policer_details_t * mp)
4604{
4605  vat_main_t *vam = &vat_main;
4606  vat_json_node_t *node;
4607  u8 *rate_type_str, *round_type_str, *type_str;
4608  u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4609
4610  rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4611  round_type_str =
4612    format (0, "%U", format_policer_round_type, mp->round_type);
4613  type_str = format (0, "%U", format_policer_type, mp->type);
4614  conform_action_str = format (0, "%U", format_policer_action_type,
4615			       mp->conform_action.type);
4616  exceed_action_str = format (0, "%U", format_policer_action_type,
4617			      mp->exceed_action.type);
4618  violate_action_str = format (0, "%U", format_policer_action_type,
4619			       mp->violate_action.type);
4620
4621  if (VAT_JSON_ARRAY != vam->json_tree.type)
4622    {
4623      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4624      vat_json_init_array (&vam->json_tree);
4625    }
4626  node = vat_json_array_add (&vam->json_tree);
4627
4628  vat_json_init_object (node);
4629  vat_json_object_add_string_copy (node, "name", mp->name);
4630  vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4631  vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4632  vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4633  vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4634  vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4635  vat_json_object_add_string_copy (node, "round_type", round_type_str);
4636  vat_json_object_add_string_copy (node, "type", type_str);
4637  vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4638  vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4639  vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4640  vat_json_object_add_uint (node, "cir_tokens_per_period",
4641			    ntohl (mp->cir_tokens_per_period));
4642  vat_json_object_add_uint (node, "eir_tokens_per_period",
4643			    ntohl (mp->pir_tokens_per_period));
4644  vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4645  vat_json_object_add_uint (node, "current_bucket",
4646			    ntohl (mp->current_bucket));
4647  vat_json_object_add_uint (node, "extended_limit",
4648			    ntohl (mp->extended_limit));
4649  vat_json_object_add_uint (node, "extended_bucket",
4650			    ntohl (mp->extended_bucket));
4651  vat_json_object_add_uint (node, "last_update_time",
4652			    ntohl (mp->last_update_time));
4653  vat_json_object_add_string_copy (node, "conform_action",
4654				   conform_action_str);
4655  if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4656    {
4657      u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
4658      vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4659      vec_free (dscp_str);
4660    }
4661  vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4662  if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4663    {
4664      u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
4665      vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4666      vec_free (dscp_str);
4667    }
4668  vat_json_object_add_string_copy (node, "violate_action",
4669				   violate_action_str);
4670  if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
4671    {
4672      u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
4673      vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4674      vec_free (dscp_str);
4675    }
4676
4677  vec_free (rate_type_str);
4678  vec_free (round_type_str);
4679  vec_free (type_str);
4680  vec_free (conform_action_str);
4681  vec_free (exceed_action_str);
4682  vec_free (violate_action_str);
4683}
4684
4685static void
4686vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4687					   mp)
4688{
4689  vat_main_t *vam = &vat_main;
4690  int i, count = ntohl (mp->count);
4691
4692  if (count > 0)
4693    print (vam->ofp, "classify table ids (%d) : ", count);
4694  for (i = 0; i < count; i++)
4695    {
4696      print (vam->ofp, "%d", ntohl (mp->ids[i]));
4697      print (vam->ofp, (i < count - 1) ? "," : "");
4698    }
4699  vam->retval = ntohl (mp->retval);
4700  vam->result_ready = 1;
4701}
4702
4703static void
4704  vl_api_classify_table_ids_reply_t_handler_json
4705  (vl_api_classify_table_ids_reply_t * mp)
4706{
4707  vat_main_t *vam = &vat_main;
4708  int i, count = ntohl (mp->count);
4709
4710  if (count > 0)
4711    {
4712      vat_json_node_t node;
4713
4714      vat_json_init_object (&node);
4715      for (i = 0; i < count; i++)
4716	{
4717	  vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4718	}
4719      vat_json_print (vam->ofp, &node);
4720      vat_json_free (&node);
4721    }
4722  vam->retval = ntohl (mp->retval);
4723  vam->result_ready = 1;
4724}
4725
4726static void
4727  vl_api_classify_table_by_interface_reply_t_handler
4728  (vl_api_classify_table_by_interface_reply_t * mp)
4729{
4730  vat_main_t *vam = &vat_main;
4731  u32 table_id;
4732
4733  table_id = ntohl (mp->l2_table_id);
4734  if (table_id != ~0)
4735    print (vam->ofp, "l2 table id : %d", table_id);
4736  else
4737    print (vam->ofp, "l2 table id : No input ACL tables configured");
4738  table_id = ntohl (mp->ip4_table_id);
4739  if (table_id != ~0)
4740    print (vam->ofp, "ip4 table id : %d", table_id);
4741  else
4742    print (vam->ofp, "ip4 table id : No input ACL tables configured");
4743  table_id = ntohl (mp->ip6_table_id);
4744  if (table_id != ~0)
4745    print (vam->ofp, "ip6 table id : %d", table_id);
4746  else
4747    print (vam->ofp, "ip6 table id : No input ACL tables configured");
4748  vam->retval = ntohl (mp->retval);
4749  vam->result_ready = 1;
4750}
4751
4752static void
4753  vl_api_classify_table_by_interface_reply_t_handler_json
4754  (vl_api_classify_table_by_interface_reply_t * mp)
4755{
4756  vat_main_t *vam = &vat_main;
4757  vat_json_node_t node;
4758
4759  vat_json_init_object (&node);
4760
4761  vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4762  vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4763  vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4764
4765  vat_json_print (vam->ofp, &node);
4766  vat_json_free (&node);
4767
4768  vam->retval = ntohl (mp->retval);
4769  vam->result_ready = 1;
4770}
4771
4772static void vl_api_policer_add_del_reply_t_handler
4773  (vl_api_policer_add_del_reply_t * mp)
4774{
4775  vat_main_t *vam = &vat_main;
4776  i32 retval = ntohl (mp->retval);
4777  if (vam->async_mode)
4778    {
4779      vam->async_errors += (retval < 0);
4780    }
4781  else
4782    {
4783      vam->retval = retval;
4784      vam->result_ready = 1;
4785      if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4786	/*
4787	 * Note: this is just barely thread-safe, depends on
4788	 * the main thread spinning waiting for an answer...
4789	 */
4790	errmsg ("policer index %d", ntohl (mp->policer_index));
4791    }
4792}
4793
4794static void vl_api_policer_add_del_reply_t_handler_json
4795  (vl_api_policer_add_del_reply_t * mp)
4796{
4797  vat_main_t *vam = &vat_main;
4798  vat_json_node_t node;
4799
4800  vat_json_init_object (&node);
4801  vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4802  vat_json_object_add_uint (&node, "policer_index",
4803			    ntohl (mp->policer_index));
4804
4805  vat_json_print (vam->ofp, &node);
4806  vat_json_free (&node);
4807
4808  vam->retval = ntohl (mp->retval);
4809  vam->result_ready = 1;
4810}
4811
4812/* Format hex dump. */
4813u8 *
4814format_hex_bytes (u8 * s, va_list * va)
4815{
4816  u8 *bytes = va_arg (*va, u8 *);
4817  int n_bytes = va_arg (*va, int);
4818  uword i;
4819
4820  /* Print short or long form depending on byte count. */
4821  uword short_form = n_bytes <= 32;
4822  u32 indent = format_get_indent (s);
4823
4824  if (n_bytes == 0)
4825    return s;
4826
4827  for (i = 0; i < n_bytes; i++)
4828    {
4829      if (!short_form && (i % 32) == 0)
4830	s = format (s, "%08x: ", i);
4831      s = format (s, "%02x", bytes[i]);
4832      if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4833	s = format (s, "\n%U", format_white_space, indent);
4834    }
4835
4836  return s;
4837}
4838
4839static void
4840vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4841					    * mp)
4842{
4843  vat_main_t *vam = &vat_main;
4844  i32 retval = ntohl (mp->retval);
4845  if (retval == 0)
4846    {
4847      print (vam->ofp, "classify table info :");
4848      print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4849	     ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4850	     ntohl (mp->miss_next_index));
4851      print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4852	     ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4853	     ntohl (mp->match_n_vectors));
4854      print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4855	     ntohl (mp->mask_length));
4856    }
4857  vam->retval = retval;
4858  vam->result_ready = 1;
4859}
4860
4861static void
4862  vl_api_classify_table_info_reply_t_handler_json
4863  (vl_api_classify_table_info_reply_t * mp)
4864{
4865  vat_main_t *vam = &vat_main;
4866  vat_json_node_t node;
4867
4868  i32 retval = ntohl (mp->retval);
4869  if (retval == 0)
4870    {
4871      vat_json_init_object (&node);
4872
4873      vat_json_object_add_int (&node, "sessions",
4874			       ntohl (mp->active_sessions));
4875      vat_json_object_add_int (&node, "nexttbl",
4876			       ntohl (mp->next_table_index));
4877      vat_json_object_add_int (&node, "nextnode",
4878			       ntohl (mp->miss_next_index));
4879      vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4880      vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4881      vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4882      u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4883		      ntohl (mp->mask_length), 0);
4884      vat_json_object_add_string_copy (&node, "mask", s);
4885
4886      vat_json_print (vam->ofp, &node);
4887      vat_json_free (&node);
4888    }
4889  vam->retval = ntohl (mp->retval);
4890  vam->result_ready = 1;
4891}
4892
4893static void
4894vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4895					   mp)
4896{
4897  vat_main_t *vam = &vat_main;
4898
4899  print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4900	 ntohl (mp->hit_next_index), ntohl (mp->advance),
4901	 ntohl (mp->opaque_index));
4902  print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4903	 ntohl (mp->match_length));
4904}
4905
4906static void
4907  vl_api_classify_session_details_t_handler_json
4908  (vl_api_classify_session_details_t * mp)
4909{
4910  vat_main_t *vam = &vat_main;
4911  vat_json_node_t *node = NULL;
4912
4913  if (VAT_JSON_ARRAY != vam->json_tree.type)
4914    {
4915      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4916      vat_json_init_array (&vam->json_tree);
4917    }
4918  node = vat_json_array_add (&vam->json_tree);
4919
4920  vat_json_init_object (node);
4921  vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4922  vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4923  vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4924  u8 *s =
4925    format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4926	    0);
4927  vat_json_object_add_string_copy (node, "match", s);
4928}
4929
4930static void vl_api_pg_create_interface_reply_t_handler
4931  (vl_api_pg_create_interface_reply_t * mp)
4932{
4933  vat_main_t *vam = &vat_main;
4934
4935  vam->retval = ntohl (mp->retval);
4936  vam->result_ready = 1;
4937}
4938
4939static void vl_api_pg_create_interface_reply_t_handler_json
4940  (vl_api_pg_create_interface_reply_t * mp)
4941{
4942  vat_main_t *vam = &vat_main;
4943  vat_json_node_t node;
4944
4945  i32 retval = ntohl (mp->retval);
4946  if (retval == 0)
4947    {
4948      vat_json_init_object (&node);
4949
4950      vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4951
4952      vat_json_print (vam->ofp, &node);
4953      vat_json_free (&node);
4954    }
4955  vam->retval = ntohl (mp->retval);
4956  vam->result_ready = 1;
4957}
4958
4959static void vl_api_policer_classify_details_t_handler
4960  (vl_api_policer_classify_details_t * mp)
4961{
4962  vat_main_t *vam = &vat_main;
4963
4964  print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4965	 ntohl (mp->table_index));
4966}
4967
4968static void vl_api_policer_classify_details_t_handler_json
4969  (vl_api_policer_classify_details_t * mp)
4970{
4971  vat_main_t *vam = &vat_main;
4972  vat_json_node_t *node;
4973
4974  if (VAT_JSON_ARRAY != vam->json_tree.type)
4975    {
4976      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4977      vat_json_init_array (&vam->json_tree);
4978    }
4979  node = vat_json_array_add (&vam->json_tree);
4980
4981  vat_json_init_object (node);
4982  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4983  vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4984}
4985
4986static void vl_api_flow_classify_details_t_handler
4987  (vl_api_flow_classify_details_t * mp)
4988{
4989  vat_main_t *vam = &vat_main;
4990
4991  print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4992	 ntohl (mp->table_index));
4993}
4994
4995static void vl_api_flow_classify_details_t_handler_json
4996  (vl_api_flow_classify_details_t * mp)
4997{
4998  vat_main_t *vam = &vat_main;
4999  vat_json_node_t *node;
5000
5001  if (VAT_JSON_ARRAY != vam->json_tree.type)
5002    {
5003      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5004      vat_json_init_array (&vam->json_tree);
5005    }
5006  node = vat_json_array_add (&vam->json_tree);
5007
5008  vat_json_init_object (node);
5009  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5010  vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5011}
5012
5013#define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5014#define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5015#define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5016#define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5017#define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5018#define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5019#define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5020#define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5021#define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5022#define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5023
5024/*
5025 * Generate boilerplate reply handlers, which
5026 * dig the return value out of the xxx_reply_t API message,
5027 * stick it into vam->retval, and set vam->result_ready
5028 *
5029 * Could also do this by pointing N message decode slots at
5030 * a single function, but that could break in subtle ways.
5031 */
5032
5033#define foreach_standard_reply_retval_handler           \
5034_(sw_interface_set_flags_reply)                         \
5035_(sw_interface_add_del_address_reply)                   \
5036_(sw_interface_set_rx_mode_reply)                       \
5037_(sw_interface_set_rx_placement_reply)                  \
5038_(sw_interface_set_table_reply)                         \
5039_(sw_interface_set_mpls_enable_reply)                   \
5040_(sw_interface_set_vpath_reply)                         \
5041_(sw_interface_set_vxlan_bypass_reply)                  \
5042_(sw_interface_set_geneve_bypass_reply)                 \
5043_(sw_interface_set_vxlan_gpe_bypass_reply)              \
5044_(sw_interface_set_l2_bridge_reply)                     \
5045_(sw_interface_set_bond_weight_reply)                   \
5046_(bridge_domain_add_del_reply)                          \
5047_(sw_interface_set_l2_xconnect_reply)                   \
5048_(l2fib_add_del_reply)                                  \
5049_(l2fib_flush_int_reply)                                \
5050_(l2fib_flush_bd_reply)                                 \
5051_(ip_route_add_del_reply)                               \
5052_(ip_table_add_del_reply)                               \
5053_(ip_table_replace_begin_reply)                         \
5054_(ip_table_flush_reply)                                 \
5055_(ip_table_replace_end_reply)                           \
5056_(ip_mroute_add_del_reply)                              \
5057_(mpls_route_add_del_reply)                             \
5058_(mpls_table_add_del_reply)                             \
5059_(mpls_ip_bind_unbind_reply)                            \
5060_(bier_route_add_del_reply)                             \
5061_(bier_table_add_del_reply)                             \
5062_(sw_interface_set_unnumbered_reply)                    \
5063_(set_ip_flow_hash_reply)                               \
5064_(sw_interface_ip6_enable_disable_reply)                \
5065_(l2_patch_add_del_reply)                               \
5066_(sr_mpls_policy_add_reply)                             \
5067_(sr_mpls_policy_mod_reply)                             \
5068_(sr_mpls_policy_del_reply)                             \
5069_(sr_policy_add_reply)                                  \
5070_(sr_policy_mod_reply)                                  \
5071_(sr_policy_del_reply)                                  \
5072_(sr_localsid_add_del_reply)                            \
5073_(sr_steering_add_del_reply)                            \
5074_(classify_add_del_session_reply)                       \
5075_(classify_set_interface_ip_table_reply)                \
5076_(classify_set_interface_l2_tables_reply)               \
5077_(l2tpv3_set_tunnel_cookies_reply)                      \
5078_(l2tpv3_interface_enable_disable_reply)                \
5079_(l2tpv3_set_lookup_key_reply)                          \
5080_(l2_fib_clear_table_reply)                             \
5081_(l2_interface_efp_filter_reply)                        \
5082_(l2_interface_vlan_tag_rewrite_reply)                  \
5083_(modify_vhost_user_if_reply)                           \
5084_(delete_vhost_user_if_reply)                           \
5085_(want_l2_macs_events_reply)                            \
5086_(input_acl_set_interface_reply)                        \
5087_(ipsec_spd_add_del_reply)                              \
5088_(ipsec_interface_add_del_spd_reply)                    \
5089_(ipsec_spd_entry_add_del_reply)                        \
5090_(ipsec_sad_entry_add_del_reply)                        \
5091_(ipsec_tunnel_if_add_del_reply)                        \
5092_(ipsec_tunnel_if_set_sa_reply)                         \
5093_(delete_loopback_reply)                                \
5094_(bd_ip_mac_add_del_reply)                              \
5095_(bd_ip_mac_flush_reply)                                \
5096_(want_interface_events_reply)                          \
5097_(cop_interface_enable_disable_reply)			\
5098_(cop_whitelist_enable_disable_reply)                   \
5099_(sw_interface_clear_stats_reply)                       \
5100_(ioam_enable_reply)                                    \
5101_(ioam_disable_reply)                                   \
5102_(one_add_del_locator_reply)                            \
5103_(one_add_del_local_eid_reply)                          \
5104_(one_add_del_remote_mapping_reply)                     \
5105_(one_add_del_adjacency_reply)                          \
5106_(one_add_del_map_resolver_reply)                       \
5107_(one_add_del_map_server_reply)                         \
5108_(one_enable_disable_reply)                             \
5109_(one_rloc_probe_enable_disable_reply)                  \
5110_(one_map_register_enable_disable_reply)                \
5111_(one_map_register_set_ttl_reply)                       \
5112_(one_set_transport_protocol_reply)                     \
5113_(one_map_register_fallback_threshold_reply)            \
5114_(one_pitr_set_locator_set_reply)                       \
5115_(one_map_request_mode_reply)                           \
5116_(one_add_del_map_request_itr_rlocs_reply)              \
5117_(one_eid_table_add_del_map_reply)                      \
5118_(one_use_petr_reply)                                   \
5119_(one_stats_enable_disable_reply)                       \
5120_(one_add_del_l2_arp_entry_reply)                       \
5121_(one_add_del_ndp_entry_reply)                          \
5122_(one_stats_flush_reply)                                \
5123_(one_enable_disable_xtr_mode_reply)                    \
5124_(one_enable_disable_pitr_mode_reply)                   \
5125_(one_enable_disable_petr_mode_reply)                   \
5126_(gpe_enable_disable_reply)                             \
5127_(gpe_set_encap_mode_reply)                             \
5128_(gpe_add_del_iface_reply)                              \
5129_(gpe_add_del_native_fwd_rpath_reply)                   \
5130_(af_packet_delete_reply)                               \
5131_(policer_classify_set_interface_reply)                 \
5132_(set_ipfix_exporter_reply)                             \
5133_(set_ipfix_classify_stream_reply)                      \
5134_(ipfix_classify_table_add_del_reply)                   \
5135_(flow_classify_set_interface_reply)                    \
5136_(sw_interface_span_enable_disable_reply)               \
5137_(pg_capture_reply)                                     \
5138_(pg_enable_disable_reply)                              \
5139_(ip_source_and_port_range_check_add_del_reply)         \
5140_(ip_source_and_port_range_check_interface_add_del_reply)\
5141_(delete_subif_reply)                                   \
5142_(l2_interface_pbb_tag_rewrite_reply)                   \
5143_(set_punt_reply)                                       \
5144_(feature_enable_disable_reply)				\
5145_(feature_gso_enable_disable_reply)	                \
5146_(sw_interface_tag_add_del_reply)			\
5147_(sw_interface_add_del_mac_address_reply)		\
5148_(hw_interface_set_mtu_reply)                           \
5149_(p2p_ethernet_add_reply)                               \
5150_(p2p_ethernet_del_reply)                               \
5151_(lldp_config_reply)                                    \
5152_(sw_interface_set_lldp_reply)				\
5153_(tcp_configure_src_addresses_reply)			\
5154_(session_rule_add_del_reply)				\
5155_(ip_container_proxy_add_del_reply)                     \
5156_(output_acl_set_interface_reply)                       \
5157_(qos_record_enable_disable_reply)
5158
5159#define _(n)                                    \
5160    static void vl_api_##n##_t_handler          \
5161    (vl_api_##n##_t * mp)                       \
5162    {                                           \
5163        vat_main_t * vam = &vat_main;           \
5164        i32 retval = ntohl(mp->retval);         \
5165        if (vam->async_mode) {                  \
5166            vam->async_errors += (retval < 0);  \
5167        } else {                                \
5168            vam->retval = retval;               \
5169            vam->result_ready = 1;              \
5170        }                                       \
5171    }
5172foreach_standard_reply_retval_handler;
5173#undef _
5174
5175#define _(n)                                    \
5176    static void vl_api_##n##_t_handler_json     \
5177    (vl_api_##n##_t * mp)                       \
5178    {                                           \
5179        vat_main_t * vam = &vat_main;           \
5180        vat_json_node_t node;                   \
5181        vat_json_init_object(&node);            \
5182        vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5183        vat_json_print(vam->ofp, &node);        \
5184        vam->retval = ntohl(mp->retval);        \
5185        vam->result_ready = 1;                  \
5186    }
5187foreach_standard_reply_retval_handler;
5188#undef _
5189
5190/*
5191 * Table of message reply handlers, must include boilerplate handlers
5192 * we just generated
5193 */
5194
5195#define foreach_vpe_api_reply_msg                                       \
5196_(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5197_(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5198_(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5199_(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5200_(CONTROL_PING_REPLY, control_ping_reply)                               \
5201_(CLI_REPLY, cli_reply)                                                 \
5202_(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5203_(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5204  sw_interface_add_del_address_reply)                                   \
5205_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5206_(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)	\
5207_(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details)	\
5208_(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) 		\
5209_(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5210_(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) 		\
5211_(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5212_(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5213_(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5214_(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5215  sw_interface_set_l2_xconnect_reply)                                   \
5216_(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5217  sw_interface_set_l2_bridge_reply)                                     \
5218_(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5219_(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5220_(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5221_(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5222_(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5223_(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5224_(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5225_(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5226_(TAP_CREATE_V2_REPLY, tap_create_v2_reply)				\
5227_(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)				\
5228_(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5229_(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)			\
5230_(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)			\
5231_(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5232_(BOND_CREATE_REPLY, bond_create_reply)	   			        \
5233_(BOND_DELETE_REPLY, bond_delete_reply)			  	        \
5234_(BOND_ENSLAVE_REPLY, bond_enslave_reply)				\
5235_(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)			\
5236_(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5237_(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5238_(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5239_(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)			\
5240_(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)			\
5241_(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5242_(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5243_(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5244_(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)			\
5245_(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)			\
5246_(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)			\
5247_(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)			\
5248_(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)			\
5249_(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)			\
5250_(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5251_(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5252  sw_interface_set_unnumbered_reply)                                    \
5253_(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5254_(CREATE_SUBIF_REPLY, create_subif_reply)                     		\
5255_(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5256_(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5257  sw_interface_ip6_enable_disable_reply)                                \
5258_(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5259_(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5260_(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5261_(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5262_(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5263_(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5264_(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5265_(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5266_(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5267_(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5268_(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5269_(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5270classify_set_interface_ip_table_reply)                                  \
5271_(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5272  classify_set_interface_l2_tables_reply)                               \
5273_(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5274_(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5275_(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5276_(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5277_(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5278  l2tpv3_interface_enable_disable_reply)                                \
5279_(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5280_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5281_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5282_(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5283_(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5284_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5285_(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5286_(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5287_(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5288_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5289_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5290_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5291_(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5292_(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5293_(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5294_(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5295_(SHOW_VERSION_REPLY, show_version_reply)                               \
5296_(SHOW_THREADS_REPLY, show_threads_reply)                               \
5297_(L2_FIB_TABLE_DETAILS, l2_fib_table_details)				\
5298_(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)	\
5299_(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5300_(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)		\
5301_(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)			\
5302_(L2_MACS_EVENT, l2_macs_event)						\
5303_(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5304_(IP_ADDRESS_DETAILS, ip_address_details)                               \
5305_(IP_DETAILS, ip_details)                                               \
5306_(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5307_(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5308_(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5309_(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5310_(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5311_(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5312_(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5313_(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5314_(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5315_(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5316_(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5317_(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5318_(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)    			\
5319_(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5320_(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5321_(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5322_(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5323_(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5324_(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5325_(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5326_(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5327_(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5328_(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5329_(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5330_(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5331_(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5332_(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5333_(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5334  one_map_register_enable_disable_reply)                                \
5335_(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5336_(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5337_(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5338_(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5339  one_map_register_fallback_threshold_reply)                            \
5340_(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5341  one_rloc_probe_enable_disable_reply)                                  \
5342_(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5343_(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5344_(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5345_(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5346_(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5347_(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5348_(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5349_(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5350_(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5351_(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5352_(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5353_(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5354_(ONE_STATS_DETAILS, one_stats_details)                                 \
5355_(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5356_(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5357_(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5358  show_one_stats_enable_disable_reply)                                  \
5359_(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5360_(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5361_(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5362_(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5363_(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5364_(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5365_(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5366_(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5367  one_enable_disable_pitr_mode_reply)                                   \
5368_(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5369  one_enable_disable_petr_mode_reply)                                   \
5370_(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5371_(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5372_(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5373_(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5374_(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5375_(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5376_(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5377_(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5378_(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5379_(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5380_(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5381_(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5382  gpe_add_del_native_fwd_rpath_reply)                                   \
5383_(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5384  gpe_fwd_entry_path_details)                                           \
5385_(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5386_(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5387  one_add_del_map_request_itr_rlocs_reply)                              \
5388_(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5389  one_get_map_request_itr_rlocs_reply)                                  \
5390_(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5391_(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5392_(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5393_(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5394_(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5395_(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5396  show_one_map_register_state_reply)                                    \
5397_(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5398_(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5399  show_one_map_register_fallback_threshold_reply)                       \
5400_(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5401_(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5402_(AF_PACKET_DETAILS, af_packet_details)					\
5403_(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5404_(POLICER_DETAILS, policer_details)                                     \
5405_(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5406_(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5407_(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5408_(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5409_(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5410_(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5411_(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5412_(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5413_(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5414_(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5415_(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5416_(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5417_(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5418_(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5419_(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5420_(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5421_(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5422_(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5423_(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5424_(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5425_(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5426_(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5427_(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5428_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5429 ip_source_and_port_range_check_add_del_reply)                          \
5430_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5431 ip_source_and_port_range_check_interface_add_del_reply)                \
5432_(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5433_(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5434_(SET_PUNT_REPLY, set_punt_reply)                                       \
5435_(IP_TABLE_DETAILS, ip_table_details)                                   \
5436_(IP_ROUTE_DETAILS, ip_route_details)                                   \
5437_(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5438_(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5439_(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)     	\
5440_(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5441_(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5442_(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5443_(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5444_(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5445_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5446_(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5447_(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)		\
5448_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)	\
5449_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)		\
5450_(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)		\
5451_(SESSION_RULES_DETAILS, session_rules_details)				\
5452_(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)	\
5453_(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5454_(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5455
5456#define foreach_standalone_reply_msg					\
5457_(SW_INTERFACE_EVENT, sw_interface_event)
5458
5459typedef struct
5460{
5461  u8 *name;
5462  u32 value;
5463} name_sort_t;
5464
5465#define STR_VTR_OP_CASE(op)     \
5466    case L2_VTR_ ## op:         \
5467        return "" # op;
5468
5469static const char *
5470str_vtr_op (u32 vtr_op)
5471{
5472  switch (vtr_op)
5473    {
5474      STR_VTR_OP_CASE (DISABLED);
5475      STR_VTR_OP_CASE (PUSH_1);
5476      STR_VTR_OP_CASE (PUSH_2);
5477      STR_VTR_OP_CASE (POP_1);
5478      STR_VTR_OP_CASE (POP_2);
5479      STR_VTR_OP_CASE (TRANSLATE_1_1);
5480      STR_VTR_OP_CASE (TRANSLATE_1_2);
5481      STR_VTR_OP_CASE (TRANSLATE_2_1);
5482      STR_VTR_OP_CASE (TRANSLATE_2_2);
5483    }
5484
5485  return "UNKNOWN";
5486}
5487
5488static int
5489dump_sub_interface_table (vat_main_t * vam)
5490{
5491  const sw_interface_subif_t *sub = NULL;
5492
5493  if (vam->json_output)
5494    {
5495      clib_warning
5496	("JSON output supported only for VPE API calls and dump_stats_table");
5497      return -99;
5498    }
5499
5500  print (vam->ofp,
5501	 "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5502	 "Interface", "sw_if_index",
5503	 "sub id", "dot1ad", "tags", "outer id",
5504	 "inner id", "exact", "default", "outer any", "inner any");
5505
5506  vec_foreach (sub, vam->sw_if_subif_table)
5507  {
5508    print (vam->ofp,
5509	   "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5510	   sub->interface_name,
5511	   sub->sw_if_index,
5512	   sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5513	   sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5514	   sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5515	   sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5516    if (sub->vtr_op != L2_VTR_DISABLED)
5517      {
5518	print (vam->ofp,
5519	       "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5520	       "tag1: %d tag2: %d ]",
5521	       str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5522	       sub->vtr_tag1, sub->vtr_tag2);
5523      }
5524  }
5525
5526  return 0;
5527}
5528
5529static int
5530name_sort_cmp (void *a1, void *a2)
5531{
5532  name_sort_t *n1 = a1;
5533  name_sort_t *n2 = a2;
5534
5535  return strcmp ((char *) n1->name, (char *) n2->name);
5536}
5537
5538static int
5539dump_interface_table (vat_main_t * vam)
5540{
5541  hash_pair_t *p;
5542  name_sort_t *nses = 0, *ns;
5543
5544  if (vam->json_output)
5545    {
5546      clib_warning
5547	("JSON output supported only for VPE API calls and dump_stats_table");
5548      return -99;
5549    }
5550
5551  /* *INDENT-OFF* */
5552  hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5553  ({
5554    vec_add2 (nses, ns, 1);
5555    ns->name = (u8 *)(p->key);
5556    ns->value = (u32) p->value[0];
5557  }));
5558  /* *INDENT-ON* */
5559
5560  vec_sort_with_function (nses, name_sort_cmp);
5561
5562  print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5563  vec_foreach (ns, nses)
5564  {
5565    print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5566  }
5567  vec_free (nses);
5568  return 0;
5569}
5570
5571static int
5572dump_ip_table (vat_main_t * vam, int is_ipv6)
5573{
5574  const ip_details_t *det = NULL;
5575  const ip_address_details_t *address = NULL;
5576  u32 i = ~0;
5577
5578  print (vam->ofp, "%-12s", "sw_if_index");
5579
5580  vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5581  {
5582    i++;
5583    if (!det->present)
5584      {
5585	continue;
5586      }
5587    print (vam->ofp, "%-12d", i);
5588    print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5589    if (!det->addr)
5590      {
5591	continue;
5592      }
5593    vec_foreach (address, det->addr)
5594    {
5595      print (vam->ofp,
5596	     "            %-30U%-13d",
5597	     is_ipv6 ? format_ip6_address : format_ip4_address,
5598	     address->ip, address->prefix_length);
5599    }
5600  }
5601
5602  return 0;
5603}
5604
5605static int
5606dump_ipv4_table (vat_main_t * vam)
5607{
5608  if (vam->json_output)
5609    {
5610      clib_warning
5611	("JSON output supported only for VPE API calls and dump_stats_table");
5612      return -99;
5613    }
5614
5615  return dump_ip_table (vam, 0);
5616}
5617
5618static int
5619dump_ipv6_table (vat_main_t * vam)
5620{
5621  if (vam->json_output)
5622    {
5623      clib_warning
5624	("JSON output supported only for VPE API calls and dump_stats_table");
5625      return -99;
5626    }
5627
5628  return dump_ip_table (vam, 1);
5629}
5630
5631/*
5632 * Pass CLI buffers directly in the CLI_INBAND API message,
5633 * instead of an additional shared memory area.
5634 */
5635static int
5636exec_inband (vat_main_t * vam)
5637{
5638  vl_api_cli_inband_t *mp;
5639  unformat_input_t *i = vam->input;
5640  int ret;
5641
5642  if (vec_len (i->buffer) == 0)
5643    return -1;
5644
5645  if (vam->exec_mode == 0 && unformat (i, "mode"))
5646    {
5647      vam->exec_mode = 1;
5648      return 0;
5649    }
5650  if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5651    {
5652      vam->exec_mode = 0;
5653      return 0;
5654    }
5655
5656  /*
5657   * In order for the CLI command to work, it
5658   * must be a vector ending in \n, not a C-string ending
5659   * in \n\0.
5660   */
5661  M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
5662  vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
5663
5664  S (mp);
5665  W (ret);
5666  /* json responses may or may not include a useful reply... */
5667  if (vec_len (vam->cmd_reply))
5668    print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5669  return ret;
5670}
5671
5672int
5673exec (vat_main_t * vam)
5674{
5675  return exec_inband (vam);
5676}
5677
5678static int
5679api_create_loopback (vat_main_t * vam)
5680{
5681  unformat_input_t *i = vam->input;
5682  vl_api_create_loopback_t *mp;
5683  vl_api_create_loopback_instance_t *mp_lbi;
5684  u8 mac_address[6];
5685  u8 mac_set = 0;
5686  u8 is_specified = 0;
5687  u32 user_instance = 0;
5688  int ret;
5689
5690  clib_memset (mac_address, 0, sizeof (mac_address));
5691
5692  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5693    {
5694      if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5695	mac_set = 1;
5696      if (unformat (i, "instance %d", &user_instance))
5697	is_specified = 1;
5698      else
5699	break;
5700    }
5701
5702  if (is_specified)
5703    {
5704      M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5705      mp_lbi->is_specified = is_specified;
5706      if (is_specified)
5707	mp_lbi->user_instance = htonl (user_instance);
5708      if (mac_set)
5709	clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5710      S (mp_lbi);
5711    }
5712  else
5713    {
5714      /* Construct the API message */
5715      M (CREATE_LOOPBACK, mp);
5716      if (mac_set)
5717	clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5718      S (mp);
5719    }
5720
5721  W (ret);
5722  return ret;
5723}
5724
5725static int
5726api_delete_loopback (vat_main_t * vam)
5727{
5728  unformat_input_t *i = vam->input;
5729  vl_api_delete_loopback_t *mp;
5730  u32 sw_if_index = ~0;
5731  int ret;
5732
5733  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5734    {
5735      if (unformat (i, "sw_if_index %d", &sw_if_index))
5736	;
5737      else
5738	break;
5739    }
5740
5741  if (sw_if_index == ~0)
5742    {
5743      errmsg ("missing sw_if_index");
5744      return -99;
5745    }
5746
5747  /* Construct the API message */
5748  M (DELETE_LOOPBACK, mp);
5749  mp->sw_if_index = ntohl (sw_if_index);
5750
5751  S (mp);
5752  W (ret);
5753  return ret;
5754}
5755
5756static int
5757api_want_interface_events (vat_main_t * vam)
5758{
5759  unformat_input_t *i = vam->input;
5760  vl_api_want_interface_events_t *mp;
5761  int enable = -1;
5762  int ret;
5763
5764  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5765    {
5766      if (unformat (i, "enable"))
5767	enable = 1;
5768      else if (unformat (i, "disable"))
5769	enable = 0;
5770      else
5771	break;
5772    }
5773
5774  if (enable == -1)
5775    {
5776      errmsg ("missing enable|disable");
5777      return -99;
5778    }
5779
5780  M (WANT_INTERFACE_EVENTS, mp);
5781  mp->enable_disable = enable;
5782
5783  vam->interface_event_display = enable;
5784
5785  S (mp);
5786  W (ret);
5787  return ret;
5788}
5789
5790
5791/* Note: non-static, called once to set up the initial intfc table */
5792int
5793api_sw_interface_dump (vat_main_t * vam)
5794{
5795  vl_api_sw_interface_dump_t *mp;
5796  vl_api_control_ping_t *mp_ping;
5797  hash_pair_t *p;
5798  name_sort_t *nses = 0, *ns;
5799  sw_interface_subif_t *sub = NULL;
5800  int ret;
5801
5802  /* Toss the old name table */
5803  /* *INDENT-OFF* */
5804  hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5805  ({
5806    vec_add2 (nses, ns, 1);
5807    ns->name = (u8 *)(p->key);
5808    ns->value = (u32) p->value[0];
5809  }));
5810  /* *INDENT-ON* */
5811
5812  hash_free (vam->sw_if_index_by_interface_name);
5813
5814  vec_foreach (ns, nses) vec_free (ns->name);
5815
5816  vec_free (nses);
5817
5818  vec_foreach (sub, vam->sw_if_subif_table)
5819  {
5820    vec_free (sub->interface_name);
5821  }
5822  vec_free (vam->sw_if_subif_table);
5823
5824  /* recreate the interface name hash table */
5825  vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5826
5827  /*
5828   * Ask for all interface names. Otherwise, the epic catalog of
5829   * name filters becomes ridiculously long, and vat ends up needing
5830   * to be taught about new interface types.
5831   */
5832  M (SW_INTERFACE_DUMP, mp);
5833  S (mp