summaryrefslogtreecommitdiffstats
path: root/src/vnet/session/session.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2017-10-02 00:18:51 -0700
committerDave Barach <openvpp@barachs.net>2017-10-10 20:42:50 +0000
commitcea194d8f973a2f2b5ef72d212533057174cc70a (patch)
tree6fdd2e8a929c62625d1ad35bfbec342129989aef /src/vnet/session/session.c
parent1f36a93d3d68f5ba6dcda08809394ce757cefd72 (diff)
session: add support for application namespacing
Applications are now provided the option to select the namespace they are to be attached to and the scope of their attachement. Application namespaces are meant to: 1) constrain the scope of communication through the network by association with source interfaces and/or fib tables that provide the source ips to be used and limit the scope of routing 2) provide a namespace local scope to session layer communication, as opposed to the global scope provided by 1). That is, sessions can be established without assistance from transport and network layers. Albeit, zero/local-host ip addresses must still be provided in session establishment messages due to existing application idiosyncrasies. This mode of communication uses shared-memory fifos (cut-through sessions) exclusively. If applications request no namespace, they are assigned to the default one, which at its turn uses the default fib. Applications can request access to both local and global scopes for a namespace. If no scope is specified, session layer defaults to the global one. When a sw_if_index is provided for a namespace, zero-ip (INADDR_ANY) binds are converted to binds to the requested interface. Change-Id: Ia0f660bbf7eec7f89673f75b4821fc7c3d58e3d1 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet/session/session.c')
-rw-r--r--src/vnet/session/session.c91
1 files changed, 56 insertions, 35 deletions
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index dc930ce87d3..88b38f15a61 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -85,7 +85,7 @@ stream_session_create_i (segment_manager_t * sm, transport_connection_t * tc,
/* Add to the main lookup table */
value = stream_session_handle (s);
- stream_session_table_add_for_tc (tc, value);
+ session_lookup_add_connection (tc, value);
*ret_s = s;
@@ -223,7 +223,7 @@ stream_session_enqueue_data (transport_connection_t * tc, vlib_buffer_t * b,
stream_session_t *s;
int enqueued = 0, rv, in_order_off;
- s = stream_session_get (tc->s_index, tc->thread_index);
+ s = session_get (tc->s_index, tc->thread_index);
if (is_in_order)
{
@@ -275,7 +275,7 @@ u8
stream_session_no_space (transport_connection_t * tc, u32 thread_index,
u16 data_len)
{
- stream_session_t *s = stream_session_get (tc->s_index, thread_index);
+ stream_session_t *s = session_get (tc->s_index, thread_index);
if (PREDICT_FALSE (s->session_state != SESSION_STATE_READY))
return 1;
@@ -289,7 +289,7 @@ stream_session_no_space (transport_connection_t * tc, u32 thread_index,
u32
stream_session_tx_fifo_max_dequeue (transport_connection_t * tc)
{
- stream_session_t *s = stream_session_get (tc->s_index, tc->thread_index);
+ stream_session_t *s = session_get (tc->s_index, tc->thread_index);
if (!s->server_tx_fifo)
return 0;
return svm_fifo_max_dequeue (s->server_tx_fifo);
@@ -299,14 +299,14 @@ int
stream_session_peek_bytes (transport_connection_t * tc, u8 * buffer,
u32 offset, u32 max_bytes)
{
- stream_session_t *s = stream_session_get (tc->s_index, tc->thread_index);
+ stream_session_t *s = session_get (tc->s_index, tc->thread_index);
return svm_fifo_peek (s->server_tx_fifo, offset, max_bytes, buffer);
}
u32
stream_session_dequeue_drop (transport_connection_t * tc, u32 max_bytes)
{
- stream_session_t *s = stream_session_get (tc->s_index, tc->thread_index);
+ stream_session_t *s = session_get (tc->s_index, tc->thread_index);
return svm_fifo_dequeue_drop (s->server_tx_fifo, max_bytes);
}
@@ -432,7 +432,7 @@ stream_session_init_fifos_pointers (transport_connection_t * tc,
u32 rx_pointer, u32 tx_pointer)
{
stream_session_t *s;
- s = stream_session_get (tc->s_index, tc->thread_index);
+ s = session_get (tc->s_index, tc->thread_index);
svm_fifo_init_pointers (s->server_rx_fifo, rx_pointer);
svm_fifo_init_pointers (s->server_tx_fifo, tx_pointer);
}
@@ -445,20 +445,16 @@ stream_session_connect_notify (transport_connection_t * tc, u8 is_fail)
u64 handle;
u32 opaque = 0;
int error = 0;
- u8 st;
- st = session_type_from_proto_and_ip (tc->transport_proto, tc->is_ip4);
- handle = stream_session_half_open_lookup_handle (&tc->lcl_ip, &tc->rmt_ip,
- tc->lcl_port, tc->rmt_port,
- st);
+ handle = session_lookup_half_open_handle (tc);
if (handle == HALF_OPEN_LOOKUP_INVALID_VALUE)
{
- TCP_DBG ("half-open was removed!");
+ SESSION_DBG ("half-open was removed!");
return -1;
}
/* Cleanup half-open table */
- stream_session_half_open_table_del (tc);
+ session_lookup_del_half_open (tc);
/* Get the app's index from the handle we stored when opening connection
* and the opaque (api_context for external apps) from transport session
@@ -489,7 +485,7 @@ stream_session_connect_notify (transport_connection_t * tc, u8 is_fail)
if (app->cb_fns.session_connected_callback (app->index, opaque, new_s,
is_fail))
{
- clib_warning ("failed to notify app");
+ SESSION_DBG ("failed to notify app");
if (!is_fail)
stream_session_disconnect (new_s);
}
@@ -508,7 +504,7 @@ stream_session_accept_notify (transport_connection_t * tc)
application_t *server;
stream_session_t *s;
- s = stream_session_get (tc->s_index, tc->thread_index);
+ s = session_get (tc->s_index, tc->thread_index);
server = application_get (s->app_index);
server->cb_fns.session_accept_callback (s);
}
@@ -526,7 +522,7 @@ stream_session_disconnect_notify (transport_connection_t * tc)
application_t *server;
stream_session_t *s;
- s = stream_session_get (tc->s_index, tc->thread_index);
+ s = session_get (tc->s_index, tc->thread_index);
server = application_get (s->app_index);
server->cb_fns.session_disconnect_callback (s);
}
@@ -541,7 +537,7 @@ stream_session_delete (stream_session_t * s)
int rv;
/* Delete from the main lookup table. */
- if ((rv = stream_session_table_del (s)))
+ if ((rv = session_lookup_del_session (s)))
clib_warning ("hash delete error, rv %d", rv);
/* Cleanup fifo segments */
@@ -581,7 +577,7 @@ stream_session_reset_notify (transport_connection_t * tc)
{
stream_session_t *s;
application_t *app;
- s = stream_session_get (tc->s_index, tc->thread_index);
+ s = session_get (tc->s_index, tc->thread_index);
app = application_get (s->app_index);
app->cb_fns.session_reset_callback (s);
@@ -592,14 +588,16 @@ stream_session_reset_notify (transport_connection_t * tc)
*/
int
stream_session_accept (transport_connection_t * tc, u32 listener_index,
- u8 sst, u8 notify)
+ u8 notify)
{
application_t *server;
stream_session_t *s, *listener;
segment_manager_t *sm;
-
+ session_type_t sst;
int rv;
+ sst = session_type_from_proto_and_ip (tc->transport_proto, tc->is_ip4);
+
/* Find the server */
listener = listen_session_get (sst, listener_index);
server = application_get (listener->app_index);
@@ -634,22 +632,23 @@ stream_session_accept (transport_connection_t * tc, u32 listener_index,
* @param res Resulting transport connection .
*/
int
-stream_session_open (u32 app_index, session_type_t st,
- transport_endpoint_t * rmt,
+stream_session_open (u32 app_index, session_endpoint_t * rmt,
transport_connection_t ** res)
{
transport_connection_t *tc;
+ session_type_t sst;
int rv;
u64 handle;
- rv = tp_vfts[st].open (rmt);
+ sst = session_type_from_proto_and_ip (rmt->transport_proto, rmt->is_ip4);
+ rv = tp_vfts[sst].open (session_endpoint_to_transport (rmt));
if (rv < 0)
{
clib_warning ("Transport failed to open connection.");
- return VNET_API_ERROR_SESSION_CONNECT_FAIL;
+ return VNET_API_ERROR_SESSION_CONNECT;
}
- tc = tp_vfts[st].get_half_open ((u32) rv);
+ tc = tp_vfts[sst].get_half_open ((u32) rv);
/* Save app and tc index. The latter is needed to help establish the
* connection while the former is needed when the connect notify comes
@@ -657,7 +656,7 @@ stream_session_open (u32 app_index, session_type_t st,
handle = (((u64) app_index) << 32) | (u64) tc->c_index;
/* Add to the half-open lookup table */
- stream_session_half_open_table_add (tc, handle);
+ session_lookup_add_half_open (tc, handle);
*res = tc;
@@ -673,13 +672,14 @@ stream_session_open (u32 app_index, session_type_t st,
* @param tep Local endpoint to be listened on.
*/
int
-stream_session_listen (stream_session_t * s, transport_endpoint_t * tep)
+stream_session_listen (stream_session_t * s, session_endpoint_t * tep)
{
transport_connection_t *tc;
u32 tci;
/* Transport bind/listen */
- tci = tp_vfts[s->session_type].bind (s->session_index, tep);
+ tci = tp_vfts[s->session_type].bind (s->session_index,
+ session_endpoint_to_transport (tep));
if (tci == (u32) ~ 0)
return -1;
@@ -693,7 +693,7 @@ stream_session_listen (stream_session_t * s, transport_endpoint_t * tep)
return -1;
/* Add to the main lookup table */
- stream_session_table_add_for_tc (tc, s->session_index);
+ session_lookup_add_connection (tc, s->session_index);
return 0;
}
@@ -721,7 +721,7 @@ stream_session_stop_listen (stream_session_t * s)
return VNET_API_ERROR_ADDRESS_NOT_IN_USE;
}
- stream_session_table_del_for_tc (tc);
+ session_lookup_del_connection (tc);
tp_vfts[s->session_type].unbind (s->connection_index);
return 0;
}
@@ -780,7 +780,7 @@ stream_session_cleanup (stream_session_t * s)
s->session_state = SESSION_STATE_CLOSED;
/* Delete from the main lookup table to avoid more enqueues */
- rv = stream_session_table_del (s);
+ rv = session_lookup_del_session (s);
if (rv)
clib_warning ("hash delete error, rv %d", rv);
@@ -837,6 +837,26 @@ session_type_from_proto_and_ip (transport_proto_t proto, u8 is_ip4)
return SESSION_N_TYPES;
}
+int
+listen_session_get_local_session_endpoint (stream_session_t * listener,
+ session_endpoint_t * sep)
+{
+ transport_connection_t *tc;
+ tc =
+ tp_vfts[listener->session_type].get_listener (listener->connection_index);
+ if (!tc)
+ {
+ clib_warning ("no transport");
+ return -1;
+ }
+
+ /* N.B. The ip should not be copied because this is the local endpoint */
+ sep->port = tc->lcl_port;
+ sep->transport_proto = tc->transport_proto;
+ sep->is_ip4 = tc->is_ip4;
+ return 0;
+}
+
static clib_error_t *
session_manager_main_enable (vlib_main_t * vm)
{
@@ -903,6 +923,7 @@ session_manager_main_enable (vlib_main_t * vm)
}
session_lookup_init ();
+ app_namespaces_init ();
smm->is_enabled = 1;
@@ -927,14 +948,14 @@ session_node_enable_disable (u8 is_en)
clib_error_t *
vnet_session_enable_disable (vlib_main_t * vm, u8 is_en)
{
+ clib_error_t *error = 0;
if (is_en)
{
if (session_manager_main.is_enabled)
return 0;
session_node_enable_disable (is_en);
-
- return session_manager_main_enable (vm);
+ error = session_manager_main_enable (vm);
}
else
{
@@ -942,7 +963,7 @@ vnet_session_enable_disable (vlib_main_t * vm, u8 is_en)
session_node_enable_disable (is_en);
}
- return 0;
+ return error;
}
clib_error_t *