[aarch64] Fixes CLI crashes on dpaa2 platform.
[vpp.git] / src / vat / api_format.c
index 0230021..99bef05 100644 (file)
  */
 
 #include <vat/vat.h>
+#include <vppinfra/socket.h>
+#include <svm/memfd.h>
 #include <vlibapi/api.h>
 #include <vlibmemory/api.h>
-#include <vlibsocket/api.h>
 #include <vnet/ip/ip.h>
 #include <vnet/l2/l2_input.h>
 #include <vnet/l2tp/l2tp.h>
 #define __plugin_msg_base 0
 #include <vlibapi/vat_helper_macros.h>
 
+#if VPP_API_TEST_BUILTIN == 0
+#include <netdb.h>
+
+u32
+vl (void *p)
+{
+  return vec_len (p);
+}
+
+int
+vat_socket_connect (vat_main_t * vam)
+{
+  return vl_socket_client_connect
+    (&vam->socket_client_main, (char *) vam->socket_name,
+     "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
+}
+#else /* vpp built-in case, we don't do sockets... */
+int
+vat_socket_connect (vat_main_t * vam)
+{
+  return 0;
+}
+
+void
+vl_socket_client_read_reply (socket_client_main_t * scm)
+{
+};
+#endif
+
+
 f64
 vat_time_now (vat_main_t * vam)
 {
@@ -1036,9 +1067,17 @@ vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
 {
   vat_main_t *vam = &vat_main;
   i32 retval = ntohl (mp->retval);
+  u32 length = ntohl (mp->length);
+
+  vec_reset_length (vam->cmd_reply);
 
   vam->retval = retval;
-  vam->cmd_reply = mp->reply;
+  if (retval == 0)
+    {
+      vec_validate (vam->cmd_reply, length);
+      clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
+      vam->cmd_reply[length] = 0;
+    }
   vam->result_ready = 1;
 }
 
@@ -1048,6 +1087,8 @@ vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
   vat_main_t *vam = &vat_main;
   vat_json_node_t node;
 
+  vec_reset_length (vam->cmd_reply);
+
   vat_json_init_object (&node);
   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
   vat_json_object_add_string_copy (&node, "reply", mp->reply);
@@ -1421,6 +1462,7 @@ static void vl_api_control_ping_reply_t_handler
       vam->retval = retval;
       vam->result_ready = 1;
     }
+  vam->socket_client_main.control_pings_outstanding--;
 }
 
 static void vl_api_control_ping_reply_t_handler_json
@@ -1979,6 +2021,130 @@ static void vl_api_create_vhost_user_if_reply_t_handler_json
   vam->result_ready = 1;
 }
 
