session: fix session filter range
[vpp.git] / src / vnet / session / session.c
index 33f1e26..1010f05 100644 (file)
@@ -63,6 +63,7 @@ session_send_evt_to_thread (void *data, void *args, u32 thread_index,
       break;
     case SESSION_IO_EVT_BUILTIN_TX:
     case SESSION_CTRL_EVT_CLOSE:
+    case SESSION_CTRL_EVT_RESET:
       evt->session_handle = session_handle ((session_t *) data);
       break;
     default:
@@ -92,10 +93,10 @@ session_send_io_evt_to_thread_custom (void *data, u32 thread_index,
 int
 session_send_ctrl_evt_to_thread (session_t * s, session_evt_type_t evt_type)
 {
-  /* only event supported for now is disconnect */
-  ASSERT (evt_type == SESSION_CTRL_EVT_CLOSE);
-  return session_send_evt_to_thread (s, 0, s->thread_index,
-                                    SESSION_CTRL_EVT_CLOSE);
+  /* only events supported are disconnect and reset */
+  ASSERT (evt_type == SESSION_CTRL_EVT_CLOSE
+         || evt_type == SESSION_CTRL_EVT_RESET);
+  return session_send_evt_to_thread (s, 0, s->thread_index, evt_type);
 }
 
 void
@@ -125,6 +126,7 @@ session_add_self_custom_tx_evt (transport_connection_t * tc, u8 has_prio)
 
   s = session_get (tc->s_index, tc->thread_index);
   ASSERT (s->thread_index == vlib_get_thread_index ());
+  ASSERT (s->session_state < SESSION_STATE_TRANSPORT_DELETED);
   if (!(s->flags & SESSION_F_CUSTOM_TX))
     {
       s->flags |= SESSION_F_CUSTOM_TX;
@@ -144,7 +146,7 @@ session_add_self_custom_tx_evt (transport_connection_t * tc, u8 has_prio)
 }
 
 static void
-session_program_transport_close (session_t * s)
+session_program_transport_ctrl_evt (session_t * s, session_evt_type_t evt)
 {
   u32 thread_index = vlib_get_thread_index ();
   session_evt_elt_t *elt;
@@ -158,10 +160,10 @@ session_program_transport_close (session_t * s)
       elt = session_evt_alloc_ctrl (wrk);
       clib_memset (&elt->evt, 0, sizeof (session_event_t));
       elt->evt.session_handle = session_handle (s);
-      elt->evt.event_type = SESSION_CTRL_EVT_CLOSE;
+      elt->evt.event_type = evt;
     }
   else
-    session_send_ctrl_evt_to_thread (s, SESSION_CTRL_EVT_CLOSE);
+    session_send_ctrl_evt_to_thread (s, evt);
 }
 
 session_t *
@@ -235,7 +237,7 @@ session_delete (session_t * s)
 
   /* Delete from the main lookup table. */
   if ((rv = session_lookup_del_session (s)))
-    clib_warning ("hash delete error, rv %d", rv);
+    clib_warning ("session %u hash delete rv %d", s->session_index, rv);
 
   session_free_w_fifos (s);
 }
@@ -568,10 +570,10 @@ session_enqueue_notify (session_t * s)
 static void
 session_enqueue_notify_rpc (void *arg)
 {
-  session_handle_t sh = (session_handle_t) arg;
+  u32 session_index = pointer_to_uword (arg);
   session_t *s;
 
-  s = session_get_from_handle_if_valid (sh);
+  s = session_get_if_valid (session_index, vlib_get_thread_index ());
   if (!s)
     return;
 
@@ -586,8 +588,15 @@ void
 session_enqueue_notify_thread (session_handle_t sh)
 {
   u32 thread_index = session_thread_from_handle (sh);
+  u32 session_index = session_index_from_handle (sh);
+
+  /*
+   * Pass session index (u32) as opposed to handle (u64) in case pointers
+   * are not 64-bit.
+   */
   session_send_rpc_evt_to_thread (thread_index,
-                                 session_enqueue_notify_rpc, (void *) sh);
+                                 session_enqueue_notify_rpc,
+                                 uword_to_pointer (session_index, void *));
 }
 
 int
@@ -595,6 +604,8 @@ session_dequeue_notify (session_t * s)
 {
   app_worker_t *app_wrk;
 
+  svm_fifo_clear_deq_ntf (s->tx_fifo);
+
   app_wrk = app_worker_get_if_valid (s->app_wrk_index);
   if (PREDICT_FALSE (!app_wrk))
     return -1;
@@ -607,8 +618,6 @@ session_dequeue_notify (session_t * s)
     return session_notify_subscribers (app_wrk->app_index, s,
                                       s->tx_fifo, SESSION_IO_EVT_TX);
 
-  svm_fifo_clear_deq_ntf (s->tx_fifo);
-
   return 0;
 }
 
@@ -881,7 +890,7 @@ session_transport_delete_notify (transport_connection_t * tc)
       s->session_state = SESSION_STATE_CLOSED;
       session_cleanup_notify (s, SESSION_CLEANUP_TRANSPORT);
       svm_fifo_dequeue_drop_all (s->tx_fifo);
-      session_program_transport_close (s);
+      session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE);
       break;
     case SESSION_STATE_TRANSPORT_DELETED:
       break;
@@ -1187,12 +1196,26 @@ session_close (session_t * s)
        * acknowledge the close */
       if (s->session_state == SESSION_STATE_TRANSPORT_CLOSED
          || s->session_state == SESSION_STATE_TRANSPORT_DELETED)
-       session_program_transport_close (s);
+       session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE);
       return;
     }
 
   s->session_state = SESSION_STATE_CLOSING;
-  session_program_transport_close (s);
+  session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE);
+}
+
+/**
+ * Force a close without waiting for data to be flushed
+ */
+void
+session_reset (session_t * s)
+{
+  if (s->session_state >= SESSION_STATE_CLOSING)
+    return;
+  /* Drop all outstanding tx data */
+  svm_fifo_dequeue_drop_all (s->tx_fifo);
+  s->session_state = SESSION_STATE_CLOSING;
+  session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_RESET);
 }
 
 /**
@@ -1227,6 +1250,26 @@ session_transport_close (session_t * s)
                   s->thread_index);
 }
 
+/**
+ * Force transport close
+ */
+void
+session_transport_reset (session_t * s)
+{
+  if (s->session_state >= SESSION_STATE_APP_CLOSED)
+    {
+      if (s->session_state == SESSION_STATE_TRANSPORT_CLOSED)
+       s->session_state = SESSION_STATE_CLOSED;
+      else if (s->session_state >= SESSION_STATE_TRANSPORT_DELETED)
+       session_free_w_fifos (s);
+      return;
+    }
+
+  s->session_state = SESSION_STATE_APP_CLOSED;
+  transport_reset (session_get_transport_proto (s), s->connection_index,
+                  s->thread_index);
+}
+
 /**
  * Cleanup transport and session state.
  *