summaryrefslogtreecommitdiffstats
path: root/src/vnet/session/session_api.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_api.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_api.c')
-rwxr-xr-xsrc/vnet/session/session_api.c153
1 files changed, 119 insertions, 34 deletions
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 60d9b4de51b..5bfca7be6fc 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -47,10 +47,11 @@ _(DISCONNECT_SESSION, disconnect_session) \
_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
_(ACCEPT_SESSION_REPLY, accept_session_reply) \
_(RESET_SESSION_REPLY, reset_session_reply) \
-_(BIND_SOCK, bind_sock) \
+_(BIND_SOCK, bind_sock) \
_(UNBIND_SOCK, unbind_sock) \
_(CONNECT_SOCK, connect_sock) \
_(SESSION_ENABLE_DISABLE, session_enable_disable) \
+_(APP_NAMESPACE_ADD_DEL, app_namespace_add_del) \
static int
send_add_segment_callback (u32 api_client_index, const u8 * segment_name,
@@ -180,7 +181,7 @@ send_session_connected_callback (u32 app_index, u32 api_context,
}
else
{
- mp->retval = clib_host_to_net_u32 (VNET_API_ERROR_SESSION_CONNECT_FAIL);
+ mp->retval = clib_host_to_net_u32 (VNET_API_ERROR_SESSION_CONNECT);
}
vl_msg_api_send_shmem (q, (u8 *) & mp);
@@ -195,7 +196,7 @@ send_session_connected_callback (u32 app_index, u32 api_context,
static int
redirect_connect_callback (u32 server_api_client_index, void *mp_arg)
{
- vl_api_connect_uri_t *mp = mp_arg;
+ vl_api_connect_sock_t *mp = mp_arg;
unix_shared_memory_queue_t *server_q, *client_q;
vlib_main_t *vm = vlib_get_main ();
f64 timeout = vlib_time_now (vm) + 0.5;
@@ -242,7 +243,7 @@ redirect_connect_callback (u32 server_api_client_index, void *mp_arg)
{
/* correctly enqueued */
case 0:
- return VNET_CONNECT_REDIRECTED;
+ return VNET_API_ERROR_SESSION_REDIRECT;
/* continue spinning, wait for pthread_mutex_trylock to work */
case -1:
@@ -260,7 +261,7 @@ out:
return rv;
}
-static session_cb_vft_t uri_session_cb_vft = {
+static session_cb_vft_t session_cb_vft = {
.session_accept_callback = send_session_accept_callback,
.session_disconnect_callback = send_session_disconnect_callback,
.session_connected_callback = send_session_connected_callback,
@@ -285,7 +286,8 @@ vl_api_application_attach_t_handler (vl_api_application_attach_t * mp)
{
vl_api_application_attach_reply_t *rmp;
vnet_app_attach_args_t _a, *a = &_a;
- int rv;
+ clib_error_t *error = 0;
+ int rv = 0;
if (session_manager_is_enabled () == 0)
{
@@ -298,12 +300,28 @@ vl_api_application_attach_t_handler (vl_api_application_attach_t * mp)
"Out of options, fix api message definition");
memset (a, 0, sizeof (*a));
-
a->api_client_index = mp->client_index;
a->options = mp->options;
- a->session_cb_vft = &uri_session_cb_vft;
+ a->session_cb_vft = &session_cb_vft;
- rv = vnet_application_attach (a);
+ if (mp->namespace_id_len > 64)
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto done;
+ }
+
+ if (mp->namespace_id_len)
+ {
+ vec_validate (a->namespace_id, mp->namespace_id_len);
+ clib_memcpy (a->namespace_id, mp->namespace_id, mp->namespace_id_len);
+ }
+
+ if ((error = vnet_application_attach (a)))
+ {
+ rv = clib_error_get_code (error);
+ clib_error_report (error);
+ }
+ vec_free (a->namespace_id);
done:
@@ -312,7 +330,6 @@ done:
if (!rv)
{
rmp->segment_name_length = 0;
- /* $$$$ policy? */
rmp->segment_size = a->segment_size;
if (a->segment_name_length)
{
@@ -418,7 +435,8 @@ vl_api_connect_uri_t_handler (vl_api_connect_uri_t * mp)
vl_api_connect_session_reply_t *rmp;
vnet_connect_args_t _a, *a = &_a;
application_t *app;
- int rv;
+ clib_error_t *error = 0;
+ int rv = 0;
if (session_manager_is_enabled () == 0)
{
@@ -433,14 +451,19 @@ vl_api_connect_uri_t_handler (vl_api_connect_uri_t * mp)
a->api_context = mp->context;
a->app_index = app->index;
a->mp = mp;
- rv = vnet_connect_uri (a);
+ if ((error = vnet_connect_uri (a)))
+ {
+ rv = clib_error_get_code (error);
+ if (rv != VNET_API_ERROR_SESSION_REDIRECT)
+ clib_error_report (error);
+ }
}
else
{
rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
}
- if (rv == 0 || rv == VNET_CONNECT_REDIRECTED)
+ if (rv == 0 || rv == VNET_API_ERROR_SESSION_REDIRECT)
return;
/* Got some error, relay it */
@@ -516,7 +539,7 @@ vl_api_reset_session_reply_t_handler (vl_api_reset_session_reply_t * mp)
if (!app)
return;
- stream_session_parse_handle (mp->handle, &index, &thread_index);
+ session_parse_handle (mp->handle, &index, &thread_index);
s = stream_session_get_if_valid (index, thread_index);
if (s == 0 || app->index != s->app_index)
{
@@ -552,7 +575,7 @@ vl_api_accept_session_reply_t_handler (vl_api_accept_session_reply_t * mp)
}
else
{
- stream_session_parse_handle (mp->handle, &session_index, &thread_index);
+ session_parse_handle (mp->handle, &session_index, &thread_index);
s = stream_session_get_if_valid (session_index, thread_index);
if (!s)
{
@@ -564,7 +587,6 @@ vl_api_accept_session_reply_t_handler (vl_api_accept_session_reply_t * mp)
clib_warning ("app doesn't own session");
return;
}
- /* XXX volatile? */
s->session_state = SESSION_STATE_READY;
}
}
@@ -581,7 +603,8 @@ vl_api_bind_sock_t_handler (vl_api_bind_sock_t * mp)
{
vl_api_bind_sock_reply_t *rmp;
vnet_bind_args_t _a, *a = &_a;
- int rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
+ int rv = 0;
+ clib_error_t *error;
application_t *app;
if (session_manager_is_enabled () == 0)
@@ -594,18 +617,28 @@ vl_api_bind_sock_t_handler (vl_api_bind_sock_t * mp)
if (app)
{
ip46_address_t *ip46 = (ip46_address_t *) mp->ip;
-
memset (a, 0, sizeof (*a));
- a->tep.is_ip4 = mp->is_ip4;
- a->tep.ip = *ip46;
- a->tep.port = mp->port;
- a->tep.vrf = mp->vrf;
+ a->sep.is_ip4 = mp->is_ip4;
+ a->sep.ip = *ip46;
+ a->sep.port = mp->port;
+ a->sep.fib_index = mp->vrf;
+ a->sep.sw_if_index = ENDPOINT_INVALID_INDEX;
a->app_index = app->index;
+ a->proto = mp->proto;
- rv = vnet_bind (a);
+ if ((error = vnet_bind (a)))
+ {
+ rv = clib_error_get_code (error);
+ clib_error_report (error);
+ }
}
done:
- REPLY_MACRO (VL_API_BIND_SOCK_REPLY);
+ /* *INDENT-OFF* */
+ REPLY_MACRO2 (VL_API_BIND_SOCK_REPLY,({
+ if (!rv)
+ rmp->handle = a->handle;
+ }));
+ /* *INDENT-ON* */
}
static void
@@ -614,7 +647,8 @@ vl_api_unbind_sock_t_handler (vl_api_unbind_sock_t * mp)
vl_api_unbind_sock_reply_t *rmp;
vnet_unbind_args_t _a, *a = &_a;
application_t *app;
- int rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
+ clib_error_t *error;
+ int rv = 0;
if (session_manager_is_enabled () == 0)
{
@@ -627,7 +661,11 @@ vl_api_unbind_sock_t_handler (vl_api_unbind_sock_t * mp)
{
a->app_index = mp->client_index;
a->handle = mp->handle;
- rv = vnet_unbind (a);
+ if ((error = vnet_unbind (a)))
+ {
+ rv = clib_error_get_code (error);
+ clib_error_report (error);
+ }
}
done:
@@ -640,7 +678,8 @@ vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp)
vl_api_connect_session_reply_t *rmp;
vnet_connect_args_t _a, *a = &_a;
application_t *app;
- int rv;
+ clib_error_t *error = 0;
+ int rv = 0;
if (session_manager_is_enabled () == 0)
{
@@ -656,22 +695,28 @@ vl_api_connect_sock_t_handler (vl_api_connect_sock_t * mp)
client_q = vl_api_client_index_to_input_queue (mp->client_index);
mp->client_queue_address = pointer_to_uword (client_q);
- a->tep.is_ip4 = mp->is_ip4;
- a->tep.ip = *ip46;
- a->tep.port = mp->port;
- a->tep.vrf = mp->vrf;
+ a->sep.is_ip4 = mp->is_ip4;
+ a->sep.ip = *ip46;
+ a->sep.port = mp->port;
+ a->sep.transport_proto = mp->proto;
+ a->sep.fib_index = mp->vrf;
+ a->sep.sw_if_index = ENDPOINT_INVALID_INDEX;
a->api_context = mp->context;
a->app_index = app->index;
- a->proto = mp->proto;
a->mp = mp;
- rv = vnet_connect (a);
+ if ((error = vnet_connect (a)))
+ {
+ rv = clib_error_get_code (error);
+ if (rv != VNET_API_ERROR_SESSION_REDIRECT)
+ clib_error_report (error);
+ }
}
else
{
rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
}
- if (rv == 0 || rv == VNET_CONNECT_REDIRECTED)
+ if (rv == 0 || rv == VNET_API_ERROR_SESSION_REDIRECT)
return;
/* Got some error, relay it */
@@ -680,6 +725,46 @@ done:
REPLY_MACRO (VL_API_CONNECT_SESSION_REPLY);
}
+static void
+vl_api_app_namespace_add_del_t_handler (vl_api_app_namespace_add_del_t * mp)
+{
+ vl_api_app_namespace_add_del_reply_t *rmp;
+ u8 *ns_id = 0;
+ clib_error_t *error = 0;
+ int rv = 0;
+ if (!session_manager_is_enabled ())
+ {
+ rv = VNET_API_ERROR_FEATURE_DISABLED;
+ goto done;
+ }
+
+ if (mp->namespace_id_len > ARRAY_LEN (mp->namespace_id))
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto done;
+ }
+
+ vec_validate (ns_id, mp->namespace_id_len - 1);
+ clib_memcpy (ns_id, mp->namespace_id, mp->namespace_id_len);
+ vnet_app_namespace_add_del_args_t args = {
+ .ns_id = ns_id,
+ .secret = mp->secret,
+ .sw_if_index = clib_net_to_host_u32 (mp->sw_if_index),
+ .ip4_fib_id = clib_net_to_host_u32 (mp->ip4_fib_id),
+ .ip6_fib_id = clib_net_to_host_u32 (mp->ip6_fib_id),
+ .is_add = 1
+ };
+ error = vnet_app_namespace_add_del (&args);
+ if (error)
+ {
+ rv = clib_error_get_code (error);
+ clib_error_report (error);
+ }
+ vec_free (ns_id);
+done:
+ REPLY_MACRO (VL_API_APP_NAMESPACE_ADD_DEL_REPLY);
+}
+
static clib_error_t *
application_reaper_cb (u32 client_index)
{