X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Ftransport.h;h=e5c09cd767d12c052d298a111b83abaafa1178df;hp=61a2b7b8aa61cd0fd04ca9d7eac5aeb365d06f46;hb=07063b8ea;hpb=561af9b441c7392cf391dd46399b0b16b876a08a diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h index 61a2b7b8aa6..e5c09cd767d 100644 --- a/src/vnet/session/transport.h +++ b/src/vnet/session/transport.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 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,120 +13,308 @@ * 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 -#include -#include +#include + +#define TRANSPORT_PACER_MIN_MSS 1460 +#define TRANSPORT_PACER_MIN_BURST TRANSPORT_PACER_MIN_MSS +#define TRANSPORT_PACER_MAX_BURST (43 * TRANSPORT_PACER_MIN_MSS) +#define TRANSPORT_PACER_MIN_IDLE 100 +#define TRANSPORT_PACER_IDLE_FACTOR 0.05 + +typedef struct _transport_options_t +{ + char *name; + char *short_name; + transport_tx_fn_type_t tx_type; + transport_service_type_t service_type; + u8 half_open_has_fifos; +} transport_options_t; + +typedef enum transport_snd_flags_ +{ + TRANSPORT_SND_F_DESCHED = 1 << 0, + TRANSPORT_SND_F_POSTPONE = 1 << 1, + TRANSPORT_SND_N_FLAGS +} __clib_packed transport_snd_flags_t; + +typedef struct transport_send_params_ +{ + u32 snd_space; + u32 tx_offset; + u16 snd_mss; + transport_snd_flags_t flags; +} transport_send_params_t; /* - * Protocol independent transport properties associated to a session + * Transport protocol virtual function table */ -typedef struct _transport_connection +/* *INDENT-OFF* */ +typedef struct _transport_proto_vft { - ip46_address_t rmt_ip; /**< Remote IP */ - ip46_address_t lcl_ip; /**< Local IP */ - u16 lcl_port; /**< Local port */ - u16 rmt_port; /**< Remote port */ - u8 proto; /**< Protocol id */ - u8 is_ip4; /**< Flag if IP4 connection */ - u32 fib_index; /**< Network namespace */ + /* + * 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 (*reset) (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); - u32 s_index; /**< Parent session index */ - u32 c_index; /**< Connection index in transport pool */ - u32 thread_index; /**< Worker-thread index */ + /* + * Transmission + */ - fib_node_index_t rmt_fei; /**< FIB entry index for rmt */ - dpo_id_t rmt_dpo; /**< Forwarding DPO for rmt */ + u32 (*push_header) (transport_connection_t * tconn, vlib_buffer_t * b); + int (*send_params) (transport_connection_t * tconn, + transport_send_params_t *sp); + void (*update_time) (f64 time_now, u8 thread_index); + void (*flush_data) (transport_connection_t *tconn); + int (*custom_tx) (void *session, u32 max_burst_size); + int (*app_rx_evt) (transport_connection_t *tconn); -#if TRANSPORT_DEBUG - elog_track_t elog_track; /**< Event logging */ - u32 cc_stat_tstamp; /**< CC stats timestamp */ -#endif + /* + * 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); - /** 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 -} transport_connection_t; - -typedef enum _transport_proto + /* + * 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 retrieval + */ + void (*get_transport_endpoint) (u32 conn_index, u32 thread_index, + transport_endpoint_t *tep, u8 is_lcl); + void (*get_transport_listener_endpoint) (u32 conn_index, + transport_endpoint_t *tep, + u8 is_lcl); + + /* + * Properties + */ + transport_options_t transport_options; +} 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); +void transport_reset (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); +void transport_get_endpoint (transport_proto_t tp, u32 conn_index, + u32 thread_index, transport_endpoint_t * tep, + u8 is_lcl); +void transport_get_listener_endpoint (transport_proto_t tp, u32 conn_index, + transport_endpoint_t * tep, u8 is_lcl); + +static inline transport_connection_t * +transport_get_connection (transport_proto_t tp, u32 conn_index, + u8 thread_index) { - TRANSPORT_PROTO_TCP, - TRANSPORT_PROTO_UDP, - 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); -uword unformat_transport_proto (unformat_input_t * input, va_list * args); - -#define foreach_transport_connection_fields \ - _(u32, sw_if_index) /**< interface endpoint is associated with */ \ - _(ip46_address_t, ip) /**< ip address */ \ - _(u32, fib_index) /**< fib table endpoint is associated with */ \ - _(u8, is_ip4) /**< 1 if ip4 */ \ - _(u16, port) /**< port in net order */ \ - -typedef struct _transport_endpoint + return tp_vfts[tp].get_connection (conn_index, thread_index); +} + +static inline transport_connection_t * +transport_get_listener (transport_proto_t tp, u32 conn_index) { -#define _(type, name) type name; - foreach_transport_connection_fields -#undef _ -} transport_endpoint_t; + return tp_vfts[tp].get_listener (conn_index); +} -typedef clib_bihash_24_8_t transport_endpoint_table_t; +static inline transport_connection_t * +transport_get_half_open (transport_proto_t tp, u32 conn_index) +{ + return tp_vfts[tp].get_half_open (conn_index); +} -#define ENDPOINT_INVALID_INDEX ((u32)~0) +static inline int +transport_custom_tx (transport_proto_t tp, void *s, u32 max_burst_size) +{ + return tp_vfts[tp].custom_tx (s, max_burst_size); +} -always_inline u8 -transport_connection_fib_proto (transport_connection_t * tc) +static inline int +transport_app_rx_evt (transport_proto_t tp, u32 conn_index, u32 thread_index) { - return tc->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; + transport_connection_t *tc; + if (!tp_vfts[tp].app_rx_evt) + return 0; + tc = transport_get_connection (tp, conn_index, thread_index); + return tp_vfts[tp].app_rx_evt (tc); } -always_inline u8 -transport_endpoint_fib_proto (transport_endpoint_t * tep) +/** + * Get send parameters for transport connection + * + * These include maximum tx burst, mss, tx offset and other flags + * transport might want to provide to sessin layer + * + * @param tc transport connection + * @param sp send paramaters + * + */ +static inline u32 +transport_connection_snd_params (transport_connection_t * tc, + transport_send_params_t * sp) { - return tep->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; + return tp_vfts[tc->proto].send_params (tc, sp); } -always_inline u8 -transport_is_stream (u8 proto) +static inline u8 +transport_connection_is_descheduled (transport_connection_t * tc) { - return (proto == TRANSPORT_PROTO_TCP); + return ((tc->flags & TRANSPORT_CONNECTION_F_DESCHED) ? 1 : 0); } -always_inline u8 -transport_is_dgram (u8 proto) +static inline void +transport_connection_deschedule (transport_connection_t * tc) { - return (proto == TRANSPORT_PROTO_UDP); + tc->flags |= TRANSPORT_CONNECTION_F_DESCHED; } +void transport_connection_reschedule (transport_connection_t * tc); + +/** + * Register transport virtual function table. + * + * @param transport_proto - transport protocol type (i.e., TCP, UDP ..) + * @param vft - virtual function table for transport proto + * @param fib_proto - network layer protocol + * @param output_node - output node index that session layer will hand off + * buffers to, for requested fib proto + */ +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_t +transport_register_new_protocol (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 (clib_time_type_t 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_t * rmt, +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); -#endif /* VNET_VNET_URI_TRANSPORT_H_ */ +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, + u64 rate_bytes_per_sec, + u32 initial_bucket, + clib_us_time_t rtt); +/** + * 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, + u64 rate_bytes_per_sec, + u32 initial_bucket); + +/** + * Update tx pacer pacing rate + * + * @param tc transport connection + * @param bytes_per_sec new pacing rate + * @param rtt connection rtt that is used to compute + * inactivity time after which pacer bucket is + * reset to 1 mtu + */ +void transport_connection_tx_pacer_update (transport_connection_t * tc, + u64 bytes_per_sec, + clib_us_time_t rtt); + +/** + * Get tx pacer max burst + * + * @param tc transport connection + * @param time_now current cpu time + * @return max burst for connection + */ +u32 transport_connection_tx_pacer_burst (transport_connection_t * tc); + +/** + * Get tx pacer current rate + * + * @param tc transport connection + * @return rate for connection in bytes/s + */ +u64 transport_connection_tx_pacer_rate (transport_connection_t * tc); + +/** + * Reset tx pacer bucket + * + * @param tc transport connection + * @param bucket value the bucket will be reset to + */ +void transport_connection_tx_pacer_reset_bucket (transport_connection_t * tc, + u32 bucket); + +/** + * 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 bytes for paced transport connection + * + * If tx pacing is enabled, this update pacer bucket to account for the + * amount of bytes that have been sent. + * + * @param tc transport connection + * @param bytes bytes recently sent + */ +void transport_connection_update_tx_bytes (transport_connection_t * tc, + u32 bytes); + +void +transport_connection_tx_pacer_update_bytes (transport_connection_t * tc, + u32 bytes); + +#endif /* SRC_VNET_SESSION_TRANSPORT_H_ */ /* * fd.io coding-style-patch-verification: ON