+ es_err ("test bytes not supported for more sessions; turning it off");
+ c->test_bytes = 0;
+ }
+ esm->byte_index = 0;
+
+ return 0;
+}
+
+static void
+echo_server_ctrl_reply (session_t *s)
+{
+ echo_server_main_t *esm = &echo_server_main;
+ int rv;
+
+ rv = svm_fifo_enqueue (s->tx_fifo, sizeof (esm->cfg), (u8 *) &esm->cfg);
+ ASSERT (rv == sizeof (esm->cfg));
+ session_send_io_evt_to_thread_custom (&s->session_index, s->thread_index,
+ SESSION_IO_EVT_TX);
+}
+
+static int
+es_test_cmd_sync (echo_server_main_t *esm, session_t *s)
+{
+ int rv;
+
+ rv = echo_server_setup_test (&esm->cfg);
+ if (rv)
+ es_err ("setup test error!");
+
+ echo_server_ctrl_reply (s);
+ return 0;
+}
+
+static int
+es_wrk_cleanup_session (void *args)
+{
+ echo_server_main_t *esm = &echo_server_main;
+ u32 thread_index = pointer_to_uword (args);
+ session_handle_t *session_handles, *sh;
+ vnet_disconnect_args_t _a = {}, *a = &_a;
+
+ a->app_index = esm->app_index;
+
+ session_handles = esm->session_handles[thread_index];
+
+ vec_foreach (sh, session_handles)
+ {
+ a->handle = sh[0];
+ vnet_disconnect_session (a);
+ }
+ vec_reset_length (session_handles);
+ return 0;
+}
+
+static int
+echo_server_rx_ctrl_callback (session_t *s)
+{
+ echo_server_main_t *esm = &echo_server_main;
+ int rv;
+
+ rv = svm_fifo_dequeue (s->rx_fifo, sizeof (esm->cfg), (u8 *) &esm->cfg);
+ ASSERT (rv == sizeof (esm->cfg));
+
+ es_dbg ("control message received:");
+ if (esm->cfg.verbose)
+ hs_test_cfg_dump (&esm->cfg, 0);
+
+ switch (esm->cfg.cmd)
+ {
+ case HS_TEST_CMD_SYNC:
+ switch (esm->cfg.test)