summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/CMakeLists.txt2
-rw-r--r--src/vnet/sctp/sctp.c6
-rw-r--r--src/vnet/sctp/sctp_output.c4
-rw-r--r--src/vnet/session/application.h2
-rw-r--r--src/vnet/session/session.c47
-rw-r--r--src/vnet/session/session.h205
-rwxr-xr-xsrc/vnet/session/session_api.c10
-rw-r--r--src/vnet/session/session_lookup.c55
-rw-r--r--src/vnet/session/session_lookup.h1
-rw-r--r--src/vnet/session/session_node.c9
-rw-r--r--src/vnet/session/session_types.h2
-rw-r--r--src/vnet/session/transport.c34
-rw-r--r--src/vnet/session/transport.h318
-rw-r--r--src/vnet/session/transport_interface.h182
-rw-r--r--src/vnet/session/transport_types.h197
-rw-r--r--src/vnet/tcp/tcp.c6
-rw-r--r--src/vnet/tcp/tcp_output.c17
-rw-r--r--src/vnet/tls/tls.c6
-rw-r--r--src/vnet/udp/udp.c12
19 files changed, 571 insertions, 544 deletions
diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt
index 72da325a08f..6c1eae8dbdf 100644
--- a/src/vnet/CMakeLists.txt
+++ b/src/vnet/CMakeLists.txt
@@ -1054,7 +1054,7 @@ list(APPEND VNET_HEADERS
session/session_lookup.h
session/application.h
session/transport.h
- session/transport_interface.h
+ session/transport_types.h
session/application_interface.h
session/application_namespace.h
session/session_debug.h
diff --git a/src/vnet/sctp/sctp.c b/src/vnet/sctp/sctp.c
index 86aef88f432..d0e28c53fe7 100644
--- a/src/vnet/sctp/sctp.c
+++ b/src/vnet/sctp/sctp.c
@@ -943,9 +943,9 @@ sctp_update_time (f64 now, u8 thread_index)
/* *INDENT OFF* */
const static transport_proto_vft_t sctp_proto = {
.enable = sctp_enable_disable,
- .bind = sctp_session_bind,
- .unbind = sctp_session_unbind,
- .open = sctp_session_open,
+ .start_listen = sctp_session_bind,
+ .stop_listen = sctp_session_unbind,
+ .connect = sctp_session_open,
.close = sctp_session_close,
.cleanup = sctp_session_cleanup,
.push_header = sctp_push_header,
diff --git a/src/vnet/sctp/sctp_output.c b/src/vnet/sctp/sctp_output.c
index 17b28a86492..8fea714f6a2 100644
--- a/src/vnet/sctp/sctp_output.c
+++ b/src/vnet/sctp/sctp_output.c
@@ -264,7 +264,7 @@ sctp_reuse_buffer (vlib_main_t * vm, vlib_buffer_t * b)
vnet_buffer (b)->sctp.subconn_idx = MAX_SCTP_CONNECTIONS;
/* Leave enough space for headers */
- return vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
+ return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
}
always_inline void *
@@ -277,7 +277,7 @@ sctp_init_buffer (vlib_main_t * vm, vlib_buffer_t * b)
vnet_buffer (b)->sctp.subconn_idx = MAX_SCTP_CONNECTIONS;
VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
/* Leave enough space for headers */
- return vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
+ return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
}
always_inline int
diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h
index f0c0a0d2403..e5bb00e2b14 100644
--- a/src/vnet/session/application.h
+++ b/src/vnet/session/application.h
@@ -16,7 +16,7 @@
#ifndef SRC_VNET_SESSION_APPLICATION_H_
#define SRC_VNET_SESSION_APPLICATION_H_
-#include <vnet/session/session.h>
+#include <vnet/session/session_types.h>
#include <vnet/session/segment_manager.h>
#include <vnet/session/application_namespace.h>
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 7b1c754d31c..6833a93e12b 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -20,12 +20,10 @@
#include <vnet/session/session.h>
#include <vnet/session/session_debug.h>
#include <vnet/session/application.h>
-#include <vlibmemory/api.h>
#include <vnet/dpo/load_balance.h>
#include <vnet/fib/ip4_fib.h>
session_manager_main_t session_manager_main;
-extern transport_proto_vft_t *tp_vfts;
static inline int
session_send_evt_to_thread (void *data, void *args, u32 thread_index,
@@ -752,14 +750,13 @@ static void
session_switch_pool (void *cb_args)
{
session_switch_pool_args_t *args = (session_switch_pool_args_t *) cb_args;
- transport_proto_t tp;
session_t *s;
ASSERT (args->thread_index == vlib_get_thread_index ());
s = session_get (args->session_index, args->thread_index);
s->tx_fifo->master_session_index = args->new_session_index;
s->tx_fifo->master_thread_index = args->new_thread_index;
- tp = session_get_transport_proto (s);
- tp_vfts[tp].cleanup (s->connection_index, s->thread_index);
+ transport_cleanup (session_get_transport_proto (s), s->connection_index,
+ s->thread_index);
session_free (s);
clib_mem_free (cb_args);
}
@@ -989,14 +986,14 @@ session_open_cl (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque)
int rv;
tep = session_endpoint_to_transport_cfg (rmt);
- rv = tp_vfts[rmt->transport_proto].open (tep);
+ rv = transport_connect (rmt->transport_proto, tep);
if (rv < 0)
{
SESSION_DBG ("Transport failed to open connection.");
return VNET_API_ERROR_SESSION_CONNECT;
}
- tc = tp_vfts[rmt->transport_proto].get_half_open ((u32) rv);
+ tc = transport_get_half_open (rmt->transport_proto, (u32) rv);
/* For dgram type of service, allocate session and fifos now.
*/
@@ -1024,14 +1021,14 @@ session_open_vc (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque)
int rv;
tep = session_endpoint_to_transport_cfg (rmt);
- rv = tp_vfts[rmt->transport_proto].open (tep);
+ rv = transport_connect (rmt->transport_proto, tep);
if (rv < 0)
{
SESSION_DBG ("Transport failed to open connection.");
return VNET_API_ERROR_SESSION_CONNECT;
}
- tc = tp_vfts[rmt->transport_proto].get_half_open ((u32) rv);
+ tc = transport_get_half_open (rmt->transport_proto, (u32) rv);
/* If transport offers a stream service, only allocate session once the
* connection has been established.
@@ -1059,7 +1056,7 @@ session_open_app (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque)
sep->app_wrk_index = app_wrk_index;
sep->opaque = opaque;
- return tp_vfts[rmt->transport_proto].open (tep_cfg);
+ return transport_connect (rmt->transport_proto, tep_cfg);
}
typedef int (*session_open_service_fn) (u32, session_endpoint_t *, u32);
@@ -1088,7 +1085,8 @@ static session_open_service_fn session_open_srv_fns[TRANSPORT_N_SERVICES] = {
int
session_open (u32 app_wrk_index, session_endpoint_t * rmt, u32 opaque)
{
- transport_service_type_t tst = tp_vfts[rmt->transport_proto].service_type;
+ transport_service_type_t tst;
+ tst = transport_protocol_service_type (rmt->transport_proto);
return session_open_srv_fns[tst] (app_wrk_index, rmt, opaque);
}
@@ -1110,7 +1108,7 @@ session_listen (session_t * ls, session_endpoint_cfg_t * sep)
/* Transport bind/listen */
tep = session_endpoint_to_transport (sep);
s_index = ls->session_index;
- tc_index = tp_vfts[sep->transport_proto].bind (s_index, tep);
+ tc_index = transport_start_listen (sep->transport_proto, s_index, tep);
if (tc_index == (u32) ~ 0)
return -1;
@@ -1120,7 +1118,7 @@ session_listen (session_t * ls, session_endpoint_cfg_t * sep)
ls->connection_index = tc_index;
/* Add to the main lookup table after transport was initialized */
- tc = tp_vfts[sep->transport_proto].get_listener (tc_index);
+ tc = transport_get_listener (sep->transport_proto, tc_index);
session_lookup_add_connection (tc, s_index);
return 0;
}
@@ -1135,21 +1133,16 @@ session_stop_listen (session_t * s)
{
transport_proto_t tp = session_get_transport_proto (s);
transport_connection_t *tc;
+
if (s->session_state != SESSION_STATE_LISTENING)
- {
- clib_warning ("not a listening session");
- return -1;
- }
+ return -1;
- tc = tp_vfts[tp].get_listener (s->connection_index);
+ tc = transport_get_listener (tp, s->connection_index);
if (!tc)
- {
- clib_warning ("no transport");
- return VNET_API_ERROR_ADDRESS_NOT_IN_USE;
- }
+ return VNET_API_ERROR_ADDRESS_NOT_IN_USE;
session_lookup_del_connection (tc);
- tp_vfts[tp].unbind (s->connection_index);
+ transport_stop_listen (tp, s->connection_index);
return 0;
}
@@ -1210,8 +1203,8 @@ session_transport_close (session_t * s)
else
s->session_state = SESSION_STATE_CLOSED;
- tp_vfts[session_get_transport_proto (s)].close (s->connection_index,
- s->thread_index);
+ transport_close (session_get_transport_proto (s), s->connection_index,
+ s->thread_index);
}
/**
@@ -1228,8 +1221,8 @@ session_transport_cleanup (session_t * s)
/* Delete from main lookup table before we axe the the transport */
session_lookup_del_session (s);
- tp_vfts[session_get_transport_proto (s)].cleanup (s->connection_index,
- s->thread_index);
+ transport_cleanup (session_get_transport_proto (s), s->connection_index,
+ s->thread_index);
/* Since we called cleanup, no delete notification will come. So, make
* sure the session is properly freed. */
session_free_w_fifos (s);
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index 68d82761dcd..c622e4eb74a 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -17,16 +17,12 @@
#include <vnet/session/session_types.h>
#include <vnet/session/session_lookup.h>
-#include <vnet/session/transport_interface.h>
#include <vnet/session/session_debug.h>
#include <vnet/session/segment_manager.h>
#include <svm/message_queue.h>
#define SESSION_PROXY_LISTENER_INDEX ((u8)~0 - 1)
-/* TODO decide how much since we have pre-data as well */
-#define MAX_HDRS_LEN 100 /* Max number of bytes for headers */
-
typedef enum
{
FIFO_EVENT_APP_RX,
@@ -298,21 +294,6 @@ extern vlib_node_registration_t session_queue_process_node;
#define SESSION_Q_PROCESS_FLUSH_FRAMES 1
#define SESSION_Q_PROCESS_STOP 2
-/*
- * Session manager function
- */
-always_inline session_manager_main_t *
-vnet_get_session_manager_main ()
-{
- return &session_manager_main;
-}
-
-always_inline session_manager_worker_t *
-session_manager_get_worker (u32 thread_index)
-{
- return &session_manager_main.wrk[thread_index];
-}
-
always_inline u8
stream_session_is_valid (u32 si, u8 thread_index)
{
@@ -438,53 +419,6 @@ session_get_from_handle_safe (u64 handle)
}
always_inline u32
-transport_max_rx_enqueue (transport_connection_t * tc)
-{
- session_t *s = session_get (tc->s_index, tc->thread_index);
- return svm_fifo_max_enqueue (s->rx_fifo);
-}
-
-always_inline u32
-transport_max_tx_dequeue (transport_connection_t * tc)
-{
- session_t *s = session_get (tc->s_index, tc->thread_index);
- return svm_fifo_max_dequeue (s->tx_fifo);
-}
-
-always_inline u32
-transport_rx_fifo_size (transport_connection_t * tc)
-{
- session_t *s = session_get (tc->s_index, tc->thread_index);
- return s->rx_fifo->nitems;
-}
-
-always_inline u32
-transport_tx_fifo_size (transport_connection_t * tc)
-{
- session_t *s = session_get (tc->s_index, tc->thread_index);
- return s->tx_fifo->nitems;
-}
-
-always_inline u8
-transport_rx_fifo_has_ooo_data (transport_connection_t * tc)
-{
- session_t *s = session_get (tc->c_index, tc->thread_index);
- return svm_fifo_has_ooo_data (s->rx_fifo);
-}
-
-always_inline f64
-transport_dispatch_period (u32 thread_index)
-{
- return session_manager_main.wrk[thread_index].dispatch_period;
-}
-
-always_inline f64
-transport_time_now (u32 thread_index)
-{
- return session_manager_main.wrk[thread_index].last_vlib_time;
-}
-
-always_inline u32
session_get_index (session_t * s)
{
return (s - session_manager_main.wrk[s->thread_index].sessions);
@@ -511,14 +445,34 @@ session_clone_safe (u32 session_index, u32 thread_index)
return new_s;
}
+int session_open (u32 app_index, session_endpoint_t * tep, u32 opaque);
+int session_listen (session_t * s, session_endpoint_cfg_t * sep);
+int session_stop_listen (session_t * s);
+void session_close (session_t * s);
+void session_transport_close (session_t * s);
+void session_transport_cleanup (session_t * s);
+int session_send_io_evt_to_thread (svm_fifo_t * f,
+ session_evt_type_t evt_type);
+int session_dequeue_notify (session_t * s);
+int session_send_io_evt_to_thread_custom (void *data, u32 thread_index,
+ session_evt_type_t evt_type);
+void session_send_rpc_evt_to_thread (u32 thread_index, void *fp,
+ void *rpc_args);
transport_connection_t *session_get_transport (session_t * s);
-u32 session_tx_fifo_max_dequeue (transport_connection_t * tc);
-int
-session_enqueue_stream_connection (transport_connection_t * tc,
- vlib_buffer_t * b, u32 offset,
- u8 queue_event, u8 is_in_order);
+u8 *format_stream_session (u8 * s, va_list * args);
+uword unformat_stream_session (unformat_input_t * input, va_list * args);
+uword unformat_transport_connection (unformat_input_t * input,
+ va_list * args);
+
+/*
+ * Interface to transport protos
+ */
+
+int session_enqueue_stream_connection (transport_connection_t * tc,
+ vlib_buffer_t * b, u32 offset,
+ u8 queue_event, u8 is_in_order);
int session_enqueue_dgram_connection (session_t * s,
session_dgram_hdr_t * hdr,
vlib_buffer_t * b, u8 proto,
@@ -531,7 +485,6 @@ int session_stream_connect_notify (transport_connection_t * tc, u8 is_fail);
int session_dgram_connect_notify (transport_connection_t * tc,
u32 old_thread_index,
session_t ** new_session);
-int session_dequeue_notify (session_t * s);
void stream_session_init_fifos_pointers (transport_connection_t * tc,
u32 rx_pointer, u32 tx_pointer);
@@ -542,30 +495,58 @@ void session_transport_closed_notify (transport_connection_t * tc);
void session_transport_reset_notify (transport_connection_t * tc);
int stream_session_accept (transport_connection_t * tc, u32 listener_index,
u8 notify);
-int session_open (u32 app_index, session_endpoint_t * tep, u32 opaque);
-int session_listen (session_t * s, session_endpoint_cfg_t * sep);
-int session_stop_listen (session_t * s);
-void session_close (session_t * s);
-void session_transport_close (session_t * s);
-void session_transport_cleanup (session_t * s);
-int session_send_io_evt_to_thread (svm_fifo_t * f,
- session_evt_type_t evt_type);
-int session_send_io_evt_to_thread_custom (void *data, u32 thread_index,
- session_evt_type_t evt_type);
-void session_send_rpc_evt_to_thread (u32 thread_index, void *fp,
- void *rpc_args);
-
-ssvm_private_t *session_manager_get_evt_q_segment (void);
-
-u8 *format_stream_session (u8 * s, va_list * args);
-uword unformat_stream_session (unformat_input_t * input, va_list * args);
-uword unformat_transport_connection (unformat_input_t * input,
- va_list * args);
-
+u32 session_tx_fifo_max_dequeue (transport_connection_t * tc);
void session_register_transport (transport_proto_t transport_proto,
const transport_proto_vft_t * vft, u8 is_ip4,
u32 output_node);
+always_inline u32
+transport_max_rx_enqueue (transport_connection_t * tc)
+{
+ session_t *s = session_get (tc->s_index, tc->thread_index);
+ return svm_fifo_max_enqueue (s->rx_fifo);
+}
+
+always_inline u32
+transport_max_tx_dequeue (transport_connection_t * tc)
+{
+ session_t *s = session_get (tc->s_index, tc->thread_index);
+ return svm_fifo_max_dequeue (s->tx_fifo);
+}
+
+always_inline u32
+transport_rx_fifo_size (transport_connection_t * tc)
+{
+ session_t *s = session_get (tc->s_index, tc->thread_index);
+ return s->rx_fifo->nitems;
+}
+
+always_inline u32
+transport_tx_fifo_size (transport_connection_t * tc)
+{
+ session_t *s = session_get (tc->s_index, tc->thread_index);
+ return s->tx_fifo->nitems;
+}
+
+always_inline u8
+transport_rx_fifo_has_ooo_data (transport_connection_t * tc)
+{
+ session_t *s = session_get (tc->c_index, tc->thread_index);
+ return svm_fifo_has_ooo_data (s->rx_fifo);
+}
+
+always_inline f64
+transport_dispatch_period (u32 thread_index)
+{
+ return session_manager_main.wrk[thread_index].dispatch_period;
+}
+
+always_inline f64
+transport_time_now (u32 thread_index)
+{
+ return session_manager_main.wrk[thread_index].last_vlib_time;
+}
+
always_inline void
transport_add_tx_event (transport_connection_t * tc)
{
@@ -575,16 +556,9 @@ transport_add_tx_event (transport_connection_t * tc)
session_send_io_evt_to_thread (s->tx_fifo, FIFO_EVENT_APP_TX);
}
-clib_error_t *vnet_session_enable_disable (vlib_main_t * vm, u8 is_en);
-
-always_inline svm_msg_q_t *
-session_manager_get_vpp_event_queue (u32 thread_index)
-{
- return session_manager_main.wrk[thread_index].vpp_event_queue;
-}
-
-int session_manager_flush_enqueue_events (u8 proto, u32 thread_index);
-int session_manager_flush_all_enqueue_events (u8 transport_proto);
+/*
+ * Listen sessions
+ */
always_inline u64
listen_session_get_handle (session_t * s)
@@ -634,7 +608,27 @@ int
listen_session_get_local_session_endpoint (session_t * listener,
session_endpoint_t * sep);
-void session_flush_frames_main_thread (vlib_main_t * vm);
+/*
+ * Session manager functions
+ */
+
+always_inline session_manager_main_t *
+vnet_get_session_manager_main ()
+{
+ return &session_manager_main;
+}
+
+always_inline session_manager_worker_t *
+session_manager_get_worker (u32 thread_index)
+{
+ return &session_manager_main.wrk[thread_index];
+}
+
+always_inline svm_msg_q_t *
+session_manager_get_vpp_event_queue (u32 thread_index)
+{
+ return session_manager_main.wrk[thread_index].vpp_event_queue;
+}
always_inline u8
session_manager_is_enabled ()
@@ -648,7 +642,12 @@ do { \
return clib_error_return(0, "session layer is not enabled"); \
} while (0)
+int session_manager_flush_enqueue_events (u8 proto, u32 thread_index);
+int session_manager_flush_all_enqueue_events (u8 transport_proto);
+void session_flush_frames_main_thread (vlib_main_t * vm);
+ssvm_private_t *session_manager_get_evt_q_segment (void);
void session_node_enable_disable (u8 is_en);
+clib_error_t *vnet_session_enable_disable (vlib_main_t * vm, u8 is_en);
#endif /* __included_session_h__ */
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index bd809367ce5..8196f4ca142 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -201,7 +201,6 @@ static int
send_session_accept_callback (session_t * s)
{
app_worker_t *server_wrk = app_worker_get (s->app_wrk_index);
- transport_proto_vft_t *tp_vft;
vl_api_accept_session_t *mp;
vl_api_registration_t *reg;
transport_connection_t *tc;
@@ -241,8 +240,8 @@ send_session_accept_callback (session_t * s)
vpp_queue = session_manager_get_vpp_event_queue (s->thread_index);
mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
mp->handle = session_handle (s);
- tp_vft = transport_protocol_get_vft (session_get_transport_proto (s));
- tc = tp_vft->get_connection (s->connection_index, s->thread_index);
+ tc = transport_get_connection (session_get_transport_proto (s),
+ s->connection_index, s->thread_index);
mp->port = tc->rmt_port;
mp->is_ip4 = tc->is_ip4;
clib_memcpy_fast (&mp->ip, &tc->rmt_ip, sizeof (tc->rmt_ip));
@@ -420,7 +419,6 @@ mq_send_session_accepted_cb (session_t * s)
app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
svm_msg_q_msg_t _msg, *msg = &_msg;
svm_msg_q_t *vpp_queue, *app_mq;
- transport_proto_vft_t *tp_vft;
transport_connection_t *tc;
session_t *listener;
session_accepted_msg_t *mp;
@@ -457,8 +455,8 @@ mq_send_session_accepted_cb (session_t * s)
vpp_queue = session_manager_get_vpp_event_queue (s->thread_index);
mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
mp->handle = session_handle (s);
- tp_vft = transport_protocol_get_vft (session_get_transport_proto (s));
- tc = tp_vft->get_connection (s->connection_index, s->thread_index);
+ tc = transport_get_connection (session_get_transport_proto (s),
+ s->connection_index, s->thread_index);
mp->port = tc->rmt_port;
mp->is_ip4 = tc->is_ip4;
clib_memcpy_fast (&mp->ip, &tc->rmt_ip, sizeof (tc->rmt_ip));
diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c
index 33fcb4250ca..f267a4cb7c3 100644
--- a/src/vnet/session/session_lookup.c
+++ b/src/vnet/session/session_lookup.c
@@ -30,11 +30,6 @@
#include <vnet/session/application.h>
/**
- * External vector of per transport virtual functions table
- */
-extern transport_proto_vft_t *tp_vfts;
-
-/**
* Network namespace index (i.e., fib index) to session lookup table. We
* should have one per network protocol type but for now we only support IP4/6
*/
@@ -340,9 +335,9 @@ session_lookup_del_connection (transport_connection_t * tc)
int
session_lookup_del_session (session_t * s)
{
- transport_proto_t tp = session_get_transport_proto (s);
transport_connection_t *ts;
- ts = tp_vfts[tp].get_connection (s->connection_index, s->thread_index);
+ ts = transport_get_connection (session_get_transport_proto (s),
+ s->connection_index, s->thread_index);
return session_lookup_del_connection (ts);
}
@@ -812,12 +807,10 @@ session_lookup_half_open_handle (transport_connection_t * tc)
transport_connection_t *
session_lookup_half_open_connection (u64 handle, u8 proto, u8 is_ip4)
{
- u32 sst;
-
if (handle != HALF_OPEN_LOOKUP_INVALID_VALUE)
{
- sst = session_type_from_proto_and_ip (proto, is_ip4);
- return tp_vfts[sst].get_half_open (handle & 0xFFFFFFFF);
+ u32 sst = session_type_from_proto_and_ip (proto, is_ip4);
+ return transport_get_half_open (sst, handle & 0xFFFFFFFF);
}
return 0;
}
@@ -877,8 +870,8 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
return 0;
}
s = session_get (kv4.value & 0xFFFFFFFFULL, thread_index);
- return tp_vfts[proto].get_connection (s->connection_index,
- thread_index);
+ return transport_get_connection (proto, s->connection_index,
+ thread_index);
}
/*
@@ -886,7 +879,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
*/
rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
if (rv == 0)
- return tp_vfts[proto].get_half_open (kv4.value & 0xFFFFFFFF);
+ return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
/*
* Check the session rules table
@@ -902,7 +895,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
}
if ((s = session_lookup_action_to_session (action_index,
FIB_PROTOCOL_IP4, proto)))
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
@@ -911,7 +904,7 @@ session_lookup_connection_wt4 (u32 fib_index, ip4_address_t * lcl,
*/
s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1);
if (s)
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
@@ -954,8 +947,8 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
if (rv == 0)
{
s = session_get_from_handle (kv4.value);
- return tp_vfts[proto].get_connection (s->connection_index,
- s->thread_index);
+ return transport_get_connection (proto, s->connection_index,
+ s->thread_index);
}
/*
@@ -963,7 +956,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
*/
rv = clib_bihash_search_inline_16_8 (&st->v4_half_open_hash, &kv4);
if (rv == 0)
- return tp_vfts[proto].get_half_open (kv4.value & 0xFFFFFFFF);
+ return transport_get_half_open (proto, kv4.value & 0xFFFFFFFF);
/*
* Check the session rules table
@@ -976,7 +969,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
return 0;
if ((s = session_lookup_action_to_session (action_index,
FIB_PROTOCOL_IP4, proto)))
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
@@ -985,7 +978,7 @@ session_lookup_connection4 (u32 fib_index, ip4_address_t * lcl,
*/
s = session_lookup_listener4_i (st, lcl, lcl_port, proto, 1);
if (s)
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
@@ -1099,14 +1092,14 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
return 0;
}
s = session_get (kv6.value & 0xFFFFFFFFULL, thread_index);
- return tp_vfts[proto].get_connection (s->connection_index,
- thread_index);
+ return transport_get_connection (proto, s->connection_index,
+ thread_index);
}
/* Try half-open connections */
rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
if (rv == 0)
- return tp_vfts[proto].get_half_open (kv6.value & 0xFFFFFFFF);
+ return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
/* Check the session rules table */
action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
@@ -1120,14 +1113,14 @@ session_lookup_connection_wt6 (u32 fib_index, ip6_address_t * lcl,
}
if ((s = session_lookup_action_to_session (action_index,
FIB_PROTOCOL_IP6, proto)))
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
/* If nothing is found, check if any listener is available */
s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1);
if (s)
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
@@ -1168,14 +1161,14 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl,
if (rv == 0)
{
s = session_get_from_handle (kv6.value);
- return tp_vfts[proto].get_connection (s->connection_index,
- s->thread_index);
+ return transport_get_connection (proto, s->connection_index,
+ s->thread_index);
}
/* Try half-open connections */
rv = clib_bihash_search_inline_48_8 (&st->v6_half_open_hash, &kv6);
if (rv == 0)
- return tp_vfts[proto].get_half_open (kv6.value & 0xFFFFFFFF);
+ return transport_get_half_open (proto, kv6.value & 0xFFFFFFFF);
/* Check the session rules table */
action_index = session_rules_table_lookup6 (&st->session_rules[proto], lcl,
@@ -1186,14 +1179,14 @@ session_lookup_connection6 (u32 fib_index, ip6_address_t * lcl,
return 0;
if ((s = session_lookup_action_to_session (action_index,
FIB_PROTOCOL_IP6, proto)))
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
/* If nothing is found, check if any listener is available */
s = session_lookup_listener6_i (st, lcl, lcl_port, proto, 1);
if (s)
- return tp_vfts[proto].get_listener (s->connection_index);
+ return transport_get_listener (proto, s->connection_index);
return 0;
}
diff --git a/src/vnet/session/session_lookup.h b/src/vnet/session/session_lookup.h
index 5efb1f41025..995d2aaf980 100644
--- a/src/vnet/session/session_lookup.h
+++ b/src/vnet/session/session_lookup.h
@@ -18,7 +18,6 @@
#include <vnet/session/session_table.h>
#include <vnet/session/session_types.h>
-#include <vnet/session/transport.h>
#include <vnet/session/application_namespace.h>
#define HALF_OPEN_LOOKUP_INVALID_VALUE ((u64)~0)
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index fa33ad37f1e..286bd7b32e0 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -447,7 +447,7 @@ session_tx_fill_buffer (vlib_main_t * vm, session_tx_context_t * ctx,
b->flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
b->current_data = 0;
- data0 = vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
+ data0 = vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
len_to_deq = clib_min (ctx->left_to_snd, ctx->deq_per_first_buf);
if (peek_data)
@@ -606,12 +606,13 @@ session_tx_set_dequeue_params (vlib_main_t * vm, session_tx_context_t * ctx,
}
n_bytes_per_buf = VLIB_BUFFER_DATA_SIZE;
- ASSERT (n_bytes_per_buf > MAX_HDRS_LEN);
- n_bytes_per_seg = MAX_HDRS_LEN + ctx->snd_mss;
+ ASSERT (n_bytes_per_buf > TRANSPORT_MAX_HDRS_LEN);
+ n_bytes_per_seg = TRANSPORT_MAX_HDRS_LEN + ctx->snd_mss;
ctx->n_bufs_per_seg = ceil ((f64) n_bytes_per_seg / n_bytes_per_buf);
ctx->deq_per_buf = clib_min (ctx->snd_mss, n_bytes_per_buf);
ctx->deq_per_first_buf = clib_min (ctx->snd_mss,
- n_bytes_per_buf - MAX_HDRS_LEN);
+ n_bytes_per_buf -
+ TRANSPORT_MAX_HDRS_LEN);
}
always_inline int
diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h
index b334c3c9f69..286f4c49d80 100644
--- a/src/vnet/session/session_types.h
+++ b/src/vnet/session/session_types.h
@@ -17,7 +17,7 @@
#define SRC_VNET_SESSION_SESSION_TYPES_H_
#include <svm/svm_fifo.h>
-#include <vnet/session/transport.h>
+#include <vnet/session/transport_types.h>
#define SESSION_LOCAL_HANDLE_PREFIX 0x7FFFFFFF
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index df5282cc43a..2c4efe15806 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-#include <vnet/session/transport_interface.h>
+#include <vnet/session/transport.h>
#include <vnet/session/session.h>
#include <vnet/fib/fib.h>
@@ -271,17 +271,35 @@ transport_protocol_tx_fn_type (transport_proto_t tp)
return tp_vfts[tp].tx_type;
}
-transport_connection_t *
-transport_get_connection (transport_proto_t tp, u32 conn_index,
- u8 thread_index)
+void
+transport_cleanup (transport_proto_t tp, u32 conn_index, u8 thread_index)
+{
+ tp_vfts[tp].cleanup (conn_index, thread_index);
+}
+
+int
+transport_connect (transport_proto_t tp, transport_endpoint_cfg_t * tep)
+{
+ return tp_vfts[tp].connect (tep);
+}
+
+void
+transport_close (transport_proto_t tp, u32 conn_index, u8 thread_index)
{
- return tp_vfts[tp].get_connection (conn_index, thread_index);
+ tp_vfts[tp].close (conn_index, thread_index);
}
-transport_connection_t *
-transport_get_listener (transport_proto_t tp, u32 conn_index)
+u32
+transport_start_listen (transport_proto_t tp, u32 session_index,
+ transport_endpoint_t * tep)
+{
+ return tp_vfts[tp].start_listen (session_index, tep);
+}
+
+u32
+transport_stop_listen (transport_proto_t tp, u32 conn_index)
{
- return tp_vfts[tp].get_listener (conn_index);
+ return tp_vfts[tp].stop_listen (conn_index);
}
u8
diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h
index a82dc3d8493..8500e9d2445 100644
--- a/src/vnet/session/transport.h
+++ b/src/vnet/session/transport.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2019 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:
@@ -13,184 +13,194 @@
* limitations under the License.
*/
-#ifndef VNET_VNET_URI_TRANSPORT_H_
-#define VNET_VNET_URI_TRANSPORT_H_
+#ifndef SRC_VNET_SESSION_TRANSPORT_H_
+#define SRC_VNET_SESSION_TRANSPORT_H_
#include <vnet/vnet.h>
-#include <vnet/ip/ip.h>
-#include <vnet/tcp/tcp_debug.h>
+#include <vnet/session/transport_types.h>
-typedef enum transport_dequeue_type_
+/*
+ * Transport protocol virtual function table
+ */
+/* *INDENT-OFF* */
+typedef struct _transport_proto_vft
{
- TRANSPORT_TX_PEEK, /**< reliable transport protos */
- TRANSPORT_TX_DEQUEUE, /**< unreliable transport protos */
- TRANSPORT_TX_INTERNAL, /**< apps acting as transports */
- TRANSPORT_TX_DGRAM, /**< datagram mode */
- TRANSPORT_TX_N_FNS
-} transport_tx_fn_type_t;
-
-typedef enum transport_service_type_
+ /*
+ * Setup
+ */
+ u32 (*start_listen) (u32 session_index, transport_endpoint_t * lcl);
+ u32 (*stop_listen) (u32 conn_index);
+ int (*connect) (transport_endpoint_cfg_t * rmt);
+ void (*close) (u32 conn_index, u32 thread_index);
+ void (*cleanup) (u32 conn_index, u32 thread_index);
+ clib_error_t *(*enable) (vlib_main_t * vm, u8 is_en);
+
+ /*
+ * Transmission
+ */
+
+ u32 (*push_header) (transport_connection_t * tconn, vlib_buffer_t * b);
+ u16 (*send_mss) (transport_connection_t * tc);
+ u32 (*send_space) (transport_connection_t * tc);
+ u32 (*tx_fifo_offset) (transport_connection_t * tc);
+ void (*update_time) (f64 time_now, u8 thread_index);
+ void (*flush_data) (transport_connection_t *tconn);
+
+ /*
+ * Connection retrieval
+ */
+ transport_connection_t *(*get_connection) (u32 conn_idx, u32 thread_idx);
+ transport_connection_t *(*get_listener) (u32 conn_index);
+ transport_connection_t *(*get_half_open) (u32 conn_index);
+
+ /*
+ * Format
+ */
+ u8 *(*format_connection) (u8 * s, va_list * args);
+ u8 *(*format_listener) (u8 * s, va_list * args);
+ u8 *(*format_half_open) (u8 * s, va_list * args);
+
+ /*
+ * Properties
+ */
+ transport_tx_fn_type_t tx_type;
+ transport_service_type_t service_type;
+} transport_proto_vft_t;
+/* *INDENT-ON* */
+
+extern transport_proto_vft_t *tp_vfts;
+
+#define transport_proto_foreach(VAR, BODY) \
+do { \
+ for (VAR = 0; VAR < vec_len (tp_vfts); VAR++) \
+ if (tp_vfts[VAR].push_header != 0) \
+ do { BODY; } while (0); \
+} while (0)
+
+int transport_connect (transport_proto_t tp, transport_endpoint_cfg_t * tep);
+void transport_close (transport_proto_t tp, u32 conn_index, u8 thread_index);
+u32 transport_start_listen (transport_proto_t tp, u32 session_index,
+ transport_endpoint_t * tep);
+u32 transport_stop_listen (transport_proto_t tp, u32 conn_index);
+void transport_cleanup (transport_proto_t tp, u32 conn_index,
+ u8 thread_index);
+
+static inline transport_connection_t *
+transport_get_connection (transport_proto_t tp, u32 conn_index,
+ u8 thread_index)
{
- TRANSPORT_SERVICE_VC, /**< virtual circuit service */
- TRANSPORT_SERVICE_CL, /**< connectionless service */
- TRANSPORT_SERVICE_APP, /**< app transport service */
- TRANSPORT_N_SERVICES
-} transport_service_type_t;
+ return tp_vfts[tp].get_connection (conn_index, thread_index);
+}
-typedef struct _transport_stats
+static inline transport_connection_t *
+transport_get_listener (transport_proto_t tp, u32 conn_index)
{
- u64 tx_bytes;
-} transport_stats_t;
+ return tp_vfts[tp].get_listener (conn_index);
+}
-typedef struct _spacer
+static inline transport_connection_t *
+transport_get_half_open (transport_proto_t tp, u32 conn_index)
{
- u64 bucket;
- u32 max_burst_size;
- f32 tokens_per_period;
- u64 last_update;
-} spacer_t;
+ return tp_vfts[tp].get_half_open (conn_index);
+}
-/*
- * Protocol independent transport properties associated to a session
- */
-typedef struct _transport_connection
-{
- /** Connection ID */
- union
- {
- /*
- * Network connection ID tuple
- */
- struct
- {
- ip46_address_t rmt_ip; /**< Remote IP */
- ip46_address_t lcl_ip; /**< Local IP */
- u16 rmt_port; /**< Remote port */
- u16 lcl_port; /**< Local port */
- u8 is_ip4; /**< Flag if IP4 connection */
- u8 proto; /**< Protocol id */
- u32 fib_index; /**< Network namespace */
- };
- /*
- * Opaque connection ID
- */
- u8 opaque_conn_id[42];
- };
-
- u32 s_index; /**< Parent session index */
- u32 c_index; /**< Connection index in transport pool */
- u32 thread_index; /**< Worker-thread index */
-
- /*fib_node_index_t rmt_fei;
- dpo_id_t rmt_dpo; */
-
- u8 flags; /**< Transport specific flags */
- transport_stats_t stats; /**< Transport connection stats */
- spacer_t pacer; /**< Simple transport pacer */
+void transport_register_protocol (transport_proto_t transport_proto,
+ const transport_proto_vft_t * vft,
+ fib_protocol_t fib_proto, u32 output_node);
+transport_proto_vft_t *transport_protocol_get_vft (transport_proto_t tp);
+void transport_update_time (f64 time_now, u8 thread_index);
+int transport_alloc_local_port (u8 proto, ip46_address_t * ip);
+int transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt,
+ ip46_address_t * lcl_addr,
+ u16 * lcl_port);
+void transport_endpoint_cleanup (u8 proto, ip46_address_t * lcl_ip, u16 port);
+void transport_enable_disable (vlib_main_t * vm, u8 is_en);
+void transport_init (void);
+
+always_inline u32
+transport_elog_track_index (transport_connection_t * tc)
+{
#if TRANSPORT_DEBUG
- elog_track_t elog_track; /**< Event logging */
- u32 cc_stat_tstamp; /**< CC stats timestamp */
+ return tc->elog_track.track_index_plus_one - 1;
+#else
+ return ~0;
#endif
+}
- /** Macros for 'derived classes' where base is named "connection" */
-#define c_lcl_ip connection.lcl_ip
-#define c_rmt_ip connection.rmt_ip
-#define c_lcl_ip4 connection.lcl_ip.ip4
-#define c_rmt_ip4 connection.rmt_ip.ip4
-#define c_lcl_ip6 connection.lcl_ip.ip6
-#define c_rmt_ip6 connection.rmt_ip.ip6
-#define c_lcl_port connection.lcl_port
-#define c_rmt_port connection.rmt_port
-#define c_proto connection.proto
-#define c_fib_index connection.fib_index
-#define c_s_index connection.s_index
-#define c_c_index connection.c_index
-#define c_is_ip4 connection.is_ip4
-#define c_thread_index connection.thread_index
-#define c_elog_track connection.elog_track
-#define c_cc_stat_tstamp connection.cc_stat_tstamp
-#define c_rmt_fei connection.rmt_fei
-#define c_rmt_dpo connection.rmt_dpo
-#define c_opaque_id connection.opaque_conn_id
-#define c_stats connection.stats
-#define c_pacer connection.pacer
-#define c_flags connection.flags
-} transport_connection_t;
-
-#define TRANSPORT_CONNECTION_F_IS_TX_PACED 1 << 0
-
-typedef enum _transport_proto
-{
- TRANSPORT_PROTO_TCP,
- TRANSPORT_PROTO_UDP,
- TRANSPORT_PROTO_SCTP,
- TRANSPORT_PROTO_NONE,
- TRANSPORT_PROTO_TLS,
- TRANSPORT_PROTO_UDPC,
- TRANSPORT_N_PROTO
-} transport_proto_t;
-
-u8 *format_transport_proto (u8 * s, va_list * args);
-u8 *format_transport_proto_short (u8 * s, va_list * args);
-u8 *format_transport_connection (u8 * s, va_list * args);
-u8 *format_transport_listen_connection (u8 * s, va_list * args);
-u8 *format_transport_half_open_connection (u8 * s, va_list * args);
-
-uword unformat_transport_proto (unformat_input_t * input, va_list * args);
-
-#define foreach_transport_endpoint_fields \
- _(ip46_address_t, ip) /**< ip address in net order */ \
- _(u16, port) /**< port in net order */ \
- _(u8, is_ip4) /**< set if ip4 */ \
- _(u32, sw_if_index) /**< interface endpoint is associated with */ \
- _(u32, fib_index) /**< fib table endpoint is associated with */ \
-
-typedef struct transport_endpoint_
-{
-#define _(type, name) type name;
- foreach_transport_endpoint_fields
-#undef _
-} transport_endpoint_t;
+void transport_connection_tx_pacer_reset (transport_connection_t * tc,
+ u32 rate_bytes_per_sec,
+ u32 initial_bucket, u64 time_now);
+/**
+ * Initialize tx pacer for connection
+ *
+ * @param tc transport connection
+ * @param rate_bytes_per_second initial byte rate
+ * @param burst_bytes initial burst size in bytes
+ */
+void transport_connection_tx_pacer_init (transport_connection_t * tc,
+ u32 rate_bytes_per_sec,
+ u32 initial_bucket);
-#define foreach_transport_endpoint_cfg_fields \
- foreach_transport_endpoint_fields \
- _(transport_endpoint_t, peer) \
+/**
+ * Update tx pacer pacing rate
+ *
+ * @param tc transport connection
+ * @param bytes_per_sec new pacing rate
+ */
+void transport_connection_tx_pacer_update (transport_connection_t * tc,
+ u64 bytes_per_sec);
-typedef struct transport_endpoint_pair_
-{
-#define _(type, name) type name;
- foreach_transport_endpoint_cfg_fields
-#undef _
-} transport_endpoint_cfg_t;
+/**
+ * Get maximum tx burst allowed for transport connection
+ *
+ * @param tc transport connection
+ * @param time_now current cpu time as returned by @ref clib_cpu_time_now
+ * @param mss transport's mss
+ */
+u32 transport_connection_snd_space (transport_connection_t * tc,
+ u64 time_now, u16 mss);
-typedef clib_bihash_24_8_t transport_endpoint_table_t;
+u32 transport_connection_tx_pacer_burst (transport_connection_t * tc,
+ u64 time_now);
-#define ENDPOINT_INVALID_INDEX ((u32)~0)
+/**
+ * Initialize period for tx pacers
+ *
+ * Defines a unit of time with respect to number of cpu cycles that is to
+ * be used by all tx pacers.
+ */
+void transport_init_tx_pacers_period (void);
+/**
+ * Check if transport connection is paced
+ */
always_inline u8
-transport_connection_fib_proto (transport_connection_t * tc)
+transport_connection_is_tx_paced (transport_connection_t * tc)
{
- return tc->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+ return (tc->flags & TRANSPORT_CONNECTION_F_IS_TX_PACED);
}
-always_inline u8
-transport_endpoint_fib_proto (transport_endpoint_t * tep)
-{
- return tep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
-}
+u8 *format_transport_pacer (u8 * s, va_list * args);
-int transport_alloc_local_port (u8 proto, ip46_address_t * ip);
-int transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t * rmt,
- ip46_address_t * lcl_addr,
- u16 * lcl_port);
-void transport_endpoint_cleanup (u8 proto, ip46_address_t * lcl_ip, u16 port);
-u8 transport_protocol_is_cl (transport_proto_t tp);
-transport_service_type_t transport_protocol_service_type (transport_proto_t);
-transport_tx_fn_type_t transport_protocol_tx_fn_type (transport_proto_t tp);
-void transport_init (void);
+/**
+ * Update tx byte stats for transport connection
+ *
+ * If tx pacing is enabled, this also updates pacer bucket to account for the
+ * amount of bytes that have been sent.
+ *
+ * @param tc transport connection
+ * @param pkts packets recently sent
+ * @param bytes bytes recently sent
+ */
+void transport_connection_update_tx_stats (transport_connection_t * tc,
+ u32 bytes);
+
+void
+transport_connection_tx_pacer_update_bytes (transport_connection_t * tc,
+ u32 bytes);
-#endif /* VNET_VNET_URI_TRANSPORT_H_ */
+#endif /* SRC_VNET_SESSION_TRANSPORT_H_ */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/session/transport_interface.h b/src/vnet/session/transport_interface.h
deleted file mode 100644
index 123048613bf..00000000000
--- a/src/vnet/session/transport_interface.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_TRANSPORT_INTERFACE_H_
-#define SRC_VNET_SESSION_TRANSPORT_INTERFACE_H_
-
-#include <vnet/vnet.h>
-#include <vnet/session/transport.h>
-
-/*
- * Transport protocol virtual function table
- */
-/* *INDENT-OFF* */
-typedef struct _transport_proto_vft
-{
- /*
- * Setup
- */
- u32 (*bind) (u32 session_index, transport_endpoint_t * lcl);
- u32 (*unbind) (u32);
- int (*open) (transport_endpoint_cfg_t * rmt);
- void (*close) (u32 conn_index, u32 thread_index);
- void (*cleanup) (u32 conn_index, u32 thread_index);
- clib_error_t *(*enable) (vlib_main_t * vm, u8 is_en);
-
- /*
- * Transmission
- */
-
- u32 (*push_header) (transport_connection_t * tconn, vlib_buffer_t * b);
- u16 (*send_mss) (transport_connection_t * tc);
- u32 (*send_space) (transport_connection_t * tc);
- u32 (*tx_fifo_offset) (transport_connection_t * tc);
- void (*update_time) (f64 time_now, u8 thread_index);
- void (*flush_data) (transport_connection_t *tconn);
-
- /*
- * Connection retrieval
- */
- transport_connection_t *(*get_connection) (u32 conn_idx, u32 thread_idx);
- transport_connection_t *(*get_listener) (u32 conn_index);
- transport_connection_t *(*get_half_open) (u32 conn_index);
-
- /*
- * Format
- */
- u8 *(*format_connection) (u8 * s, va_list * args);
- u8 *(*format_listener) (u8 * s, va_list * args);
- u8 *(*format_half_open) (u8 * s, va_list * args);
-
- /*
- * Properties
- */
- transport_tx_fn_type_t tx_type;
- transport_service_type_t service_type;
-} transport_proto_vft_t;
-/* *INDENT-ON* */
-
-extern transport_proto_vft_t *tp_vfts;
-
-#define transport_proto_foreach(VAR, BODY) \
-do { \
- for (VAR = 0; VAR < vec_len (tp_vfts); VAR++) \
- if (tp_vfts[VAR].push_header != 0) \
- do { BODY; } while (0); \
-} while (0)
-
-void transport_register_protocol (transport_proto_t transport_proto,
- const transport_proto_vft_t * vft,
- fib_protocol_t fib_proto, u32 output_node);
-transport_proto_vft_t *transport_protocol_get_vft (transport_proto_t tp);
-void transport_update_time (f64 time_now, u8 thread_index);
-transport_connection_t *transport_get_connection (transport_proto_t tp,
- u32 conn_index,
- u8 thread_index);
-transport_connection_t *transport_get_listener (transport_proto_t tp,
- u32 conn_index);
-void transport_enable_disable (vlib_main_t * vm, u8 is_en);
-
-always_inline u32
-transport_elog_track_index (transport_connection_t * tc)
-{
-#if TRANSPORT_DEBUG
- return tc->elog_track.track_index_plus_one - 1;
-#else
- return ~0;
-#endif
-}
-
-void transport_connection_tx_pacer_reset (transport_connection_t * tc,
- u32 rate_bytes_per_sec,
- u32 initial_bucket, u64 time_now);
-/**
- * Initialize tx pacer for connection
- *
- * @param tc transport connection
- * @param rate_bytes_per_second initial byte rate
- * @param burst_bytes initial burst size in bytes
- */
-void transport_connection_tx_pacer_init (transport_connection_t * tc,
- u32 rate_bytes_per_sec,
- u32 initial_bucket);
-
-/**
- * Update tx pacer pacing rate
- *
- * @param tc transport connection
- * @param bytes_per_sec new pacing rate
- */
-void transport_connection_tx_pacer_update (transport_connection_t * tc,
- u64 bytes_per_sec);
-
-/**
- * Get maximum tx burst allowed for transport connection
- *
- * @param tc transport connection
- * @param time_now current cpu time as returned by @ref clib_cpu_time_now
- * @param mss transport's mss
- */
-u32 transport_connection_snd_space (transport_connection_t * tc,
- u64 time_now, u16 mss);
-
-u32 transport_connection_tx_pacer_burst (transport_connection_t * tc,
- u64 time_now);
-
-/**
- * Initialize period for tx pacers
- *
- * Defines a unit of time with respect to number of cpu cycles that is to
- * be used by all tx pacers.
- */
-void transport_init_tx_pacers_period (void);
-
-/**
- * Check if transport connection is paced
- */
-always_inline u8
-transport_connection_is_tx_paced (transport_connection_t * tc)
-{
- return (tc->flags & TRANSPORT_CONNECTION_F_IS_TX_PACED);
-}
-
-u8 *format_transport_pacer (u8 * s, va_list * args);
-
-/**
- * Update tx byte stats for transport connection
- *
- * If tx pacing is enabled, this also updates pacer bucket to account for the
- * amount of bytes that have been sent.
- *
- * @param tc transport connection
- * @param pkts packets recently sent
- * @param bytes bytes recently sent
- */
-void transport_connection_update_tx_stats (transport_connection_t * tc,
- u32 bytes);
-
-void
-transport_connection_tx_pacer_update_bytes (transport_connection_t * tc,
- u32 bytes);
-
-#endif /* SRC_VNET_SESSION_TRANSPORT_INTERFACE_H_ */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h
new file mode 100644
index 00000000000..d309c581db8
--- /dev/null
+++ b/src/vnet/session/transport_types.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2016-2019 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 VNET_VNET_URI_TRANSPORT_TYPES_H_
+#define VNET_VNET_URI_TRANSPORT_TYPES_H_
+
+#include <vnet/vnet.h>
+#include <vnet/ip/ip.h>
+#include <vnet/tcp/tcp_debug.h>
+
+#define TRANSPORT_MAX_HDRS_LEN 100 /* Max number of bytes for headers */
+
+typedef enum transport_dequeue_type_
+{
+ TRANSPORT_TX_PEEK, /**< reliable transport protos */
+ TRANSPORT_TX_DEQUEUE, /**< unreliable transport protos */
+ TRANSPORT_TX_INTERNAL, /**< apps acting as transports */
+ TRANSPORT_TX_DGRAM, /**< datagram mode */
+ TRANSPORT_TX_N_FNS
+} transport_tx_fn_type_t;
+
+typedef enum transport_service_type_
+{
+ TRANSPORT_SERVICE_VC, /**< virtual circuit service */
+ TRANSPORT_SERVICE_CL, /**< connectionless service */
+ TRANSPORT_SERVICE_APP, /**< app transport service */
+ TRANSPORT_N_SERVICES
+} transport_service_type_t;
+
+typedef struct _transport_stats
+{
+ u64 tx_bytes;
+} transport_stats_t;
+
+typedef struct _spacer
+{
+ u64 bucket;
+ u32 max_burst_size;
+ f32 tokens_per_period;
+ u64 last_update;
+} spacer_t;
+
+/*
+ * Protocol independent transport properties associated to a session
+ */
+typedef struct _transport_connection
+{
+ /** Connection ID */
+ union
+ {
+ /*
+ * Network connection ID tuple
+ */
+ struct
+ {
+ ip46_address_t rmt_ip; /**< Remote IP */
+ ip46_address_t lcl_ip; /**< Local IP */
+ u16 rmt_port; /**< Remote port */
+ u16 lcl_port; /**< Local port */
+ u8 is_ip4; /**< Flag if IP4 connection */
+ u8 proto; /**< Protocol id */
+ u32 fib_index; /**< Network namespace */
+ };
+ /*
+ * Opaque connection ID
+ */
+ u8 opaque_conn_id[42];
+ };
+
+ u32 s_index; /**< Parent session index */
+ u32 c_index; /**< Connection index in transport pool */
+ u32 thread_index; /**< Worker-thread index */
+
+ /*fib_node_index_t rmt_fei;
+ dpo_id_t rmt_dpo; */
+
+ u8 flags; /**< Transport specific flags */
+ transport_stats_t stats; /**< Transport connection stats */
+ spacer_t pacer; /**< Simple transport pacer */
+
+#if TRANSPORT_DEBUG
+ elog_track_t elog_track; /**< Event logging */
+ u32 cc_stat_tstamp; /**< CC stats timestamp */
+#endif
+
+ /** Macros for 'derived classes' where base is named "connection" */
+#define c_lcl_ip connection.lcl_ip
+#define c_rmt_ip connection.rmt_ip
+#define c_lcl_ip4 connection.lcl_ip.ip4
+#define c_rmt_ip4 connection.rmt_ip.ip4
+#define c_lcl_ip6 connection.lcl_ip.ip6
+#define c_rmt_ip6 connection.rmt_ip.ip6
+#define c_lcl_port connection.lcl_port
+#define c_rmt_port connection.rmt_port
+#define c_proto connection.proto
+#define c_fib_index connection.fib_index
+#define c_s_index connection.s_index
+#define c_c_index connection.c_index
+#define c_is_ip4 connection.is_ip4
+#define c_thread_index connection.thread_index
+#define c_elog_track connection.elog_track
+#define c_cc_stat_tstamp connection.cc_stat_tstamp
+#define c_rmt_fei connection.rmt_fei
+#define c_rmt_dpo connection.rmt_dpo
+#define c_opaque_id connection.opaque_conn_id
+#define c_stats connection.stats
+#define c_pacer connection.pacer
+#define c_flags connection.flags
+} transport_connection_t;
+
+#define TRANSPORT_CONNECTION_F_IS_TX_PACED 1 << 0
+
+typedef enum _transport_proto
+{
+ TRANSPORT_PROTO_TCP,
+ TRANSPORT_PROTO_UDP,
+ TRANSPORT_PROTO_SCTP,
+ TRANSPORT_PROTO_NONE,
+ TRANSPORT_PROTO_TLS,
+ TRANSPORT_PROTO_UDPC,
+ TRANSPORT_N_PROTO
+} transport_proto_t;
+
+u8 *format_transport_proto (u8 * s, va_list * args);
+u8 *format_transport_proto_short (u8 * s, va_list * args);
+u8 *format_transport_connection (u8 * s, va_list * args);
+u8 *format_transport_listen_connection (u8 * s, va_list * args);
+u8 *format_transport_half_open_connection (u8 * s, va_list * args);
+
+uword unformat_transport_proto (unformat_input_t * input, va_list * args);
+
+#define foreach_transport_endpoint_fields \
+ _(ip46_address_t, ip) /**< ip address in net order */ \
+ _(u16, port) /**< port in net order */ \
+ _(u8, is_ip4) /**< set if ip4 */ \
+ _(u32, sw_if_index) /**< interface endpoint is associated with */ \
+ _(u32, fib_index) /**< fib table endpoint is associated with */ \
+
+typedef struct transport_endpoint_
+{
+#define _(type, name) type name;
+ foreach_transport_endpoint_fields
+#undef _
+} transport_endpoint_t;
+
+#define foreach_transport_endpoint_cfg_fields \
+ foreach_transport_endpoint_fields \
+ _(transport_endpoint_t, peer) \
+
+typedef struct transport_endpoint_pair_
+{
+#define _(type, name) type name;
+ foreach_transport_endpoint_cfg_fields
+#undef _
+} transport_endpoint_cfg_t;
+
+typedef clib_bihash_24_8_t transport_endpoint_table_t;
+
+#define ENDPOINT_INVALID_INDEX ((u32)~0)
+
+always_inline u8
+transport_connection_fib_proto (transport_connection_t * tc)
+{
+ return tc->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+}
+
+always_inline u8
+transport_endpoint_fib_proto (transport_endpoint_t * tep)
+{
+ return tep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+}
+
+u8 transport_protocol_is_cl (transport_proto_t tp);
+transport_service_type_t transport_protocol_service_type (transport_proto_t);
+transport_tx_fn_type_t transport_protocol_tx_fn_type (transport_proto_t tp);
+
+#endif /* VNET_VNET_URI_TRANSPORT_TYPES_H_ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index 99b015ba3d8..5fdeec608c9 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -1173,13 +1173,13 @@ tcp_session_flush_data (transport_connection_t * tconn)
/* *INDENT-OFF* */
const static transport_proto_vft_t tcp_proto = {
.enable = vnet_tcp_enable_disable,
- .bind = tcp_session_bind,
- .unbind = tcp_session_unbind,
+ .start_listen = tcp_session_bind,
+ .stop_listen = tcp_session_unbind,
.push_header = tcp_session_push_header,
.get_connection = tcp_session_get_transport,
.get_listener = tcp_session_get_listener,
.get_half_open = tcp_half_open_session_get_transport,
- .open = tcp_session_open,
+ .connect = tcp_session_open,
.close = tcp_session_close,
.cleanup = tcp_session_cleanup,
.send_mss = tcp_session_send_mss,
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index 9032a97a7f9..96ffd2c7efe 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -14,7 +14,6 @@
*/
#include <vnet/tcp/tcp.h>
-#include <vnet/lisp-cp/packets.h>
#include <math.h>
vlib_node_registration_t tcp4_output_node;
@@ -477,7 +476,7 @@ tcp_reuse_buffer (vlib_main_t * vm, vlib_buffer_t * b)
vnet_buffer (b)->tcp.flags = 0;
/* Leave enough space for headers */
- return vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
+ return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
}
static void *
@@ -490,7 +489,7 @@ tcp_init_buffer (vlib_main_t * vm, vlib_buffer_t * b)
vnet_buffer (b)->tcp.flags = 0;
VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
/* Leave enough space for headers */
- return vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
+ return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
}
/**
@@ -1290,7 +1289,7 @@ tcp_prepare_segment (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
int n_bytes = 0;
u8 *data;
- seg_size = max_deq_bytes + MAX_HDRS_LEN;
+ seg_size = max_deq_bytes + TRANSPORT_MAX_HDRS_LEN;
/*
* Prepare options
@@ -1339,7 +1338,8 @@ tcp_prepare_segment (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
*b = vlib_get_buffer (vm, wrk->tx_buffers[--n_bufs]);
data = tcp_init_buffer (vm, *b);
n_bytes = stream_session_peek_bytes (&tc->connection, data, offset,
- bytes_per_buffer - MAX_HDRS_LEN);
+ bytes_per_buffer -
+ TRANSPORT_MAX_HDRS_LEN);
b[0]->current_length = n_bytes;
b[0]->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
b[0]->total_length_not_including_first_buffer = 0;
@@ -1710,9 +1710,10 @@ tcp_timer_persist_handler (u32 index)
tcp_validate_txf_size (tc, offset);
tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
- max_snd_bytes = clib_min (tc->snd_mss, tm->bytes_per_buffer - MAX_HDRS_LEN);
- n_bytes = stream_session_peek_bytes (&tc->connection, data, offset,
- max_snd_bytes);
+ max_snd_bytes =
+ clib_min (tc->snd_mss, tm->bytes_per_buffer - TRANSPORT_MAX_HDRS_LEN);
+ n_bytes =
+ stream_session_peek_bytes (&tc->connection, data, offset, max_snd_bytes);
b->current_length = n_bytes;
ASSERT (n_bytes != 0 && (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)
|| tc->snd_nxt == tc->snd_una_max
diff --git a/src/vnet/tls/tls.c b/src/vnet/tls/tls.c
index 3f21e6e3cb2..ed12378862d 100644
--- a/src/vnet/tls/tls.c
+++ b/src/vnet/tls/tls.c
@@ -739,12 +739,12 @@ format_tls_half_open (u8 * s, va_list * args)
/* *INDENT-OFF* */
const static transport_proto_vft_t tls_proto = {
- .open = tls_connect,
+ .connect = tls_connect,
.close = tls_disconnect,
- .bind = tls_start_listen,
+ .start_listen = tls_start_listen,
+ .stop_listen = tls_stop_listen,
.get_connection = tls_connection_get,
.get_listener = tls_listener_get,
- .unbind = tls_stop_listen,
.tx_type = TRANSPORT_TX_INTERNAL,
.service_type = TRANSPORT_SERVICE_APP,
.format_connection = format_tls_connection,
diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c
index 7674ef2e5d6..694cffa6f5f 100644
--- a/src/vnet/udp/udp.c
+++ b/src/vnet/udp/udp.c
@@ -318,9 +318,9 @@ udp_session_get_half_open (u32 conn_index)
/* *INDENT-OFF* */
const static transport_proto_vft_t udp_proto = {
- .bind = udp_session_bind,
- .open = udp_open_connection,
- .unbind = udp_session_unbind,
+ .start_listen = udp_session_bind,
+ .connect = udp_open_connection,
+ .stop_listen = udp_session_unbind,
.push_header = udp_push_header,
.get_connection = udp_session_get,
.get_listener = udp_session_get_listener,
@@ -362,9 +362,9 @@ udpc_connection_listen (u32 session_index, transport_endpoint_t * lcl)
/* *INDENT-OFF* */
const static transport_proto_vft_t udpc_proto = {
- .bind = udpc_connection_listen,
- .open = udpc_connection_open,
- .unbind = udp_session_unbind,
+ .start_listen = udpc_connection_listen,
+ .stop_listen = udp_session_unbind,
+ .connect = udpc_connection_open,
.push_header = udp_push_header,
.get_connection = udp_session_get,
.get_listener = udp_session_get_listener,