X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvnet%2Fsession%2Ftransport.h;h=adc695f5e5af84fe54b60171195aa6b7d7a11374;hb=282872127;hp=3895a60af489f1c23e3fd4b33a2adea7344e4667;hpb=04e5344a358a9ad42d896486d2d226149fd326f4;p=vpp.git diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h index 3895a60af48..adc695f5e5a 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,77 +13,260 @@ * 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 -#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 +{ + transport_tx_fn_type_t tx_type; + transport_service_type_t service_type; + u8 half_open_has_fifos; +} transport_options_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 (also session type) */ - u32 vrf; /**< FIB table id */ + /* + * 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); + + /* + * 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); + int (*custom_tx) (void *session, u32 max_burst_size); + int (*app_rx_evt) (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); - u32 s_index; /**< Parent session index */ - u32 c_index; /**< Connection index in transport pool */ - u8 is_ip4; /**< Flag if IP4 connection */ - u32 thread_index; /**< Worker-thread index */ + /* + * 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) +{ + 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) +{ + return tp_vfts[tp].get_listener (conn_index); +} + +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); +} + +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); +} + +static inline int +transport_app_rx_evt (transport_proto_t tp, u32 conn_index, u32 thread_index) +{ + 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); +} + +/** + * Get maximum tx burst allowed for transport connection + * + * @param tc transport connection + */ +static inline u32 +transport_connection_snd_space (transport_connection_t * tc) +{ + return tp_vfts[tc->proto].send_space (tc); +} - fib_node_index_t rmt_fei; /**< FIB entry index for rmt */ - dpo_id_t rmt_dpo; /**< Forwarding DPO for rmt */ +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 (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_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_vrf connection.vrf -#define c_state connection.state -#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 -{ - TRANSPORT_PROTO_TCP, - TRANSPORT_PROTO_UDP -} transport_proto_t; +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); -typedef struct _transport_endpoint +/** + * Check if transport connection is paced + */ +always_inline u8 +transport_connection_is_tx_paced (transport_connection_t * tc) { - ip46_address_t ip; /** ip address */ - u16 port; /** port in host order */ - u8 is_ip4; /** 1 if ip4 */ - u32 vrf; /** fib table the endpoint is associated with */ -} transport_endpoint_t; + 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 /* VNET_VNET_URI_TRANSPORT_H_ */ +#endif /* SRC_VNET_SESSION_TRANSPORT_H_ */ /* * fd.io coding-style-patch-verification: ON