bonding: process lacp when bond is admin down
[vpp.git] / src / vnet / session / session_node.c
index 865c8b7..540f6e6 100644 (file)
@@ -117,6 +117,7 @@ session_mq_connect_handler (void *data)
   a->sep_ext.parent_handle = mp->parent_handle;
   a->sep_ext.ckpair_index = mp->ckpair_index;
   a->sep_ext.crypto_engine = mp->crypto_engine;
+  a->sep_ext.flags = mp->flags;
   if (mp->hostname_len)
     {
       vec_validate (a->sep_ext.hostname, mp->hostname_len - 1);
@@ -309,8 +310,8 @@ session_mq_reset_reply_handler (void *data)
   session_parse_handle (mp->handle, &index, &thread_index);
   s = session_get_if_valid (index, thread_index);
 
-  /* Session was already closed or already cleaned up */
-  if (!s || s->session_state != SESSION_STATE_TRANSPORT_CLOSING)
+  /* No session or not the right session */
+  if (!s || s->session_state < SESSION_STATE_TRANSPORT_CLOSING)
     return;
 
   app_wrk = app_worker_get (s->app_wrk_index);
@@ -873,16 +874,29 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
       return SESSION_TX_NO_DATA;
     }
 
-  ctx->snd_space = transport_connection_snd_space (ctx->tc, ctx->snd_mss);
+  ctx->snd_space = transport_connection_snd_space (ctx->tc);
 
   /* This flow queue is "empty" so it should be re-evaluated before
    * the ones that have data to send. */
-  if (ctx->snd_space == 0)
+  if (!ctx->snd_space)
     {
       session_evt_add_head_old (wrk, elt);
       return SESSION_TX_NO_DATA;
     }
 
+  if (transport_connection_is_tx_paced (ctx->tc))
+    {
+      u32 snd_space = transport_connection_tx_pacer_burst (ctx->tc);
+      if (snd_space < TRANSPORT_PACER_MIN_BURST)
+       {
+         session_evt_add_head_old (wrk, elt);
+         return SESSION_TX_NO_DATA;
+       }
+      snd_space = clib_min (ctx->snd_space, snd_space);
+      ctx->snd_space = snd_space >= ctx->snd_mss ?
+       snd_space - snd_space % ctx->snd_mss : snd_space;
+    }
+
   /* Allow enqueuing of a new event */
   svm_fifo_unset_event (ctx->s->tx_fifo);
 
@@ -891,7 +905,7 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
 
   if (PREDICT_FALSE (!ctx->max_len_to_snd))
     {
-      transport_connection_tx_pacer_reset_bucket (ctx->tc);
+      transport_connection_tx_pacer_reset_bucket (ctx->tc, 0);
       return SESSION_TX_NO_DATA;
     }
 
@@ -903,7 +917,8 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk,
     {
       if (n_bufs)
        vlib_buffer_free (vm, wrk->tx_buffers, n_bufs);
-      session_evt_add_head_old (wrk, elt);
+      if (svm_fifo_set_event (ctx->s->tx_fifo))
+       session_evt_add_head_old (wrk, elt);
       vlib_node_increment_counter (wrk->vm, node->node_index,
                                   SESSION_QUEUE_ERROR_NO_BUFFER, 1);
       return SESSION_TX_NO_BUFFERS;
@@ -1148,10 +1163,7 @@ session_event_dispatch_io (session_worker_t * wrk, vlib_node_runtime_t * node,
     case SESSION_IO_EVT_TX:
       s = session_event_get_session (e, thread_index);
       if (PREDICT_FALSE (!s))
-       {
-         clib_warning ("session %u was freed!", e->session_index);
-         break;
-       }
+       break;
       CLIB_PREFETCH (s->tx_fifo, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
       wrk->ctx.s = s;
       /* Spray packets in per session type frames, since they go to