session: support local sessions and deprecate redirects
[vpp.git] / src / tests / vnet / session / udp_echo.c
index ac94118..d1363fc 100644 (file)
@@ -65,7 +65,7 @@ typedef struct
 typedef struct
 {
   /* vpe input queue */
-  unix_shared_memory_queue_t *vl_input_queue;
+  svm_queue_t *vl_input_queue;
 
   /* API client handle */
   u32 my_client_index;
@@ -91,10 +91,10 @@ typedef struct
   int i_am_master;
 
   /* Our event queue */
-  unix_shared_memory_queue_t *our_event_queue;
+  svm_queue_t *our_event_queue;
 
   /* $$$ single thread only for the moment */
-  unix_shared_memory_queue_t *vpp_event_queue;
+  svm_queue_t *vpp_event_queue;
 
   /* $$$$ hack: cut-through session index */
   volatile u32 cut_through_session_index;
@@ -126,6 +126,8 @@ typedef struct
   svm_fifo_segment_main_t *segment_main;
 
   u8 *connect_test_data;
+
+  uword *segments_table;
 } uri_udp_test_main_t;
 
 #if CLIB_DEBUG > 0
@@ -173,8 +175,9 @@ application_send_attach (uri_udp_test_main_t * utm)
   bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH);
   bmp->client_index = utm->my_client_index;
   bmp->context = ntohl (0xfeedface);
-  bmp->options[APP_OPTIONS_FLAGS] =
-    APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT;
+  bmp->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_ADD_SEGMENT;
+  bmp->options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
+  bmp->options[APP_OPTIONS_FLAGS] |= APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
   bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 2;
   bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = fifo_size;
   bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size;
@@ -202,7 +205,7 @@ vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
                                           mp)
 {
   uri_udp_test_main_t *utm = &uri_udp_test_main;
-  svm_fifo_segment_create_args_t _a, *a = &_a;
+  svm_fifo_segment_create_args_t _a = { 0 }, *a = &_a;
   int rv;
 
   if (mp->retval)
@@ -233,8 +236,7 @@ vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t *
     }
 
   utm->our_event_queue =
-    uword_to_pointer (mp->app_event_queue_address,
-                     unix_shared_memory_queue_t *);
+    uword_to_pointer (mp->app_event_queue_address, svm_queue_t *);
 }
 
 static void
@@ -309,7 +311,7 @@ cut_through_thread_fn (void *arg)
       /* We read from the tx fifo and write to the rx fifo */
       do
        {
-         actual_transfer = svm_fifo_dequeue_nowait (tx_fifo,
+         actual_transfer = svm_fifo_dequeue_nowait (rx_fifo,
                                                     vec_len (my_copy_buffer),
                                                     my_copy_buffer);
        }
@@ -320,7 +322,7 @@ cut_through_thread_fn (void *arg)
       buffer_offset = 0;
       while (actual_transfer > 0)
        {
-         rv = svm_fifo_enqueue_nowait (rx_fifo, actual_transfer,
+         rv = svm_fifo_enqueue_nowait (tx_fifo, actual_transfer,
                                        my_copy_buffer + buffer_offset);
          if (rv > 0)
            {
@@ -488,9 +490,8 @@ send_test_chunk (uri_udp_test_main_t * utm, svm_fifo_t * tx_fifo, int mypid,
              evt.fifo = tx_fifo;
              evt.event_type = FIFO_EVENT_APP_TX;
 
-             unix_shared_memory_queue_add (utm->vpp_event_queue,
-                                           (u8 *) & evt,
-                                           0 /* do wait for mutex */ );
+             svm_queue_add (utm->vpp_event_queue,
+                            (u8 *) & evt, 0 /* do wait for mutex */ );
            }
        }
     }
@@ -607,7 +608,10 @@ vl_api_bind_uri_reply_t_handler (vl_api_bind_uri_reply_t * mp)
 static void
 vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
 {
+  uri_udp_test_main_t *utm = &uri_udp_test_main;
   svm_fifo_segment_create_args_t _a, *a = &_a;
+  svm_fifo_segment_private_t *seg;
+  u8 *seg_name;
   int rv;
 
   memset (a, 0, sizeof (*a));
@@ -621,8 +625,35 @@ vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp)
                    mp->segment_name);
       return;
     }
