diff options
Diffstat (limited to 'src/vnet/session/transport.h')
-rw-r--r-- | src/vnet/session/transport.h | 318 |
1 files changed, 164 insertions, 154 deletions
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 |