+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");
+}
+
+