-  clib_warning ("Mapped new segment '%s' size %d", mp->segment_name,
-               mp->segment_size);
+  seg = svm_fifo_segment_get_segment (a->new_segment_indices[0]);
+  clib_warning ("Mapped new segment '%s' size %d", seg->ssvm.name,
+               seg->ssvm.ssvm_size);
+  seg_name = format (0, "%s", (char *) mp->segment_name);
+  hash_set_mem (utm->segments_table, seg_name, a->new_segment_indices[0]);
+  vec_free (seg_name);
+}
+
+static void
+vl_api_unmap_segment_t_handler (vl_api_unmap_segment_t * mp)
+{
+  uri_udp_test_main_t *utm = &uri_udp_test_main;
+  svm_fifo_segment_private_t *seg;
+  u64 *seg_indexp;
+  u8 *seg_name;
+
+
+  seg_name = format (0, "%s", mp->segment_name);
+  seg_indexp = hash_get_mem (utm->segments_table, seg_name);
+  if (!seg_indexp)
+    {
+      clib_warning ("segment not mapped: %s", seg_name);
+      return;
+    }
+  hash_unset_mem (utm->segments_table, seg_name);
+  seg = svm_fifo_segment_get_segment ((u32) seg_indexp[0]);
+  svm_fifo_segment_delete (seg);
+  clib_warning ("Unmapped segment '%s'", seg_name);
+  vec_free (seg_name);
 }
 
 /**
@@ -636,7 +667,7 @@ vl_api_connect_uri_t_handler (vl_api_connect_uri_t * mp)
   svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
   svm_fifo_segment_create_args_t _a, *a = &_a;
   svm_fifo_segment_private_t *seg;
-  unix_shared_memory_queue_t *client_q;
+  svm_queue_t *client_q;
   vl_api_connect_session_reply_t *rmp;
   session_t *session = 0;
   int rv = 0;
@@ -699,8 +730,7 @@ send_reply:
 
   vec_free (a->segment_name);
 
-  client_q =
-    uword_to_pointer (mp->client_queue_address, unix_shared_memory_queue_t *);
+  client_q = uword_to_pointer (mp->client_queue_address, svm_queue_t *);
   vl_msg_api_send_shmem (client_q, (u8 *) & rmp);
 }
 
@@ -723,27 +753,51 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
   svm_fifo_t *rx_fifo, *tx_fifo;
   session_t *session;
   static f64 start_time;
+  u32 session_index;
+  int rv = 0;
 
   if (start_time == 0.0)
     start_time = clib_time_now (&utm->clib_time);
 
   utm->vpp_event_queue =
-    uword_to_pointer (mp->vpp_event_queue_address,
-                     unix_shared_memory_queue_t *);
-
-  pool_get (utm->sessions, session);
+    uword_to_pointer (mp->vpp_event_queue_address, svm_queue_t *);
 
   rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
-  rx_fifo->client_session_index = session - utm->sessions;
   tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
-  tx_fifo->client_session_index = session - utm->sessions;
 
-  session->server_rx_fifo = rx_fifo;
-  session->server_tx_fifo = tx_fifo;
+  pool_get (utm->sessions, session);
+  memset (session, 0, sizeof (*session));
+  session_index = session - utm->sessions;
 
-  hash_set (utm->session_index_by_vpp_handles, mp->handle,
-           session - utm->sessions);
+  /* Cut-through case */
+  if (mp->server_event_queue_address)
+    {
+      clib_warning ("cut-through session");
+      utm->our_event_queue = uword_to_pointer (mp->server_event_queue_address,
+                                              svm_queue_t *);
+      rx_fifo->master_session_index = session_index;
+      tx_fifo->master_session_index = session_index;
+      utm->cut_through_session_index = session_index;
+      session->server_rx_fifo = rx_fifo;
+      session->server_tx_fifo = tx_fifo;
+
+      rv = pthread_create (&utm->cut_through_thread_handle,
+                          NULL /*attr */ , cut_through_thread_fn, 0);
+      if (rv)
+       {
+         clib_warning ("pthread_create returned %d", rv);
+         rv = VNET_API_ERROR_SYSCALL_ERROR_1;
+       }
+    }
+  else
+    {
+      rx_fifo->client_session_index = session_index;
+      tx_fifo->client_session_index = session_index;
+      session->server_rx_fifo = rx_fifo;
+      session->server_tx_fifo = tx_fifo;
+    }
 
