+static void
+vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t *
+ mp)
+{
+ int n_fds = 0, *fds = 0;
+ u64 segment_handle;
+ vcl_worker_t *wrk;
+ u32 wrk_index;
+
+ if (mp->retval)
+ {
+ clib_warning ("VCL<%d>: add/del worker failed: %U", getpid (),
+ format_api_error, ntohl (mp->retval));
+ goto failed;
+ }
+
+ if (!mp->is_add)
+ return;
+
+ wrk_index = mp->context;
+ wrk = vcl_worker_get_if_valid (wrk_index);
+ if (!wrk)
+ return;
+
+ wrk->vpp_wrk_index = clib_net_to_host_u32 (mp->wrk_index);
+ wrk->app_event_queue = uword_to_pointer (mp->app_event_queue_address,
+ svm_msg_q_t *);
+
+ segment_handle = clib_net_to_host_u64 (mp->segment_handle);
+ if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
+ {
+ clib_warning ("invalid segment handle");
+ goto failed;
+ }
+
+ if (mp->n_fds)
+ {
+ vec_validate (fds, mp->n_fds);
+ vl_socket_client_recv_fd_msg (fds, mp->n_fds, 5);
+
+ if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
+ if (vcl_segment_attach (vcl_vpp_worker_segment_handle (wrk_index),
+ "vpp-worker-seg", SSVM_SEGMENT_MEMFD,
+ fds[n_fds++]))
+ goto failed;
+
+ if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
+ if (vcl_segment_attach (segment_handle, (char *) mp->segment_name,
+ SSVM_SEGMENT_MEMFD, fds[n_fds++]))
+ goto failed;
+
+ if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
+ {
+ svm_msg_q_set_consumer_eventfd (wrk->app_event_queue, fds[n_fds]);
+ vcl_mq_epoll_add_evfd (wrk, wrk->app_event_queue);
+ n_fds++;
+ }
+
+ vec_free (fds);
+ }
+ else
+ {
+ if (vcl_segment_attach (segment_handle, (char *) mp->segment_name,
+ SSVM_SEGMENT_SHM, -1))
+ goto failed;
+ }
+ vcm->app_state = STATE_APP_READY;
+ VDBG (0, "worker %u vpp-worker %u added", wrk_index, wrk->vpp_wrk_index);
+ return;
+
+failed:
+ vcm->app_state = STATE_APP_FAILED;
+}
+