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>
This commit is contained in:
Florin Coras
2017-10-02 00:18:51 -07:00
committed by Dave Barach
parent 1f36a93d3d
commit cea194d8f9
43 changed files with 2937 additions and 803 deletions
+1 -1
View File
@@ -190,7 +190,7 @@ application_send_attach (uri_tcp_test_main_t * utm)
bmp->client_index = utm->my_client_index;
bmp->context = ntohl (0xfeedface);
bmp->options[APP_OPTIONS_FLAGS] =
APP_OPTIONS_FLAGS_USE_FIFO | APP_OPTIONS_FLAGS_ADD_SEGMENT;
APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT;
bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 16;
bmp->options[SESSION_OPTIONS_RX_FIFO_SIZE] = fifo_size;
bmp->options[SESSION_OPTIONS_TX_FIFO_SIZE] = fifo_size;
+1 -1
View File
@@ -171,7 +171,7 @@ application_send_attach (uri_udp_test_main_t * utm)
bmp->client_index = utm->my_client_index;
bmp->context = ntohl (0xfeedface);
bmp->options[APP_OPTIONS_FLAGS] =
APP_OPTIONS_FLAGS_USE_FIFO | APP_OPTIONS_FLAGS_ADD_SEGMENT;
APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT;
bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = 16;
bmp->options[SESSION_OPTIONS_RX_FIFO_SIZE] = fifo_size;
bmp->options[SESSION_OPTIONS_TX_FIFO_SIZE] = fifo_size;
+2 -1
View File
@@ -456,7 +456,8 @@ vppcom_app_send_attach (void)
bmp->client_index = vcm->my_client_index;
bmp->context = htonl (0xfeedface);
bmp->options[APP_OPTIONS_FLAGS] =
APP_OPTIONS_FLAGS_USE_FIFO | APP_OPTIONS_FLAGS_ADD_SEGMENT;
APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE | APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
bmp->options[SESSION_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
bmp->options[SESSION_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
bmp->options[SESSION_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
+55 -3
View File
@@ -5116,7 +5116,8 @@ _(p2p_ethernet_add_reply) \
_(p2p_ethernet_del_reply) \
_(lldp_config_reply) \
_(sw_interface_set_lldp_reply) \
_(tcp_configure_src_addresses_reply)
_(tcp_configure_src_addresses_reply) \
_(app_namespace_add_del_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -5420,7 +5421,8 @@ _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply) \
_(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply) \
_(LLDP_CONFIG_REPLY, lldp_config_reply) \
_(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply) \
_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)
_(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
_(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)
#define foreach_standalone_reply_msg \
_(SW_INTERFACE_EVENT, sw_interface_event) \
@@ -20735,6 +20737,55 @@ api_tcp_configure_src_addresses (vat_main_t * vam)
return ret;
}
static int
api_app_namespace_add_del (vat_main_t * vam)
{
vl_api_app_namespace_add_del_t *mp;
unformat_input_t *i = vam->input;
u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
u32 sw_if_index, ip4_fib_id, ip6_fib_id;
u64 secret;
int ret;
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
{
if (unformat (i, "id %_%v%_", &ns_id))
;
else if (unformat (i, "secret %lu", &secret))
secret_set = 1;
else if (unformat (i, "sw_if_index %d", &sw_if_index))
sw_if_index_set = 1;
else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
;
else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
;
else
break;
}
if (!ns_id || !secret_set || !sw_if_index_set)
{
errmsg ("namespace id, secret and sw_if_index must be set");
return -99;
}
if (vec_len (ns_id) > 64)
{
errmsg ("namespace id too long");
return -99;
}
M (APP_NAMESPACE_ADD_DEL, mp);
clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
mp->namespace_id_len = vec_len (ns_id);
mp->secret = secret;
mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
vec_free (ns_id);
S (mp);
W (ret);
return ret;
}
static int
api_memfd_segment_create (vat_main_t * vam)
{
@@ -21551,7 +21602,8 @@ _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
_(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
_(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
_(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]") \
_(memfd_segment_create,"size <nnn>")
_(memfd_segment_create,"size <nnn>") \
_(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
/* List of command functions, CLI names map directly to functions */
#define foreach_cli_function \
+6 -1
View File
@@ -349,7 +349,7 @@ libvnet_la_SOURCES += \
vnet/ip/ip_api.c \
vnet/ip/ip_checksum.c \
vnet/ip/ip_frag.c \
vnet/ip/ip.h \
vnet/ip/ip.c \
vnet/ip/ip_init.c \
vnet/ip/ip_input_acl.c \
vnet/ip/lookup.c \
@@ -858,23 +858,28 @@ nobase_include_HEADERS += \
libvnet_la_SOURCES += \
vnet/session/session.c \
vnet/session/session_table.c \
vnet/session/session_lookup.c \
vnet/session/session_node.c \
vnet/session/transport_interface.c \
vnet/session/application.c \
vnet/session/session_cli.c \
vnet/session/application_interface.c \
vnet/session/application_namespace.c \
vnet/session/segment_manager.c \
vnet/session/session_test.c \
vnet/session/session_api.c
nobase_include_HEADERS += \
vnet/session/session.h \
vnet/session/session_table.h \
vnet/session/stream_session.h \
vnet/session/session_lookup.h \
vnet/session/application.h \
vnet/session/transport.h \
vnet/session/transport_interface.h \
vnet/session/application_interface.h \
vnet/session/application_namespace.h \
vnet/session/session_debug.h \
vnet/session/segment_manager.h \
vnet/session/session.api.h
+7 -2
View File
@@ -104,7 +104,7 @@ _(BFD_EAGAIN, -111, "BFD object cannot be manipulated at this time") \
_(INVALID_GPE_MODE, -112, "Invalid GPE mode") \
_(LISP_GPE_ENTRIES_PRESENT, -113, "LISP GPE entries are present") \
_(ADDRESS_FOUND_FOR_INTERFACE, -114, "Address found for interface") \
_(SESSION_CONNECT_FAIL, -115, "Session failed to connect") \
_(SESSION_CONNECT, -115, "Session failed to connect") \
_(ENTRY_ALREADY_EXISTS, -116, "Entry already exists") \
_(SVM_SEGMENT_CREATE_FAIL, -117, "svm segment create fail") \
_(APPLICATION_NOT_ATTACHED, -118, "application not attached") \
@@ -116,7 +116,12 @@ _(SUBIF_DOESNT_EXIST, -123, "Subinterface doesn't exist") \
_(L2_MACS_EVENT_CLINET_PRESENT, -124, "Client already exist for L2 MACs events") \
_(INVALID_QUEUE, -125, "Invalid queue") \
_(UNSUPPORTED, -126, "Unsupported") \
_(DUPLICATE_IF_ADDRESS, -127, "Address already present on another interface")
_(DUPLICATE_IF_ADDRESS, -127, "Address already present on another interface") \
_(APP_INVALID_NS, -128, "Invalid application namespace") \
_(APP_WRONG_NS_SECRET, -129, "Wrong app namespace secret") \
_(APP_CONNECT_SCOPE, -130, "Connect scope") \
_(APP_ALREADY_ATTACHED, -131, "App already attached") \
_(SESSION_REDIRECT, -132, "Redirect failed") \
typedef enum
{
+8 -2
View File
@@ -126,8 +126,14 @@ typedef struct
protocol and ports. */
u32 flow_hash;
/* next protocol */
u32 save_protocol;
union
{
/* next protocol */
u32 save_protocol;
/* Hint for transport protocols */
u32 fib_index;
};
/* Rewrite length */
u32 save_rewrite_length;
+124
View File
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2017 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vnet/ip/ip.h>
#include <vnet/fib/fib_table.h>
u8
ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4)
{
if (is_ip4)
return (ip46_address->ip4.as_u32 == 0);
else
return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 0);
}
u8
ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4)
{
if (is_ip4)
return (ip46_address->ip4.as_u8[0] == 127);
else
return (ip46_address->as_u64[0] == 0 && ip46_address->as_u64[1] == 1);
}
/**
* Checks that an ip is local to the requested fib
*/
u8
ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4)
{
fib_node_index_t fei;
fib_entry_flag_t flags;
fib_prefix_t prefix;
/* Check if requester is local */
if (is_ip4)
{
prefix.fp_len = 32;
prefix.fp_proto = FIB_PROTOCOL_IP4;
}
else
{
prefix.fp_len = 128;
prefix.fp_proto = FIB_PROTOCOL_IP6;
}
clib_memcpy (&prefix.fp_addr, ip46_address, sizeof (ip46_address_t));
fei = fib_table_lookup (0, &prefix);
flags = fib_entry_get_flags (fei);
return (flags & FIB_ENTRY_FLAG_LOCAL);
}
u8
ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4)
{
ip_interface_address_t *ia = 0;
if (is_ip4)
{
ip_lookup_main_t *lm4 = &ip4_main.lookup_main;
ip4_address_t *ip4;
/* *INDENT-OFF* */
foreach_ip_interface_address (lm4, ia, sw_if_index, 1 /* unnumbered */ ,
({
ip4 = ip_interface_address_get_address (lm4, ia);
if (ip4_address_compare (ip4, &ip->ip4) == 0)
return 1;
}));
/* *INDENT-ON* */
}
else
{
ip_lookup_main_t *lm6 = &ip6_main.lookup_main;
ip6_address_t *ip6;
/* *INDENT-OFF* */
foreach_ip_interface_address (lm6, ia, sw_if_index, 1 /* unnumbered */ ,
({
ip6 = ip_interface_address_get_address (lm6, ia);
if (ip6_address_compare (ip6, &ip->ip6) == 0)
return 1;
}));
/* *INDENT-ON* */
}
return 0;
}
void
ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4)
{
if (is_ip4)
dst->ip4.as_u32 = src->ip4.as_u32;
else
clib_memcpy (&dst->ip6, &src->ip6, sizeof (ip6_address_t));
}
void
ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
{
if (is_ip4)
dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
else
clib_memcpy (&dst->ip6, (ip6_address_t *) src, sizeof (ip6_address_t));
}
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/
+7
View File
@@ -192,6 +192,13 @@ void ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api);
int ip_table_bind (fib_protocol_t fproto, u32 sw_if_index,
u32 table_id, u8 is_api);
u8 ip_is_zero (ip46_address_t * ip46_address, u8 is_ip4);
u8 ip_is_local_host (ip46_address_t * ip46_address, u8 is_ip4);
u8 ip_is_local (u32 fib_index, ip46_address_t * ip46_address, u8 is_ip4);
u8 ip_interface_has_address (u32 sw_if_index, ip46_address_t * ip, u8 is_ip4);
void ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4);
void ip_set (ip46_address_t * dst, void *src, u8 is_ip4);
#endif /* included_ip_main_h */
/*
+5
View File
@@ -1606,6 +1606,10 @@ ip4_local_inline (vlib_main_t * vm,
(vnet_buffer (p1)->sw_if_index[VLIB_TX] ==
(u32) ~ 0) ? fib_index1 : vnet_buffer (p1)->sw_if_index[VLIB_TX];
/* TODO maybe move to lookup? */
vnet_buffer (p0)->ip.fib_index = fib_index0;
vnet_buffer (p1)->ip.fib_index = fib_index1;
mtrie0 = &ip4_fib_get (fib_index0)->mtrie;
mtrie1 = &ip4_fib_get (fib_index1)->mtrie;
@@ -1744,6 +1748,7 @@ ip4_local_inline (vlib_main_t * vm,
fib_index0 =
(vnet_buffer (p0)->sw_if_index[VLIB_TX] ==
(u32) ~ 0) ? fib_index0 : vnet_buffer (p0)->sw_if_index[VLIB_TX];
vnet_buffer (p0)->ip.fib_index = fib_index0;
mtrie0 = &ip4_fib_get (fib_index0)->mtrie;
leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, &ip0->src_address);
leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, &ip0->src_address,
+26
View File
@@ -1428,6 +1428,24 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
? IP6_ERROR_SRC_LOOKUP_MISS : error1);
}
/* TODO maybe move to lookup? */
vnet_buffer (p0)->ip.fib_index =
vec_elt (im->fib_index_by_sw_if_index,
vnet_buffer (p0)->sw_if_index[VLIB_RX]);
vnet_buffer (p0)->ip.fib_index =
(vnet_buffer (p0)->sw_if_index[VLIB_TX] ==
(u32) ~ 0) ? vnet_buffer (p0)->ip.
fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX];
vnet_buffer (p1)->ip.fib_index =
vec_elt (im->fib_index_by_sw_if_index,
vnet_buffer (p1)->sw_if_index[VLIB_RX]);
vnet_buffer (p1)->ip.fib_index =
(vnet_buffer (p1)->sw_if_index[VLIB_TX] ==
(u32) ~ 0) ? vnet_buffer (p1)->ip.
fib_index : vnet_buffer (p1)->sw_if_index[VLIB_TX];
skip_checks:
next0 = lm->local_next_by_ip_protocol[ip0->protocol];
@@ -1538,6 +1556,14 @@ ip6_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
? IP6_ERROR_SRC_LOOKUP_MISS : error0);
}
vnet_buffer (p0)->ip.fib_index =
vec_elt (im->fib_index_by_sw_if_index,
vnet_buffer (p0)->sw_if_index[VLIB_RX]);
vnet_buffer (p0)->ip.fib_index =
(vnet_buffer (p0)->sw_if_index[VLIB_TX] ==
(u32) ~ 0) ? vnet_buffer (p0)->ip.
fib_index : vnet_buffer (p0)->sw_if_index[VLIB_TX];
skip_check:
next0 = lm->local_next_by_ip_protocol[ip0->protocol];
+113 -45
View File
@@ -15,6 +15,7 @@
#include <vnet/session/application.h>
#include <vnet/session/application_interface.h>
#include <vnet/session/application_namespace.h>
#include <vnet/session/session.h>
/**
@@ -32,6 +33,46 @@ static uword *app_by_api_client_index;
*/
static u32 default_app_evt_queue_size = 128;
static u8 *
app_get_name_from_reg_index (application_t * app)
{
u8 *app_name;
vl_api_registration_t *regp;
regp = vl_api_client_index_to_registration (app->api_client_index);
if (!regp)
app_name = format (0, "builtin-%d%c", app->index, 0);
else
app_name = format (0, "%s%c", regp->name, 0);
return app_name;
}
u32
application_session_table (application_t * app, u8 fib_proto)
{
app_namespace_t *app_ns;
app_ns = app_namespace_get (app->ns_index);
if (!application_has_global_scope (app))
return APP_INVALID_INDEX;
if (fib_proto == FIB_PROTOCOL_IP4)
return session_lookup_get_index_for_fib (fib_proto,
app_ns->ip4_fib_index);
else
return session_lookup_get_index_for_fib (fib_proto,
app_ns->ip6_fib_index);
}
u32
application_local_session_table (application_t * app)
{
app_namespace_t *app_ns;
if (!application_has_local_scope (app))
return APP_INVALID_INDEX;
app_ns = app_namespace_get (app->ns_index);
return app_ns->local_table_index;
}
int
application_api_queue_is_full (application_t * app)
{
@@ -50,6 +91,21 @@ application_api_queue_is_full (application_t * app)
return 0;
}
/**
* Returns app name
*
* Since the name is not stored per app, we generate it on the fly. It is
* the caller's responsibility to free the vector
*/
u8 *
application_name_from_index (u32 app_index)
{
application_t *app = application_get (app_index);
if (!app)
return 0;
return app_get_name_from_reg_index (app);
}
static void
application_table_add (application_t * app)
{
@@ -135,7 +191,6 @@ application_del (application_t * app)
segment_manager_init_del (sm);
}
/* If first segment manager is used by a listener */
if (app->first_segment_manager != APP_INVALID_SEGMENT_MANAGER_INDEX
&& app->first_segment_manager != app->connects_seg_manager)
@@ -180,7 +235,9 @@ application_init (application_t * app, u32 api_client_index, u64 * options,
app_evt_queue_size = options[APP_EVT_QUEUE_SIZE] > 0 ?
options[APP_EVT_QUEUE_SIZE] : default_app_evt_queue_size;
/* Setup segment manager */
/*
* Setup segment manager
*/
sm = segment_manager_new ();
sm->app_index = app->index;
props = &app->sm_properties;
@@ -203,10 +260,19 @@ application_init (application_t * app, u32 api_client_index, u64 * options,
return rv;
sm->first_is_protected = 1;
/*
* Setup application
*/
app->first_segment_manager = segment_manager_index (sm);
app->api_client_index = api_client_index;
app->flags = options[APP_OPTIONS_FLAGS];
app->cb_fns = *cb_fns;
app->ns_index = options[APP_OPTIONS_NAMESPACE];
/* If no scope enabled, default to global */
if (!application_has_global_scope (app)
&& !application_has_local_scope (app))
app->flags |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
/* Allocate app event queue in the first shared-memory segment */
app->event_queue = segment_manager_alloc_queue (sm, app_evt_queue_size);
@@ -223,6 +289,8 @@ application_init (application_t * app, u32 api_client_index, u64 * options,
application_t *
application_get (u32 index)
{
if (index == APP_INVALID_INDEX)
return 0;
return pool_elt_at_index (app_pool, index);
}
@@ -269,17 +337,19 @@ application_alloc_segment_manager (application_t * app)
* it's own specific listening connection.
*/
int
application_start_listen (application_t * srv, session_type_t session_type,
transport_endpoint_t * tep, u64 * res)
application_start_listen (application_t * srv, session_endpoint_t * sep,
u64 * res)
{
segment_manager_t *sm;
stream_session_t *s;
u64 handle;
session_type_t sst;
s = listen_session_new (session_type);
sst = session_type_from_proto_and_ip (sep->transport_proto, sep->is_ip4);
s = listen_session_new (sst);
s->app_index = srv->index;
if (stream_session_listen (s, tep))
if (stream_session_listen (s, sep))
goto err;
/* Allocate segment manager. All sessions derived out of a listen session
@@ -341,15 +411,15 @@ application_stop_listen (application_t * srv, u64 handle)
}
int
application_open_session (application_t * app, session_type_t sst,
transport_endpoint_t * tep, u32 api_context)
application_open_session (application_t * app, session_endpoint_t * sep,
u32 api_context)
{
segment_manager_t *sm;
transport_connection_t *tc = 0;
int rv;
/* Make sure we have a segment manager for connects */
if (app->connects_seg_manager == (u32) ~ 0)
if (app->connects_seg_manager == APP_INVALID_SEGMENT_MANAGER_INDEX)
{
sm = application_alloc_segment_manager (app);
if (sm == 0)
@@ -357,7 +427,7 @@ application_open_session (application_t * app, session_type_t sst,
app->connects_seg_manager = segment_manager_index (sm);
}
if ((rv = stream_session_open (app->index, sst, tep, &tc)))
if ((rv = stream_session_open (app->index, sep, &tc)))
return rv;
/* Store api_context for when the reply comes. Not the nicest thing
@@ -384,21 +454,6 @@ application_get_listen_segment_manager (application_t * app,
return segment_manager_get (*smp);
}
static u8 *
app_get_name_from_reg_index (application_t * app)
{
u8 *app_name;
vl_api_registration_t *regp;
regp = vl_api_client_index_to_registration (app->api_client_index);
if (!regp)
app_name = format (0, "builtin-%d%c", app->index, 0);
else
app_name = format (0, "%s%c", regp->name, 0);
return app_name;
}
int
application_is_proxy (application_t * app)
{
@@ -420,6 +475,18 @@ application_add_segment_notify (u32 app_index, u32 fifo_segment_index)
seg_size);
}
u8
application_has_local_scope (application_t * app)
{
return app->flags & APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
}
u8
application_has_global_scope (application_t * app)
{
return app->flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
}
u8 *
format_application_listener (u8 * s, va_list * args)
{
@@ -500,7 +567,7 @@ application_format_connects (application_t * app, int verbose)
session_index = fifo->master_session_index;
thread_index = fifo->master_thread_index;
session = stream_session_get (session_index, thread_index);
session = session_get (session_index, thread_index);
str = format (0, "%U", format_stream_session, session, verbose);
if (verbose)
@@ -526,27 +593,33 @@ format_application (u8 * s, va_list * args)
{
application_t *app = va_arg (*args, application_t *);
CLIB_UNUSED (int verbose) = va_arg (*args, int);
const u8 *app_ns_name;
u8 *app_name;
if (app == 0)
{
if (verbose)
s = format (s, "%-10s%-20s%-15s%-15s%-15s%-15s", "Index", "Name",
"API Client", "Add seg size", "Rx fifo size",
s = format (s, "%-10s%-20s%-15s%-15s%-15s%-15s%-15s", "Index", "Name",
"Namespace", "API Client", "Add seg size", "Rx fifo size",
"Tx fifo size");
else
s = format (s, "%-10s%-20s%-20s", "Index", "Name", "API Client");
s =
format (s, "%-10s%-20s%-15s%-20s", "Index", "Name", "Namespace",
"API Client");
return s;
}
app_name = app_get_name_from_reg_index (app);
app_ns_name = app_namespace_id_from_index (app->ns_index);
if (verbose)
s = format (s, "%-10d%-20s%-15d%-15d%-15d%-15d", app->index, app_name,
app->api_client_index, app->sm_properties.add_segment_size,
app->sm_properties.rx_fifo_size,
app->sm_properties.tx_fifo_size);
s =
format (s, "%-10d%-20s%-15s%-15d%-15d%-15d%-15d", app->index, app_name,
app_ns_name, app->api_client_index,
app->sm_properties.add_segment_size,
app->sm_properties.rx_fifo_size,
app->sm_properties.tx_fifo_size);
else
s = format (s, "%-10d%-20s%-20d", app->index, app_name,
s = format (s, "%-10d%-20s%-15s%-20d", app->index, app_name, app_ns_name,
app->api_client_index);
return s;
}
@@ -560,10 +633,7 @@ show_app_command_fn (vlib_main_t * vm, unformat_input_t * input,
int do_client = 0;
int verbose = 0;
if (!session_manager_is_enabled ())
{
clib_error_return (0, "session layer is not enabled");
}
session_cli_return_if_not_enabled ();
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -627,13 +697,11 @@ show_app_command_fn (vlib_main_t * vm, unformat_input_t * input,
if (!do_server && !do_client)
{
vlib_cli_output (vm, "%U", format_application, 0, verbose);
pool_foreach (app, app_pool, (
{
vlib_cli_output (vm, "%U",
format_application, app,
verbose);
}
));
/* *INDENT-OFF* */
pool_foreach (app, app_pool, ({
vlib_cli_output (vm, "%U", format_application, app, verbose);
}));
/* *INDENT-ON* */
}
return 0;
+21 -13
View File
@@ -19,7 +19,7 @@
#include <vnet/vnet.h>
#include <vnet/session/session.h>
#include <vnet/session/segment_manager.h>
#include <vnet/session/application_namespace.h>
typedef enum
{
APP_SERVER,
@@ -36,7 +36,7 @@ typedef struct _stream_session_cb_vft
/** Notify server of newly accepted session */
int (*session_accept_callback) (stream_session_t * new_session);
/* Connection request callback */
/** Connection request callback */
int (*session_connected_callback) (u32 app_index, u32 opaque,
stream_session_t * s, u8 code);
@@ -46,10 +46,10 @@ typedef struct _stream_session_cb_vft
/** Notify app that session was reset */
void (*session_reset_callback) (stream_session_t * s);
/* Direct RX callback, for built-in servers */
/** Direct RX callback, for built-in servers */
int (*builtin_server_rx_callback) (stream_session_t * session);
/* Redirect connection to local server */
/** Redirect connection to local server */
int (*redirect_connect_callback) (u32 api_client_index, void *mp);
} session_cb_vft_t;
@@ -68,6 +68,9 @@ typedef struct _application
/** Binary API connection index, ~0 if internal */
u32 api_client_index;
/** Namespace the application belongs to */
u32 ns_index;
/** Application listens for events on this svm queue */
unix_shared_memory_queue_t *event_queue;
@@ -95,25 +98,24 @@ typedef struct _application
segment_manager_properties_t sm_properties;
} application_t;
#define APP_INVALID_INDEX ((u32)~0)
#define APP_NS_INVALID_INDEX ((u32)~0)
#define APP_INVALID_SEGMENT_MANAGER_INDEX ((u32) ~0)
application_t *application_new ();
int
application_init (application_t * app, u32 api_client_index, u64 * options,
session_cb_vft_t * cb_fns);
int application_init (application_t * app, u32 api_client_index,
u64 * options, session_cb_vft_t * cb_fns);
void application_del (application_t * app);
application_t *application_get (u32 index);
application_t *application_get_if_valid (u32 index);
application_t *application_lookup (u32 api_client_index);
u32 application_get_index (application_t * app);
int
application_start_listen (application_t * app, session_type_t session_type,
transport_endpoint_t * tep, u64 * handle);
int application_start_listen (application_t * app,
session_endpoint_t * tep, u64 * handle);
int application_stop_listen (application_t * srv, u64 handle);
int
application_open_session (application_t * app, session_type_t sst,
transport_endpoint_t * tep, u32 api_context);
int application_open_session (application_t * app, session_endpoint_t * tep,
u32 api_context);
int application_api_queue_is_full (application_t * app);
segment_manager_t *application_get_listen_segment_manager (application_t *
@@ -124,6 +126,12 @@ segment_manager_t *application_get_connect_segment_manager (application_t *
app);
int application_is_proxy (application_t * app);
int application_add_segment_notify (u32 app_index, u32 fifo_segment_index);
u32 application_session_table (application_t * app, u8 fib_proto);
u32 application_local_session_table (application_t * app);
u8 *application_name_from_index (u32 app_index);
u8 application_has_local_scope (application_t * app);
u8 application_has_global_scope (application_t * app);
#endif /* SRC_VNET_SESSION_APPLICATION_H_ */
File diff suppressed because it is too large Load Diff
+16 -20
View File
@@ -30,12 +30,12 @@ typedef struct _vnet_app_attach_args_t
/** Application and segment manager options */
u64 *options;
/* Namespace id */
u8 *namespace_id;
/** Session to application callback functions */
session_cb_vft_t *session_cb_vft;
/** Flag that indicates if app is builtin */
u8 builtin;
/*
* Results
*/
@@ -58,7 +58,7 @@ typedef struct _vnet_bind_args_t
char *uri;
struct
{
transport_endpoint_t tep;
session_endpoint_t sep;
transport_proto_t proto;
};
};
@@ -91,7 +91,7 @@ typedef struct _vnet_connect_args
char *uri;
struct
{
transport_endpoint_t tep;
session_endpoint_t sep;
transport_proto_t proto;
};
};
@@ -119,6 +119,8 @@ typedef enum
APP_OPTIONS_PREALLOC_FIFO_PAIRS,
APP_OPTIONS_PRIVATE_SEGMENT_COUNT,
APP_OPTIONS_PRIVATE_SEGMENT_SIZE,
APP_OPTIONS_NAMESPACE,
APP_OPTIONS_NAMESPACE_SECRET,
SESSION_OPTIONS_SEGMENT_SIZE,
SESSION_OPTIONS_ADD_SEGMENT_SIZE,
SESSION_OPTIONS_RX_FIFO_SIZE,
@@ -129,10 +131,12 @@ typedef enum
} app_attach_options_index_t;
#define foreach_app_options_flags \
_(USE_FIFO, "Use FIFO with redirects") \
_(ACCEPT_REDIRECT, "Use FIFO with redirects") \
_(ADD_SEGMENT, "Add segment and signal app if needed") \
_(BUILTIN_APP, "Application is builtin") \
_(IS_PROXY, "Application is proxying")
_(IS_PROXY, "Application is proxying") \
_(USE_GLOBAL_SCOPE, "App can use global session scope") \
_(USE_LOCAL_SCOPE, "App can use local session scope")
typedef enum _app_options
{
@@ -148,25 +152,17 @@ typedef enum _app_options_flags
#undef _
} app_options_flags_t;
///** Server can handle delegated connect requests from local clients */
//#define APP_OPTIONS_FLAGS_USE_FIFO (1<<0)
//
///** Server wants vpp to add segments when out of memory for fifos */
//#define APP_OPTIONS_FLAGS_ADD_SEGMENT (1<<1)
#define VNET_CONNECT_REDIRECTED 123
int vnet_application_attach (vnet_app_attach_args_t * a);
clib_error_t *vnet_application_attach (vnet_app_attach_args_t * a);
int vnet_application_detach (vnet_app_detach_args_t * a);
int vnet_bind_uri (vnet_bind_args_t *);
int vnet_unbind_uri (vnet_unbind_args_t * a);
int vnet_connect_uri (vnet_connect_args_t * a);
clib_error_t *vnet_connect_uri (vnet_connect_args_t * a);
int vnet_disconnect_session (vnet_disconnect_args_t * a);
int vnet_bind (vnet_bind_args_t * a);
int vnet_connect (vnet_connect_args_t * a);
int vnet_unbind (vnet_unbind_args_t * a);
clib_error_t *vnet_bind (vnet_bind_args_t * a);
clib_error_t *vnet_connect (vnet_connect_args_t * a);
clib_error_t *vnet_unbind (vnet_unbind_args_t * a);
int
api_parse_session_handle (u64 handle, u32 * session_index,
+293
View File
@@ -0,0 +1,293 @@
/*
* Copyright (c) 2017 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vnet/session/application_namespace.h>
#include <vnet/session/session_table.h>
#include <vnet/session/session.h>
#include <vnet/fib/fib_table.h>
/**
* Hash table of application namespaces by app ns ids
*/
uword *app_namespace_lookup_table;
/**
* Pool of application namespaces
*/
static app_namespace_t *app_namespace_pool;
app_namespace_t *
app_namespace_get (u32 index)
{
return pool_elt_at_index (app_namespace_pool, index);
}
app_namespace_t *
app_namespace_get_from_id (const u8 * ns_id)
{
u32 index = app_namespace_index_from_id (ns_id);
if (index == APP_NAMESPACE_INVALID_INDEX)
return 0;
return app_namespace_get (index);
}
u32
app_namespace_index (app_namespace_t * app_ns)
{
return (app_ns - app_namespace_pool);
}
app_namespace_t *
app_namespace_alloc (u8 * ns_id)
{
app_namespace_t *app_ns;
pool_get (app_namespace_pool, app_ns);
memset (app_ns, 0, sizeof (*app_ns));
app_ns->ns_id = vec_dup (ns_id);
hash_set_mem (app_namespace_lookup_table, app_ns->ns_id,
app_ns - app_namespace_pool);
return app_ns;
}
clib_error_t *
vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t * a)
{
app_namespace_t *app_ns;
session_table_t *st;
if (a->is_add)
{
if (a->sw_if_index != APP_NAMESPACE_INVALID_INDEX
&& !vnet_get_sw_interface_safe (vnet_get_main (), a->sw_if_index))
return clib_error_return_code (0, VNET_API_ERROR_INVALID_SW_IF_INDEX,
0, "sw_if_index %u doesn't exist",
a->sw_if_index);
if (a->sw_if_index != APP_NAMESPACE_INVALID_INDEX)
{
a->ip4_fib_id =
fib_table_get_table_id_for_sw_if_index (FIB_PROTOCOL_IP4,
a->sw_if_index);
a->ip6_fib_id =
fib_table_get_table_id_for_sw_if_index (FIB_PROTOCOL_IP4,
a->sw_if_index);
}
if (a->sw_if_index == APP_NAMESPACE_INVALID_INDEX
&& a->ip4_fib_id == APP_NAMESPACE_INVALID_INDEX)
return clib_error_return_code (0, VNET_API_ERROR_INVALID_VALUE, 0,
"sw_if_index or fib_id must be "
"configured");
st = session_table_alloc ();
session_table_init (st);
app_ns = app_namespace_get_from_id (a->ns_id);
if (!app_ns)
app_ns = app_namespace_alloc (a->ns_id);
app_ns->ns_secret = a->secret;
app_ns->sw_if_index = a->sw_if_index;
app_ns->local_table_index = session_table_index (st);
app_ns->ip4_fib_index =
fib_table_find (FIB_PROTOCOL_IP4, a->ip4_fib_id);
app_ns->ip6_fib_index =
fib_table_find (FIB_PROTOCOL_IP6, a->ip6_fib_id);
}
else
{
return clib_error_return_code (0, VNET_API_ERROR_UNIMPLEMENTED, 0,
"namespace deletion not supported");
}
return 0;
}
const u8 *
app_namespace_id (app_namespace_t * app_ns)
{
return app_ns->ns_id;
}
u32
app_namespace_index_from_id (const u8 * ns_id)
{
uword *indexp;
indexp = hash_get_mem (app_namespace_lookup_table, ns_id);
if (!indexp)
return APP_NAMESPACE_INVALID_INDEX;
return *indexp;
}
const u8 *
app_namespace_id_from_index (u32 index)
{
app_namespace_t *app_ns;
app_ns = app_namespace_get (index);
return app_namespace_id (app_ns);
}
void
app_namespaces_init (void)
{
u8 *ns_id = format (0, "default");
app_namespace_lookup_table =
hash_create_vec (0, sizeof (u8), sizeof (uword));
/*
* Allocate default namespace
*/
vnet_app_namespace_add_del_args_t a = {
.ns_id = ns_id,
.secret = 0,
.sw_if_index = APP_NAMESPACE_INVALID_INDEX,
.is_add = 1
};
vnet_app_namespace_add_del (&a);
vec_free (ns_id);
}
static clib_error_t *
app_ns_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
{
u8 is_add = 0, *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
u32 sw_if_index, fib_id = APP_NAMESPACE_INVALID_INDEX;
u64 secret;
clib_error_t *error = 0;
session_cli_return_if_not_enabled ();
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "add"))
is_add = 1;
else if (unformat (input, "id %_%v%_", &ns_id))
;
else if (unformat (input, "secret %lu", &secret))
secret_set = 1;
else if (unformat (input, "sw_if_index %u", &sw_if_index))
sw_if_index_set = 1;
else if (unformat (input, "fib_id", &fib_id))
;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
}
if (!ns_id || !secret_set || !sw_if_index_set)
{
vlib_cli_output (vm, "namespace-id, secret and sw_if_index must be "
"provided");
return 0;
}
if (is_add)
{
vnet_app_namespace_add_del_args_t args = {
.ns_id = ns_id,
.secret = secret,
.sw_if_index = sw_if_index,
.ip4_fib_id = fib_id,
.is_add = 1
};
error = vnet_app_namespace_add_del (&args);
}
return error;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (app_ns_command, static) =
{
.path = "app ns",
.short_help = "app ns [add] id <namespace-id> secret <secret> "
"sw_if_index <sw_if_index>",
.function = app_ns_fn,
};
/* *INDENT-ON* */
u8 *
format_app_namespace (u8 * s, va_list * args)
{
app_namespace_t *app_ns = va_arg (*args, app_namespace_t *);
s = format (s, "%-20v%-20lu%-20u", app_ns->ns_id, app_ns->ns_secret,
app_ns->sw_if_index);
return s;
}
static clib_error_t *
show_app_ns_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
{
app_namespace_t *app_ns;
session_table_t *st;
u8 *ns_id, do_table = 0;
session_cli_return_if_not_enabled ();
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "table %_%v%_", &ns_id))
do_table = 1;
else
return clib_error_return (0, "unknown input `%U'",
format_unformat_error, input);
}
if (do_table)
{
app_ns = app_namespace_get_from_id (ns_id);
if (!app_ns)
{
vlib_cli_output (vm, "ns %v not found", ns_id);
return 0;
}
st = session_table_get (app_ns->local_table_index);
if (!st)
{
vlib_cli_output (vm, "table for ns %v could not be found", ns_id);
return 0;
}
session_lookup_show_table_entries (vm, st, 0, 1);
vec_free (ns_id);
return 0;
}
vlib_cli_output (vm, "%-20s%-20s%-20s", "Namespace", "Secret",
"sw_if_index");
/* *INDENT-OFF* */
pool_foreach (app_ns, app_namespace_pool, ({
vlib_cli_output (vm, "%U", format_app_namespace, app_ns);
}));
/* *INDENT-ON* */
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_app_ns_command, static) =
{
.path = "show app ns",
.short_help = "show app ns",
.function = show_app_ns_fn,
};
/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2017 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vnet/vnet.h>
#ifndef SRC_VNET_SESSION_APPLICATION_NAMESPACE_H_
#define SRC_VNET_SESSION_APPLICATION_NAMESPACE_H_
typedef struct _app_namespace
{
/**
* Local sw_if_index that supports transport connections for this namespace
*/
u32 sw_if_index;
/**
* Network namespace (e.g., fib_index associated to the sw_if_index)
* wherein connections are to be established. Since v4 and v6 fibs are
* separate, we actually need to keep pointers to both.
*/
u32 ip4_fib_index;
u32 ip6_fib_index;
/**
* Local session table associated to ns
*/
u32 local_table_index;
/**
* Secret apps need to provide to authorize attachment to the namespace
*/
u64 ns_secret;
/**
* Application namespace id
*/
u8 *ns_id;
} app_namespace_t;
typedef struct _vnet_app_namespace_add_del_args
{
u8 *ns_id;
u64 secret;
u32 sw_if_index;
u32 ip4_fib_id;
u32 ip6_fib_id;
u8 is_add;
} vnet_app_namespace_add_del_args_t;
#define APP_NAMESPACE_INVALID_INDEX ((u32)~0)
app_namespace_t *app_namespace_alloc (u8 * ns_id);
app_namespace_t *app_namespace_get (u32 index);
app_namespace_t *app_namespace_get_from_id (const u8 * ns_id);
u32 app_namespace_index (app_namespace_t * app_ns);
const u8 *app_namespace_id (app_namespace_t * app_ns);
const u8 *app_namespace_id_from_index (u32 index);
u32 app_namespace_index_from_id (const u8 * ns_id);
void app_namespaces_init (void);
clib_error_t *vnet_app_namespace_add_del (vnet_app_namespace_add_del_args_t *
a);
#endif /* SRC_VNET_SESSION_APPLICATION_NAMESPACE_H_ */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/
+1 -1
View File
@@ -267,7 +267,7 @@ segment_manager_del_sessions (segment_manager_t * sm)
session_index = fifo->master_session_index;
thread_index = fifo->master_thread_index;
session = stream_session_get (session_index, thread_index);
session = session_get (session_index, thread_index);
/* Instead of directly removing the session call disconnect */
if (session->session_state != SESSION_STATE_CLOSED)
+39 -12
View File
@@ -21,12 +21,16 @@ vl_api_version 1.0.0
@param initial_segment_size - size of the initial shm segment to be
allocated
@param options - segment size, fifo sizes, etc.
@param namespace_id_len - length of the namespace id c-string
@param namespace_id - 0 terminted c-string
*/
define application_attach {
u32 client_index;
u32 context;
u32 initial_segment_size;
u64 options[16];
u8 namespace_id_len;
u8 namespace_id [64];
};
/** \brief Application attach reply
@@ -99,20 +103,19 @@ autoreply define unbind_uri {
/** \brief Connect to a given URI
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param accept_cookie - sender accept cookie, to identify this bind flavor
@param uri - a URI, e.g. "tcp4://0.0.0.0/0/80"
"tcp6://::/0/80" [ipv6], etc.
@param options - socket options, fifo sizes, etc. passed by vpp to the
server when redirecting connects
@param client_queue_address - binary API client queue address. Used by
local server when connect was redirected.
@param options - socket options, fifo sizes, etc. passed by vpp to the
server when redirecting connects
@param uri - a URI, e.g. "tcp4://0.0.0.0/0/80"
"tcp6://::/0/80" [ipv6], etc.
*/
autoreply define connect_uri {
u32 client_index;
u32 context;
u8 uri[128];
u64 client_queue_address;
u64 options[16];
u8 uri[128];
};
/** \brief vpp->client, accept this session
@@ -240,26 +243,25 @@ autoreply define unbind_sock {
/** \brief Connect to a remote peer
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param app_connect - application connection id to be returned in reply
@param client_queue_address - client's API queue address. Non-zero when
used to perform redirects
@param options - socket options, fifo sizes, etc. when doing redirects
@param vrf - connection namespace
@param is_ip4 - flag that is 1 if ip address family is IPv4
@param ip - ip address
@param port - port
@param proto - protocol 0 - TCP 1 - UDP
@param client_queue_address - client's API queue address. Non-zero when
used to perform redirects
@param options - socket options, fifo sizes, etc. when doing redirects
*/
autoreply define connect_sock {
u32 client_index;
u32 context;
u64 client_queue_address;
u64 options[16];
u32 vrf;
u8 is_ip4;
u8 ip[16];
u16 port;
u8 proto;
u64 client_queue_address;
u64 options[16];
};
/** \brief Bind reply
@@ -326,6 +328,31 @@ autoreply define session_enable_disable {
u8 is_enable;
};
/** \brief add/del application namespace
@param client_index - opaque cookie to identify the sender
client to vpp direction only
@param context - sender context, to match reply w/ request
@param secret - secret shared between app and vpp
@param sw_if_index - local interface that "supports" namespace. Set to
~0 if no preference
@param ip4_fib_id - id of ip4 fib that "supports" the namespace. Ignored
if sw_if_index set.
@param ip6_fib_id - id of ip6 fib that "supports" the namespace. Ignored
if sw_if_index set.
@param namespace_id_len - length of namespace id lower
@param namespace_id - namespace id
*/
autoreply define app_namespace_add_del {
u32 client_index;
u32 context;
u64 secret;
u32 sw_if_index;
u32 ip4_fib_id;
u32 ip6_fib_id;
u8 namespace_id_len;
u8 namespace_id[64];
};
/*
* Local Variables:
* eval: (c-set-style "gnu")
+56 -35
View File
@@ -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 *
+25 -16
View File
@@ -214,7 +214,7 @@ stream_session_is_valid (u32 si, u8 thread_index)
}
always_inline stream_session_t *
stream_session_get (u32 si, u32 thread_index)
session_get (u32 si, u32 thread_index)
{
ASSERT (stream_session_is_valid (si, thread_index));
return pool_elt_at_index (session_manager_main.sessions[thread_index], si);
@@ -240,31 +240,31 @@ stream_session_handle (stream_session_t * s)
}
always_inline u32
stream_session_index_from_handle (u64 handle)
session_index_from_handle (u64 handle)
{
return handle & 0xFFFFFFFF;
}
always_inline u32
stream_session_thread_from_handle (u64 handle)
session_thread_from_handle (u64 handle)
{
return handle >> 32;
}
always_inline void
stream_session_parse_handle (u64 handle, u32 * index, u32 * thread_index)
session_parse_handle (u64 handle, u32 * index, u32 * thread_index)
{
*index = stream_session_index_from_handle (handle);
*thread_index = stream_session_thread_from_handle (handle);
*index = session_index_from_handle (handle);
*thread_index = session_thread_from_handle (handle);
}
always_inline stream_session_t *
stream_session_get_from_handle (u64 handle)
session_get_from_handle (u64 handle)
{
session_manager_main_t *smm = &session_manager_main;
return pool_elt_at_index (smm->sessions[stream_session_thread_from_handle
(handle)],
stream_session_index_from_handle (handle));
return
pool_elt_at_index (smm->sessions[session_thread_from_handle (handle)],
session_index_from_handle (handle));
}
always_inline stream_session_t *
@@ -285,14 +285,14 @@ stream_session_get_index (stream_session_t * s)
always_inline u32
stream_session_max_rx_enqueue (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);
return svm_fifo_max_enqueue (s->server_rx_fifo);
}
always_inline u32
stream_session_rx_fifo_size (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);
return s->server_rx_fifo->nitems;
}
@@ -316,12 +316,11 @@ void stream_session_delete_notify (transport_connection_t * tc);
void 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);
int
stream_session_open (u32 app_index, session_type_t st,
transport_endpoint_t * tep,
stream_session_open (u32 app_index, session_endpoint_t * tep,
transport_connection_t ** tc);
int stream_session_listen (stream_session_t * s, transport_endpoint_t * tep);
int stream_session_listen (stream_session_t * s, session_endpoint_t * tep);
int stream_session_stop_listen (stream_session_t * s);
void stream_session_disconnect (stream_session_t * s);
void stream_session_cleanup (stream_session_t * s);
@@ -401,6 +400,10 @@ listen_session_del (stream_session_t * s)
pool_put (session_manager_main.listen_sessions[s->session_type], s);
}
int
listen_session_get_local_session_endpoint (stream_session_t * listener,
session_endpoint_t * sep);
always_inline stream_session_t *
session_manager_get_listener (u8 type, u32 index)
{
@@ -425,6 +428,12 @@ session_manager_is_enabled ()
return session_manager_main.is_enabled == 1;
}
#define session_cli_return_if_not_enabled() \
do { \
if (!session_manager_main.is_enabled) \
return clib_error_return(0, "session layer is not enabled"); \
} while (0)
#endif /* __included_session_h__ */
/*
+119 -34
View File
@@ -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)
{
+16 -20
View File
@@ -138,22 +138,21 @@ unformat_stream_session (unformat_input_t * input, va_list * args)
stream_session_t *s;
u8 proto = ~0;
ip46_address_t lcl, rmt;
u32 lcl_port = 0, rmt_port = 0;
u8 is_ip4 = 0, s_type = ~0;
u32 lcl_port = 0, rmt_port = 0, fib_index = 0;
u8 is_ip4 = 0;
if (!unformat (input, "%U", unformat_stream_session_id, &proto, &lcl, &rmt,
&lcl_port, &rmt_port, &is_ip4))
return 0;
s_type = session_type_from_proto_and_ip (proto, is_ip4);
if (is_ip4)
s = stream_session_lookup4 (&lcl.ip4, &rmt.ip4,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port), s_type);
s = session_lookup4 (fib_index, &lcl.ip4, &rmt.ip4,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port), proto);
else
s = stream_session_lookup6 (&lcl.ip6, &rmt.ip6,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port), s_type);
s = session_lookup6 (fib_index, &lcl.ip6, &rmt.ip6,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port), proto);
if (s)
{
*result = s;
@@ -170,8 +169,8 @@ unformat_transport_connection (unformat_input_t * input, va_list * args)
transport_connection_t *tc;
u8 proto = ~0;
ip46_address_t lcl, rmt;
u32 lcl_port = 0, rmt_port = 0;
u8 is_ip4 = 0, s_type = ~0;
u32 lcl_port = 0, rmt_port = 0, fib_index = 0;
u8 is_ip4 = 0;
if (!unformat (input, "%U", unformat_stream_session_id, &proto, &lcl, &rmt,
&lcl_port, &rmt_port, &is_ip4))
@@ -180,17 +179,14 @@ unformat_transport_connection (unformat_input_t * input, va_list * args)
proto = (proto == (u8) ~ 0) ? suggested_proto : proto;
if (proto == (u8) ~ 0)
return 0;
s_type = session_type_from_proto_and_ip (proto, is_ip4);
if (is_ip4)
tc = stream_session_lookup_transport4 (&lcl.ip4, &rmt.ip4,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port),
s_type);
tc = session_lookup_connection4 (fib_index, &lcl.ip4, &rmt.ip4,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port), proto);
else
tc = stream_session_lookup_transport6 (&lcl.ip6, &rmt.ip6,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port),
s_type);
tc = session_lookup_connection6 (fib_index, &lcl.ip6, &rmt.ip6,
clib_host_to_net_u16 (lcl_port),
clib_host_to_net_u16 (rmt_port), proto);
if (tc)
{
+10 -7
View File
@@ -31,11 +31,13 @@ typedef enum _session_evt_dbg
#undef _
} session_evt_dbg_e;
#define SESSION_DBG (0)
#define SESSION_DEBUG (0 && TRANSPORT_DEBUG)
#define SESSION_DEQ_NODE_EVTS (0)
#define SESSION_EVT_POLL_DBG (1)
#if TRANSPORT_DEBUG && SESSION_DBG
#if SESSION_DEBUG
#define SESSION_DBG(_fmt, _args...) clib_warning (_fmt, ##_args)
#define DEC_SESSION_ETD(_s, _e, _size) \
struct \
@@ -78,7 +80,7 @@ typedef enum _session_evt_dbg
do { _body; } while (0); \
}
#if SESSION_DEQ_NODE_EVTS
#if SESSION_DEQ_NODE_EVTS && SESSION_DEBUG > 1
#define SESSION_EVT_DEQ_NODE_HANDLER(_node_evt) \
{ \
ELOG_TYPE_DECLARE (_e) = \
@@ -96,9 +98,9 @@ typedef enum _session_evt_dbg
}
#else
#define SESSION_EVT_DEQ_NODE_HANDLER(_node_evt)
#endif
#endif /* SESSION_DEQ_NODE_EVTS */
#if SESSION_DBG && SESSION_EVT_POLL_DBG
#if SESSION_EVT_POLL_DBG && SESSION_DEBUG > 1
#define SESSION_EVT_POLL_GAP(_smm, _my_thread_index) \
{ \
ELOG_TYPE_DECLARE (_e) = \
@@ -122,7 +124,7 @@ typedef enum _session_evt_dbg
#else
#define SESSION_EVT_POLL_GAP(_smm, _my_thread_index)
#define SESSION_EVT_POLL_GAP_TRACK_HANDLER(_smm, _my_thread_index)
#endif
#endif /* SESSION_EVT_POLL_DBG */
#define CONCAT_HELPER(_a, _b) _a##_b
#define CC(_a, _b) CONCAT_HELPER(_a, _b)
@@ -130,7 +132,8 @@ typedef enum _session_evt_dbg
#else
#define SESSION_EVT_DBG(_evt, _args...)
#endif
#define SESSION_DBG(_fmt, _args...)
#endif /* SESSION_DEBUG */
#endif /* SRC_VNET_SESSION_SESSION_DEBUG_H_ */
/*
File diff suppressed because it is too large Load Diff
+61 -65
View File
@@ -16,77 +16,73 @@
#ifndef SRC_VNET_SESSION_SESSION_LOOKUP_H_
#define SRC_VNET_SESSION_SESSION_LOOKUP_H_
#include <vnet/session/session_table.h>
#include <vnet/session/stream_session.h>
#include <vnet/session/transport.h>
typedef struct _session_lookup
{
/** Lookup tables for established sessions and listeners */
clib_bihash_16_8_t v4_session_hash;
clib_bihash_48_8_t v6_session_hash;
/** Lookup tables for half-open sessions */
clib_bihash_16_8_t v4_half_open_hash;
clib_bihash_48_8_t v6_half_open_hash;
} session_lookup_t;
stream_session_t *stream_session_lookup_listener4 (ip4_address_t * lcl,
u16 lcl_port, u8 proto);
stream_session_t *stream_session_lookup4 (ip4_address_t * lcl,
ip4_address_t * rmt, u16 lcl_port,
u16 rmt_port, u8 proto);
stream_session_t *stream_session_lookup_listener6 (ip6_address_t * lcl,
u16 lcl_port, u8 proto);
stream_session_t *stream_session_lookup6 (ip6_address_t * lcl,
ip6_address_t * rmt, u16 lcl_port,
u16 rmt_port, u8 proto);
transport_connection_t *stream_session_lookup_transport_wt4 (ip4_address_t *
lcl,
ip4_address_t *
rmt,
u16 lcl_port,
u16 rmt_port,
stream_session_t *session_lookup4 (u32 fib_index, ip4_address_t * lcl,
ip4_address_t * rmt, u16 lcl_port,
u16 rmt_port, u8 proto);
stream_session_t *session_lookup6 (u32 fib_index, ip6_address_t * lcl,
ip6_address_t * rmt, u16 lcl_port,
u16 rmt_port, u8 proto);
transport_connection_t *session_lookup_connection_wt4 (u32 fib_index,
ip4_address_t * lcl,
ip4_address_t * rmt,
u16 lcl_port,
u16 rmt_port, u8 proto,
u32 thread_index);
transport_connection_t *session_lookup_connection4 (u32 fib_index,
ip4_address_t * lcl,
ip4_address_t * rmt,
u16 lcl_port,
u16 rmt_port, u8 proto);
transport_connection_t *session_lookup_connection_wt6 (u32 fib_index,
ip6_address_t * lcl,
ip6_address_t * rmt,
u16 lcl_port,
u16 rmt_port, u8 proto,
u32 thread_index);
transport_connection_t *session_lookup_connection6 (u32 fib_index,
ip6_address_t * lcl,
ip6_address_t * rmt,
u16 lcl_port,
u16 rmt_port, u8 proto);
stream_session_t *session_lookup_listener4 (u32 fib_index,
ip4_address_t * lcl, u16 lcl_port,
u8 proto);
stream_session_t *session_lookup_listener6 (u32 fib_index,
ip6_address_t * lcl, u16 lcl_port,
u8 proto);
stream_session_t *session_lookup_listener (u32 table_index,
session_endpoint_t * sep);
int session_lookup_add_connection (transport_connection_t * tc, u64 value);
int session_lookup_del_connection (transport_connection_t * tc);
u32 session_lookup_session_endpoint (u32 table_index,
session_endpoint_t * sep);
u32 session_lookup_local_session_endpoint (u32 table_index,
session_endpoint_t * sep);
int session_lookup_add_session_endpoint (u32 table_index,
session_endpoint_t * sep, u64 value);
int session_lookup_del_session_endpoint (u32 table_index,
session_endpoint_t * sep);
int session_lookup_del_session (stream_session_t * s);
int session_lookup_del_half_open (transport_connection_t * tc);
int session_lookup_add_half_open (transport_connection_t * tc, u64 value);
u64 session_lookup_half_open_handle (transport_connection_t * tc);
transport_connection_t *session_lookup_half_open_connection (u64 handle,
u8 proto,
u32
thread_index);
transport_connection_t *stream_session_lookup_transport4 (ip4_address_t * lcl,
ip4_address_t * rmt,
u16 lcl_port,
u16 rmt_port,
u8 proto);
transport_connection_t *stream_session_lookup_transport_wt6 (ip6_address_t *
lcl,
ip6_address_t *
rmt,
u16 lcl_port,
u16 rmt_port,
u8 proto,
u32
thread_index);
transport_connection_t *stream_session_lookup_transport6 (ip6_address_t * lcl,
ip6_address_t * rmt,
u16 lcl_port,
u16 rmt_port,
u8 proto);
u8 is_ip4);
u32 session_lookup_get_index_for_fib (u32 fib_proto, u32 fib_index);
stream_session_t *stream_session_lookup_listener (ip46_address_t * lcl,
u16 lcl_port, u8 proto);
u64 stream_session_half_open_lookup_handle (ip46_address_t * lcl,
ip46_address_t * rmt,
u16 lcl_port,
u16 rmt_port, u8 proto);
transport_connection_t *stream_session_half_open_lookup (ip46_address_t * lcl,
ip46_address_t * rmt,
u16 lcl_port,
u16 rmt_port,
u8 proto);
void stream_session_table_add_for_tc (transport_connection_t * tc, u64 value);
int stream_session_table_del_for_tc (transport_connection_t * tc);
int stream_session_table_del (stream_session_t * s);
void stream_session_half_open_table_del (transport_connection_t * tc);
void stream_session_half_open_table_add (transport_connection_t * tc,
u64 value);
u64 session_lookup_local_listener_make_handle (session_endpoint_t * sep);
u8 session_lookup_local_is_handle (u64 handle);
int session_lookup_local_listener_parse_handle (u64 handle,
session_endpoint_t * sep);
void session_lookup_show_table_entries (vlib_main_t * vm,
session_table_t * table, u8 type,
u8 is_local);
void session_lookup_init (void);
#endif /* SRC_VNET_SESSION_SESSION_LOOKUP_H_ */
+3 -3
View File
@@ -434,7 +434,7 @@ dump_thread_0_event_queue (void)
break;
case FIFO_EVENT_DISCONNECT:
s0 = stream_session_get_from_handle (e->session_handle);
s0 = session_get_from_handle (e->session_handle);
fformat (stdout, "[%04d] disconnect session %d\n", i,
s0->session_index);
break;
@@ -477,7 +477,7 @@ session_node_cmp_event (session_fifo_event_t * e, svm_fifo_t * f)
case FIFO_EVENT_DISCONNECT:
break;
case FIFO_EVENT_RPC:
s = stream_session_get_from_handle (e->session_handle);
s = session_get_from_handle (e->session_handle);
if (!s)
{
clib_warning ("session has event but doesn't exist!");
@@ -644,7 +644,7 @@ skip_dequeue:
}
break;
case FIFO_EVENT_DISCONNECT:
s0 = stream_session_get_from_handle (e0->session_handle);
s0 = session_get_from_handle (e0->session_handle);
stream_session_disconnect (s0);
break;
case FIFO_EVENT_BUILTIN_RX:
+124
View File
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2017 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vnet/session/session_table.h>
#include <vnet/session/session.h>
/**
* Pool of session tables
*/
static session_table_t *lookup_tables;
session_table_t *
session_table_alloc (void)
{
session_table_t *slt;
pool_get_aligned (lookup_tables, slt, CLIB_CACHE_LINE_BYTES);
memset (slt, 0, sizeof (*slt));
return slt;
}
u32
session_table_index (session_table_t * slt)
{
return (slt - lookup_tables);
}
session_table_t *
session_table_get (u32 table_index)
{
if (vec_len (lookup_tables) <= table_index)
return 0;
return vec_elt_at_index (lookup_tables, table_index);
}
#define foreach_hash_table_parameter \
_(v4,session,buckets,20000) \
_(v4,session,memory,(64<<20)) \
_(v6,session,buckets,20000) \
_(v6,session,memory,(64<<20)) \
_(v4,halfopen,buckets,20000) \
_(v4,halfopen,memory,(64<<20)) \
_(v6,halfopen,buckets,20000) \
_(v6,halfopen,memory,(64<<20))
/**
* Initialize session table hash tables
*
* If vpp configured with set of table parameters it uses them,
* otherwise it uses defaults above.
*/
void
session_table_init (session_table_t * slt)
{
#define _(af,table,parm,value) \
u32 configured_##af##_##table##_table_##parm = value;
foreach_hash_table_parameter;
#undef _
#define _(af,table,parm,value) \
if (session_manager_main.configured_##af##_##table##_table_##parm) \
configured_##af##_##table##_table_##parm = \
session_manager_main.configured_##af##_##table##_table_##parm;
foreach_hash_table_parameter;
#undef _
clib_bihash_init_16_8 (&slt->v4_session_hash, "v4 session table",
configured_v4_session_table_buckets,
configured_v4_session_table_memory);
clib_bihash_init_48_8 (&slt->v6_session_hash, "v6 session table",
configured_v6_session_table_buckets,
configured_v6_session_table_memory);
clib_bihash_init_16_8 (&slt->v4_half_open_hash, "v4 half-open table",
configured_v4_halfopen_table_buckets,
configured_v4_halfopen_table_memory);
clib_bihash_init_48_8 (&slt->v6_half_open_hash, "v6 half-open table",
configured_v6_halfopen_table_buckets,
configured_v6_halfopen_table_memory);
}
typedef struct _ip4_session_table_walk_ctx_t
{
ip4_session_table_walk_fn_t fn;
void *ctx;
} ip4_session_table_walk_ctx_t;
void
ip4_session_table_walk_cb (clib_bihash_kv_16_8_t * kvp, void *arg)
{
ip4_session_table_walk_ctx_t *ctx = arg;
ctx->fn (kvp, ctx->ctx);
}
void
ip4_session_table_walk (clib_bihash_16_8_t * hash,
ip4_session_table_walk_fn_t fn, void *arg)
{
ip4_session_table_walk_ctx_t ctx = {
.fn = fn,
.ctx = arg,
};
clib_bihash_foreach_key_value_pair_16_8 (hash, ip4_session_table_walk_cb,
&ctx);
}
/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/
+61
View File
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2017 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SRC_VNET_SESSION_SESSION_TABLE_H_
#define SRC_VNET_SESSION_SESSION_TABLE_H_
#include <vppinfra/bihash_16_8.h>
#include <vppinfra/bihash_48_8.h>
typedef struct _session_lookup_table
{
/**
* Lookup tables for established sessions and listeners
*/
clib_bihash_16_8_t v4_session_hash;
clib_bihash_48_8_t v6_session_hash;
/**
* Lookup tables for half-open sessions
*/
clib_bihash_16_8_t v4_half_open_hash;
clib_bihash_48_8_t v6_half_open_hash;
} session_table_t;
#define SESSION_TABLE_INVALID_INDEX ((u32)~0)
#define SESSION_LOCAL_TABLE_PREFIX ((u32)~0)
#define SESSION_INVALID_INDEX ((u32)~0)
typedef int (*ip4_session_table_walk_fn_t) (clib_bihash_kv_16_8_t * kvp,
void *ctx);
void ip4_session_table_walk_cb (clib_bihash_kv_16_8_t * kvp, void *arg);
void ip4_session_table_walk (clib_bihash_16_8_t * hash,
ip4_session_table_walk_fn_t fn, void *arg);
session_table_t *session_table_alloc (void);
session_table_t *session_table_get (u32 table_index);
u32 session_table_index (session_table_t * slt);
void session_table_init (session_table_t * slt);
#endif /* SRC_VNET_SESSION_SESSION_TABLE_H_ */
/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More