+  hash_set (utm->session_index_by_vpp_handles, mp->handle, session_index);
   if (pool_elts (utm->sessions) && (pool_elts (utm->sessions) % 20000) == 0)
     {
       f64 now = clib_time_now (&utm->clib_time);
@@ -757,6 +811,7 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp)
   rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY);
   rmp->handle = mp->handle;
   rmp->context = mp->context;
+  rmp->retval = rv;
   vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & rmp);
 
   CLIB_MEMORY_BARRIER ();
@@ -791,6 +846,7 @@ vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp)
   rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY);
   rmp->retval = rv;
   rmp->handle = mp->handle;
+  rmp->context = mp->context;
   vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & rmp);
 }
 
@@ -808,34 +864,6 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
       return;
     }
 
-  /* We've been redirected */
-  if (mp->segment_name_length > 0)
-    {
-      svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
-      svm_fifo_segment_create_args_t _a, *a = &_a;
-      u32 segment_index;
-      svm_fifo_segment_private_t *seg;
-      int rv;
-
-      memset (a, 0, sizeof (*a));
-      a->segment_name = (char *) mp->segment_name;
-
-      sleep (1);
-
-      rv = svm_fifo_segment_attach (a);
-      if (rv)
-       {
-         clib_warning ("sm_fifo_segment_create ('%v') failed",
-                       mp->segment_name);
-         return;
-       }
-
-      segment_index = a->new_segment_indices[0];
-      vec_add2 (utm->seg, seg, 1);
-      memcpy (seg, sm->segments + segment_index, sizeof (*seg));
-      sleep (1);
-    }
-
   pool_get (utm->sessions, session);
   session->server_rx_fifo = uword_to_pointer (mp->server_rx_fifo,
                                              svm_fifo_t *);
@@ -844,18 +872,26 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp)
                                              svm_fifo_t *);
   ASSERT (session->server_tx_fifo);
 
-  if (mp->segment_name_length > 0)
-    utm->cut_through_session_index = session - utm->sessions;
+  /* Cut-through case */
+  if (mp->client_event_queue_address)
+    {
+      clib_warning ("cut-through session");
+      utm->cut_through_session_index = session - utm->sessions;
+      utm->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
+                                              svm_queue_t *);
+      utm->our_event_queue = uword_to_pointer (mp->client_event_queue_address,
+                                              svm_queue_t *);
+    }
   else
     {
       utm->connected_session = session - utm->sessions;
       utm->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address,
-                                              unix_shared_memory_queue_t *);
+                                              svm_queue_t *);
     }
   utm->state = STATE_READY;
 }
 
-#define foreach_uri_msg                                \
+#define foreach_tcp_echo_msg                           \
 _(BIND_URI_REPLY, bind_uri_reply)                      \
 _(CONNECT_URI, connect_uri)                            \
 _(CONNECT_SESSION_REPLY, connect_session_reply)        \
@@ -863,11 +899,12 @@ _(UNBIND_URI_REPLY, unbind_uri_reply)             \
 _(ACCEPT_SESSION, accept_session)                      \
 _(DISCONNECT_SESSION, disconnect_session)              \
 _(MAP_ANOTHER_SEGMENT, map_another_segment)            \
+_(UNMAP_SEGMENT, unmap_segment)                                \
 _(APPLICATION_ATTACH_REPLY, application_attach_reply)  \
 _(APPLICATION_DETACH_REPLY, application_detach_reply)  \
 
 void
