aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/session
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-07-18 05:38:03 -0400
committerFlorin Coras <fcoras@cisco.com>2017-07-21 19:20:09 -0400
commit6534b7aa13bc5bed15ed87f47bb766405963e9e8 (patch)
tree999524eff2a5c811ef61e65354e6018c8ae3de33 /src/vnet/session
parent161c59c75c667ce7a3c1d6173723831dc30e994c (diff)
Improvements to tcp rx path and debugging
- Increment rcv_nxt for fin packets - Call tcp_segment_rcv only if buffer has data - Parse rcv opts before deleting half-open connection - Fix initial rcv_wnd - Improved event logging Change-Id: I9b83c04f432c4cec832c480b03e534deff02c3b1 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/session')
-rw-r--r--src/vnet/session/node.c73
-rw-r--r--src/vnet/session/session.c38
-rw-r--r--src/vnet/session/session.h4
-rwxr-xr-xsrc/vnet/session/session_api.c7
-rwxr-xr-xsrc/vnet/session/session_cli.c22
5 files changed, 130 insertions, 14 deletions
diff --git a/src/vnet/session/node.c b/src/vnet/session/node.c
index 983b78b8..8d703b0b 100644
--- a/src/vnet/session/node.c
+++ b/src/vnet/session/node.c
@@ -443,6 +443,79 @@ dump_thread_0_event_queue (void)
}
}
+static u8
+session_node_cmp_event (session_fifo_event_t * e, svm_fifo_t * f)
+{
+ stream_session_t *s;
+ switch (e->event_type)
+ {
+ case FIFO_EVENT_APP_RX:
+ case FIFO_EVENT_APP_TX:
+ case FIFO_EVENT_BUILTIN_RX:
+ if (e->fifo == f)
+ return 1;
+ break;
+ case FIFO_EVENT_DISCONNECT:
+ break;
+ case FIFO_EVENT_RPC:
+ s = stream_session_get_from_handle (e->session_handle);
+ if (!s)
+ {
+ clib_warning ("session has event but doesn't exist!");
+ break;
+ }
+ if (s->server_rx_fifo == f || s->server_tx_fifo == f)
+ return 1;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+u8
+session_node_lookup_fifo_event (svm_fifo_t * f, session_fifo_event_t * e)
+{
+ session_manager_main_t *smm = vnet_get_session_manager_main ();
+ unix_shared_memory_queue_t *q;
+ session_fifo_event_t *pending_event_vector, *evt;
+ int i, index, found = 0;
+ i8 *headp;
+ u8 thread_index;
+
+ ASSERT (e);
+ thread_index = f->master_thread_index;
+ /*
+ * Search evt queue
+ */
+ q = smm->vpp_event_queues[thread_index];
+ index = q->head;
+ for (i = 0; i < q->cursize; i++)
+ {
+ headp = (i8 *) (&q->data[0] + q->elsize * index);
+ clib_memcpy (e, headp, q->elsize);
+ found = session_node_cmp_event (e, f);
+ if (found)
+ break;
+ if (++index == q->maxsize)
+ index = 0;
+ }
+ /*
+ * Search pending events vector
+ */
+ pending_event_vector = smm->pending_event_vector[thread_index];
+ vec_foreach (evt, pending_event_vector)
+ {
+ found = session_node_cmp_event (evt, f);
+ if (found)
+ {
+ clib_memcpy (e, evt, sizeof (*evt));
+ break;
+ }
+ }
+ return found;
+}
+
static uword
session_queue_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 2c2a27c1..09bc00e7 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -32,6 +32,22 @@ static transport_proto_vft_t *tp_vfts;
session_manager_main_t session_manager_main;
+transport_connection_t *
+stream_session_lookup_half_open (transport_connection_t * tc)
+{
+ session_manager_main_t *smm = &session_manager_main;
+ session_kv4_t kv4;
+ int rv;
+ if (tc->is_ip4)
+ {
+ make_v4_ss_kv_from_tc (&kv4, tc);
+ rv = clib_bihash_search_inline_16_8 (&smm->v4_half_open_hash, &kv4);
+ if (rv == 0)
+ return tp_vfts[tc->proto].get_half_open (kv4.value & 0xFFFFFFFFULL);
+ }
+ return 0;
+}
+
/*
* Session lookup key; (src-ip, dst-ip, src-port, dst-port, session-type)
* Value: (owner thread index << 32 | session_index);
@@ -501,7 +517,7 @@ stream_session_create_i (segment_manager_t * sm, transport_connection_t * tc,
tc->s_index = s->session_index;
/* Add to the main lookup table */
- value = (((u64) thread_index) << 32) | (u64) s->session_index;
+ value = stream_session_handle (s);
stream_session_table_add_for_tc (tc, value);
*ret_s = s;
@@ -817,8 +833,18 @@ stream_session_connect_notify (transport_connection_t * tc, u8 sst,
}
/* Notify client */
- app->cb_fns.session_connected_callback (app->index, api_context, new_s,
- is_fail);
+ if (app->cb_fns.session_connected_callback (app->index, api_context, new_s,
+ is_fail))
+ {
+ clib_warning ("failed to notify app");
+ if (!is_fail)
+ stream_session_disconnect (new_s);
+ }
+ else
+ {
+ if (!is_fail)
+ new_s->session_state = SESSION_STATE_READY;
+ }
/* Cleanup session lookup */
stream_session_half_open_table_del (smm, sst, tc);
@@ -862,15 +888,19 @@ void
stream_session_delete (stream_session_t * s)
{
session_manager_main_t *smm = vnet_get_session_manager_main ();
+ int rv;
/* Delete from the main lookup table. */
- stream_session_table_del (smm, s);
+ if ((rv = stream_session_table_del (smm, s)))
+ clib_warning ("hash delete error, rv %d", rv);
/* Cleanup fifo segments */
segment_manager_dealloc_fifos (s->svm_segment_index, s->server_rx_fifo,
s->server_tx_fifo);
pool_put (smm->sessions[s->thread_index], s);
+ if (CLIB_DEBUG)
+ memset (s, 0xFA, sizeof (*s));
}
/**
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index 6069c574..6c616326 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -170,6 +170,8 @@ typedef int
extern session_fifo_rx_fn session_tx_fifo_peek_and_snd;
extern session_fifo_rx_fn session_tx_fifo_dequeue_and_snd;
+u8 session_node_lookup_fifo_event (svm_fifo_t * f, session_fifo_event_t * e);
+
struct _session_manager_main
{
/** Lookup tables for established sessions and listeners */
@@ -289,6 +291,8 @@ transport_connection_t *stream_session_lookup_transport6 (ip6_address_t * lcl,
stream_session_t *stream_session_lookup_listener (ip46_address_t * lcl,
u16 lcl_port, u8 proto);
+transport_connection_t
+ * stream_session_lookup_half_open (transport_connection_t * tc);
void stream_session_table_add_for_tc (transport_connection_t * tc, u64 value);
int stream_session_table_del_for_tc (transport_connection_t * tc);
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 60f764af..6bee3e27 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -184,13 +184,6 @@ send_session_connected_callback (u32 app_index, u32 api_context,
}
vl_msg_api_send_shmem (q, (u8 *) & mp);
-
- /* Remove client if connect failed */
- if (!is_fail)
- {
- s->session_state = SESSION_STATE_READY;
- }
-
return 0;
}
diff --git a/src/vnet/session/session_cli.c b/src/vnet/session/session_cli.c
index e8e6f99c..4d432977 100755
--- a/src/vnet/session/session_cli.c
+++ b/src/vnet/session/session_cli.c
@@ -19,8 +19,24 @@ u8 *
format_stream_session_fifos (u8 * s, va_list * args)
{
stream_session_t *ss = va_arg (*args, stream_session_t *);
+ int verbose = va_arg (*args, int);
+ session_fifo_event_t _e, *e = &_e;
+ u8 found;
+
s = format (s, " Rx fifo: %U", format_svm_fifo, ss->server_rx_fifo, 1);
+ if (verbose > 2 && ss->server_rx_fifo->has_event)
+ {
+ found = session_node_lookup_fifo_event (ss->server_rx_fifo, e);
+ s = format (s, " session node event: %s\n",
+ found ? "found" : "not found");
+ }
s = format (s, " Tx fifo: %U", format_svm_fifo, ss->server_tx_fifo, 1);
+ if (verbose > 2 && ss->server_tx_fifo->has_event)
+ {
+ found = session_node_lookup_fifo_event (ss->server_tx_fifo, e);
+ s = format (s, " session node event: %s\n",
+ found ? "found" : "not found");
+ }
return s;
}
@@ -55,7 +71,7 @@ format_stream_session (u8 * s, va_list * args)
if (verbose == 1)
s = format (s, "%v", str);
if (verbose > 1)
- s = format (s, "%U", format_stream_session_fifos, ss);
+ s = format (s, "%U", format_stream_session_fifos, ss, verbose);
}
else if (ss->session_state == SESSION_STATE_LISTENING)
{
@@ -75,7 +91,7 @@ format_stream_session (u8 * s, va_list * args)
if (verbose == 1)
s = format (s, "%v", str);
if (verbose > 1)
- s = format (s, "%U", format_stream_session_fifos, ss);
+ s = format (s, "%U", format_stream_session_fifos, ss, verbose);
}
else
{
@@ -248,7 +264,7 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
if (one_session)
{
- vlib_cli_output (vm, "%U", format_stream_session, s, 2);
+ vlib_cli_output (vm, "%U", format_stream_session, s, 3);
return 0;
}