+static clib_error_t *
+receive_fd_msg (int socket_fd, int *my_fd)
+{
+  char msgbuf[16];
+  char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
+  struct msghdr mh = { 0 };
+  struct iovec iov[1];
+  ssize_t size;
+  struct ucred *cr = 0;
+  struct cmsghdr *cmsg;
+  pid_t pid __attribute__ ((unused));
+  uid_t uid __attribute__ ((unused));
+  gid_t gid __attribute__ ((unused));
+
+  iov[0].iov_base = msgbuf;
+  iov[0].iov_len = 5;
+  mh.msg_iov = iov;
+  mh.msg_iovlen = 1;
+  mh.msg_control = ctl;
+  mh.msg_controllen = sizeof (ctl);
+
+  memset (ctl, 0, sizeof (ctl));
+
+  /* receive the incoming message */
+  size = recvmsg (socket_fd, &mh, 0);
+  if (size != 5)
+    {
+      return (size == 0) ? clib_error_return (0, "disconnected") :
+       clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
+                               socket_fd);
+    }
+
+  cmsg = CMSG_FIRSTHDR (&mh);
+  while (cmsg)
+    {
+      if (cmsg->cmsg_level == SOL_SOCKET)
+       {
+         if (cmsg->cmsg_type == SCM_CREDENTIALS)
+           {
+             cr = (struct ucred *) CMSG_DATA (cmsg);
+             uid = cr->uid;
+             gid = cr->gid;
+             pid = cr->pid;
+           }
+         else if (cmsg->cmsg_type == SCM_RIGHTS)
+           {
+             clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
+           }
+       }
+      cmsg = CMSG_NXTHDR (&mh, cmsg);
+    }
+  return 0;
+}
+
+static void vl_api_memfd_segment_create_reply_t_handler
+  (vl_api_memfd_segment_create_reply_t * mp)
+{
+  /* Dont bother in the builtin version */
+#if VPP_API_TEST_BUILTIN == 0
+  vat_main_t *vam = &vat_main;
+  api_main_t *am = &api_main;
+  socket_client_main_t *scm = &vam->socket_client_main;
+  int my_fd = -1;
+  clib_error_t *error;
+  memfd_private_t memfd;
+  i32 retval = ntohl (mp->retval);
+
+  if (retval == 0)
+    {
+      error = receive_fd_msg (scm->socket_fd, &my_fd);
+      if (error)
+       {
+         retval = -99;
+         goto out;
+       }
+
+      memset (&memfd, 0, sizeof (memfd));
+      memfd.fd = my_fd;
+
+      vam->client_index_invalid = 1;
+
+      retval = memfd_slave_init (&memfd);
+      if (retval)
+       clib_warning ("WARNING: segment map returned %d", retval);
+
+      /* Pivot to the memory client segment that vpp just created */
+
+      am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
+
+      am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
+
+      vl_client_install_client_message_handlers ();
+
+      vl_client_connect_to_vlib_no_map ("pvt",
+                                       "vpp_api_test(p)",
+                                       32 /* input_queue_length */ );
+      if (close (my_fd) < 0)
+       clib_unix_warning ("close memfd fd pivot");
+      vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
+
+      vl_socket_client_enable_disable (&vam->socket_client_main,
+                                      0 /* disable socket */ );
+    }
+
+out:
+  if (vam->async_mode)
+    {
+      vam->async_errors += (retval < 0);
+    }
+  else
+    {
+      vam->retval = retval;
+      vam->result_ready = 1;
+    }
+#endif
+}
+
+static void vl_api_memfd_segment_create_reply_t_handler_json
+  (vl_api_memfd_segment_create_reply_t * mp)
+{
+  clib_warning ("no");
+}
+
+
 static void vl_api_ip_address_details_t_handler
   (vl_api_ip_address_details_t * mp)
 {
@@ -4521,7 +4687,7 @@ format_hex_bytes (u8 * s, va_list * va)
 
   /* Print short or long form depending on byte count. */
   uword short_form = n_bytes <= 32;
-  uword indent = format_get_indent (s);
+  u32 indent = format_get_indent (s);
 
   if (n_bytes == 0)
     return s;
@@ -5066,6 +5232,7 @@ _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
+_(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
@@ -5223,7 +5390,8 @@ _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
-_(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
+_(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                                \
+_(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)
 
 typedef struct
 {
@@ -5597,76 +5765,9 @@ dump_stats_table (vat_main_t * vam)
   return 0;
 }
 
-int
-exec (vat_main_t * vam)
-{
-  api_main_t *am = &api_main;
-  vl_api_cli_t *mp;
-  f64 timeout;
-  void *oldheap;
-  u8 *cmd = 0;
-  unformat_input_t *i = vam->input;
-
-  if (vec_len (i->buffer) == 0)
-    return -1;
-
-  if (vam->exec_mode == 0 && unformat (i, "mode"))
-    {
-      vam->exec_mode = 1;
-      return 0;
-    }
-  if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
-    {
-      vam->exec_mode = 0;
-      return 0;
-    }
-
-
-  M (CLI, mp);
-
-  /*
-   * Copy cmd into shared memory.
-   * In order for the CLI command to work, it
-   * must be a vector ending in \n, not a C-string ending
-   * in \n\0.
-   */
-  pthread_mutex_lock (&am->vlib_rp->mutex);
-  oldheap = svm_push_data_heap (am->vlib_rp);
-
-  vec_validate (cmd, vec_len (vam->input->buffer) - 1);
-  clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
-
-  svm_pop_heap (oldheap);
-  pthread_mutex_unlock (&am->vlib_rp->mutex);
-
-  mp->cmd_in_shmem = pointer_to_uword (cmd);
-  S (mp);
-  timeout = vat_time_now (vam) + 10.0;
-
-  while (vat_time_now (vam) < timeout)
-    {
-      if (vam->result_ready == 1)
-       {
-         u8 *free_me;
-         if (vam->shmem_result != NULL)
-           print (vam->ofp, "%s", vam->shmem_result);
-         pthread_mutex_lock (&am->vlib_rp->mutex);
-         oldheap = svm_push_data_heap (am->vlib_rp);
-
-         free_me = (u8 *) vam->shmem_result;
-         vec_free (free_me);
-
-         svm_pop_heap (oldheap);
-         pthread_mutex_unlock (&am->vlib_rp->mutex);
-         return 0;
-       }
-    }
-  return -99;
-}
-
 /*
- * Future replacement of exec() that passes CLI buffers directly in
- * the API messages instead of an additional shared memory area.
+ * Pass CLI buffers directly in the CLI_INBAND API message,
+ * instead of an additional shared memory area.
  */
 static int
 exec_inband (vat_main_t * vam)
@@ -5700,10 +5801,19 @@ exec_inband (vat_main_t * vam)
   mp->length = htonl (len);
 
   S (mp);
-  W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
+  W (ret);
+  /* json responses may or may not include a useful reply... */
+  if (vec_len (vam->cmd_reply))
+    print (vam->ofp, (char *) (vam->cmd_reply));
   return ret;
 }
 
+int
+exec (vat_main_t * vam)
+{
+  return exec_inband (vam);
+}
+
 static int
 api_create_loopback (vat_main_t * vam)
 {
@@ -5949,7 +6059,7 @@ api_sw_interface_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -6526,7 +6636,7 @@ api_bridge_domain_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -6793,7 +6903,7 @@ api_l2fib_add_del (vat_main_t * vam)
       /* Shut off async mode */
       vam->async_mode = 0;
 
-      M (CONTROL_PING, mp_ping);
+      MPING (CONTROL_PING, mp_ping);
       S (mp_ping);
 
       timeout = vat_time_now (vam) + 1.0;
@@ -7565,7 +7675,7 @@ api_ip_add_del_route (vat_main_t * vam)
       /* Shut off async mode */
       vam->async_mode = 0;
 
-      M (CONTROL_PING, mp_ping);
+      MPING (CONTROL_PING, mp_ping);
       S (mp_ping);
 
       timeout = vat_time_now (vam) + 1.0;
@@ -7954,7 +8064,7 @@ api_mpls_route_add_del (vat_main_t * vam)
       /* Shut off async mode */
       vam->async_mode = 0;
 
-      M (CONTROL_PING, mp_ping);
+      MPING (CONTROL_PING, mp_ping);
       S (mp_ping);
 
       timeout = vat_time_now (vam) + 1.0;
@@ -8864,7 +8974,7 @@ api_dhcp_proxy_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -9216,7 +9326,7 @@ api_ip6nd_proxy_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -11552,7 +11662,7 @@ api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -11600,7 +11710,7 @@ api_sw_interface_tap_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -11875,7 +11985,7 @@ api_vxlan_tunnel_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -12066,7 +12176,7 @@ api_gre_tunnel_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -12422,7 +12532,7 @@ api_sw_interface_vhost_user_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -12697,7 +12807,7 @@ api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -12782,7 +12892,7 @@ api_l2_fib_table_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -13050,7 +13160,7 @@ api_ip_address_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -13106,7 +13216,7 @@ api_ip_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -13665,6 +13775,121 @@ api_ipsec_tunnel_if_add_del (vat_main_t * vam)
   return ret;
 }
 
+static void
+vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
+{
+  vat_main_t *vam = &vat_main;
+
+  print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
+        "crypto_key %U integ_alg %u integ_key %U use_esn %u "
+        "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
+        "tunnel_src_addr %U tunnel_dst_addr %U "
+        "salt %u seq_outbound %lu last_seq_inbound %lu "
+        "replay_window %lu total_data_size %lu\n",
+        ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
+        mp->protocol,
+        mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
+        mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
+        mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
+        (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
+        mp->tunnel_src_addr,
+        (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
+        mp->tunnel_dst_addr,
+        ntohl (mp->salt),
+        clib_net_to_host_u64 (mp->seq_outbound),
+        clib_net_to_host_u64 (mp->last_seq_inbound),
+        clib_net_to_host_u64 (mp->replay_window),
+        clib_net_to_host_u64 (mp->total_data_size));
+}
+
+#define vl_api_ipsec_sa_details_t_endian vl_noop_handler
+#define vl_api_ipsec_sa_details_t_print vl_noop_handler
+
+static void vl_api_ipsec_sa_details_t_handler_json
+  (vl_api_ipsec_sa_details_t * mp)
+{
+  vat_main_t *vam = &vat_main;
+  vat_json_node_t *node = NULL;
+  struct in_addr src_ip4, dst_ip4;
+  struct in6_addr src_ip6, dst_ip6;
+
+  if (VAT_JSON_ARRAY != vam->json_tree.type)
+    {
+      ASSERT (VAT_JSON_NONE == vam->json_tree.type);
+      vat_json_init_array (&vam->json_tree);
+    }
+  node = vat_json_array_add (&vam->json_tree);
+
+  vat_json_init_object (node);
+  vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
+  vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
+  vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
+  vat_json_object_add_uint (node, "proto", mp->protocol);
+  vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
+  vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
+  vat_json_object_add_uint (node, "use_esn", mp->use_esn);
+  vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
+  vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
+  vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
+  vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
+                            mp->crypto_key_len);
+  vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
+                            mp->integ_key_len);
+  if (mp->is_tunnel_ip6)
+    {
+      clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
+      vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
+      clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
+      vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
+    }
+  else
+    {
+      clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
+      vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
+      clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
+      vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
+    }
+  vat_json_object_add_uint (node, "replay_window",
+                           clib_net_to_host_u64 (mp->replay_window));
+  vat_json_object_add_uint (node, "total_data_size",
+                           clib_net_to_host_u64 (mp->total_data_size));
+
+}
+
+static int
+api_ipsec_sa_dump (vat_main_t * vam)
+{
+  unformat_input_t *i = vam->input;
+  vl_api_ipsec_sa_dump_t *mp;
+  vl_api_control_ping_t *mp_ping;
+  u32 sa_id = ~0;
+  int ret;
+
+  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (i, "sa_id %d", &sa_id))
+       ;
+      else
+       {
+         clib_warning ("parse error '%U'", format_unformat_error, i);
+         return -99;
+       }
+    }
+
+  M (IPSEC_SA_DUMP, mp);
+
+  mp->sa_id = ntohl (sa_id);
+
+  S (mp);
+
+  /* Use a control ping for synchronization */
+  M (CONTROL_PING, mp_ping);
+  S (mp_ping);
+
+  W (ret);
+  return ret;
+}
+
 static int
 api_ikev2_profile_add_del (vat_main_t * vam)
 {
@@ -14485,7 +14710,7 @@ api_map_domain_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -14524,7 +14749,7 @@ api_map_rule_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -16920,7 +17145,7 @@ api_one_locator_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -16970,7 +17195,7 @@ api_one_locator_set_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17028,7 +17253,7 @@ api_one_eid_table_map_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17056,7 +17281,7 @@ api_one_eid_table_vni_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17164,7 +17389,7 @@ api_one_eid_table_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17431,7 +17656,7 @@ api_one_map_server_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17458,7 +17683,7 @@ api_one_map_resolver_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17492,7 +17717,7 @@ api_one_stats_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17554,7 +17779,7 @@ api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
   /* send it... */
   S (mp);
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17803,7 +18028,7 @@ api_policer_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -17892,7 +18117,7 @@ api_policer_classify_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -18118,7 +18343,7 @@ api_mpls_tunnel_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18188,7 +18413,7 @@ api_mpls_fib_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18289,7 +18514,7 @@ api_ip_fib_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18307,7 +18532,7 @@ api_ip_mfib_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18398,7 +18623,7 @@ api_ip_neighbor_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18499,7 +18724,7 @@ api_ip6_fib_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18517,7 +18742,7 @@ api_ip6_mfib_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18632,7 +18857,7 @@ api_classify_session_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18766,7 +18991,7 @@ api_ipfix_classify_table_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -18957,7 +19182,7 @@ api_sw_interface_span_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -19458,7 +19683,7 @@ api_ipsec_gre_tunnel_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -19665,7 +19890,7 @@ api_flow_classify_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   /* Wait for a reply... */
@@ -19836,7 +20061,7 @@ api_l2_xconnect_dump (vat_main_t * vam)
   S (mp);
 
   /* Use a control ping for synchronization */
-  M (CONTROL_PING, mp_ping);
+  MPING (CONTROL_PING, mp_ping);
   S (mp_ping);
 
   W (ret);
@@ -20140,6 +20365,34 @@ api_tcp_configure_src_addresses (vat_main_t * vam)
   return ret;
 }
 
+static int
+api_memfd_segment_create (vat_main_t * vam)
+{
+  unformat_input_t *i = vam->input;
+  vl_api_memfd_segment_create_t *mp;
+  u64 size = 64 << 20;
+  int ret;
+
+#if VPP_API_TEST_BUILTIN == 1
+  errmsg ("memfd_segment_create (builtin) not supported");
+  return -99;
+#endif
+
+  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (i, "size %U", unformat_memory_size, &size))
+       ;
+      else
+       break;
+    }
+
+  M (MEMFD_SEGMENT_CREATE, mp);
+  mp->requested_size = size;
+  S (mp);
+  W (ret);
+  return ret;
+}
+
 static int
 q_or_quit (vat_main_t * vam)
 {
@@ -20701,6 +20954,7 @@ _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
+_(ipsec_sa_dump, "[sa_id <n>]")                                         \
 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
   "(auth_data 0x<data> | auth_data <data>)")                            \
@@ -20919,7 +21173,8 @@ _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id
 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
-_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")
+_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")  \
+_(memfd_segment_create,"size <nnn>")
 
 /* List of command functions, CLI names map directly to functions */
 #define foreach_cli_function                                    \