-uri_api_hookup (uri_udp_test_main_t * utm)
+tcp_echo_api_hookup (uri_udp_test_main_t * utm)
 {
 #define _(N,n)                                                  \
     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
@@ -876,7 +913,7 @@ uri_api_hookup (uri_udp_test_main_t * utm)
                            vl_api_##n##_t_endian,               \
                            vl_api_##n##_t_print,                \
                            sizeof(vl_api_##n##_t), 1);
-  foreach_uri_msg;
+  foreach_tcp_echo_msg;
 #undef _
 
 }
@@ -921,7 +958,7 @@ server_handle_fifo_event_rx (uri_udp_test_main_t * utm,
   svm_fifo_t *rx_fifo, *tx_fifo;
   int nbytes;
   session_fifo_event_t evt;
-  unix_shared_memory_queue_t *q;
+  svm_queue_t *q;
   int rv;
 
   rx_fifo = e->fifo;
@@ -946,8 +983,7 @@ server_handle_fifo_event_rx (uri_udp_test_main_t * utm,
       evt.fifo = tx_fifo;
       evt.event_type = FIFO_EVENT_APP_TX;
       q = utm->vpp_event_queue;
-      unix_shared_memory_queue_add (q, (u8 *) & evt,
-                                   0 /* do wait for mutex */ );
+      svm_queue_add (q, (u8 *) & evt, 0 /* do wait for mutex */ );
     }
 }
 
@@ -961,8 +997,7 @@ server_handle_event_queue (uri_udp_test_main_t * utm)
 
   while (1)
     {
-      unix_shared_memory_queue_sub (utm->our_event_queue, (u8 *) e,
-                                   0 /* nowait */ );
+      svm_queue_sub (utm->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0);
       switch (e->event_type)
        {
        case FIFO_EVENT_APP_RX:
@@ -1050,15 +1085,16 @@ int
 main (int argc, char **argv)
 {
   uri_udp_test_main_t *utm = &uri_udp_test_main;
+  u8 *bind_name = (u8 *) "udp://0.0.0.0/1234";
   unformat_input_t _argv, *a = &_argv;
+  int i_am_master = 1;
+  session_t *session;
   u8 *chroot_prefix;
+  char *app_name;
+  mheap_t *h;
   u8 *heap;
-  u8 *bind_name = (u8 *) "udp://0.0.0.0/1234";
   u32 tmp;
-  mheap_t *h;
-  session_t *session;
   int i;
-  int i_am_master = 1;
 
   clib_mem_init (0, 256 << 20);
 
@@ -1071,13 +1107,13 @@ main (int argc, char **argv)
   vec_validate (utm->rx_buf, 8192);
 
   utm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
-
   utm->my_pid = getpid ();
   utm->configured_segment_size = 1 << 20;
+  utm->segments_table = hash_create_vec (0, sizeof (u8), sizeof (u64));
 
   clib_time_init (&utm->clib_time);
   init_error_string_table (utm);
-  svm_fifo_segment_init (0x200000000ULL, 20);
+  svm_fifo_segment_main_init (0x200000000ULL, 20);
   unformat_init_command_line (a, argv);
 
   while (unformat_check_input (a) != UNFORMAT_END_OF_INPUT)
@@ -1107,14 +1143,13 @@ main (int argc, char **argv)
   utm->uri = format (0, "%s%c", bind_name, 0);
   utm->i_am_master = i_am_master;
   utm->segment_main = &svm_fifo_segment_main;
-
   utm->connect_uri = format (0, "udp://6.0.1.2/1234%c", 0);
 
   setup_signal_handlers ();
+  tcp_echo_api_hookup (utm);
 
-  uri_api_hookup (utm);
-
-  if (connect_to_vpp (i_am_master ? "uri_udp_master" : "uri_udp_slave") < 0)
+  app_name = i_am_master ? "udp_echo_master" : "udp_echo_slave";
+  if (connect_to_vpp (app_name) < 0)
     {
       svm_region_exit ();
       fformat (stderr, "Couldn't connect to vpe, exiting...\n");