Line data Source code
1 : /*
2 : * Copyright (c) 2017-2019 Cisco and/or its affiliates.
3 : * Licensed under the Apache License, Version 2.0 (the "License");
4 : * you may not use this file except in compliance with the License.
5 : * You may obtain a copy of the License at:
6 : *
7 : * http://www.apache.org/licenses/LICENSE-2.0
8 : *
9 : * Unless required by applicable law or agreed to in writing, software
10 : * distributed under the License is distributed on an "AS IS" BASIS,
11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : * See the License for the specific language governing permissions and
13 : * limitations under the License.
14 : */
15 :
16 : #ifndef SRC_VNET_SESSION_TRANSPORT_H_
17 : #define SRC_VNET_SESSION_TRANSPORT_H_
18 :
19 : #include <vnet/vnet.h>
20 : #include <vnet/session/transport_types.h>
21 :
22 : #define TRANSPORT_PACER_MIN_MSS 1460
23 : #define TRANSPORT_PACER_MIN_BURST TRANSPORT_PACER_MIN_MSS
24 : #define TRANSPORT_PACER_MAX_BURST (43 * TRANSPORT_PACER_MIN_MSS)
25 : #define TRANSPORT_PACER_MAX_BURST_PKTS 43
26 : #define TRANSPORT_PACER_BURSTS_PER_RTT 20
27 : #define TRANSPORT_PACER_MIN_IDLE 100
28 : #define TRANSPORT_PACER_IDLE_FACTOR 0.05
29 :
30 : typedef struct _transport_options_t
31 : {
32 : char *name;
33 : char *short_name;
34 : transport_tx_fn_type_t tx_type;
35 : transport_service_type_t service_type;
36 : } transport_options_t;
37 :
38 : typedef enum transport_snd_flags_
39 : {
40 : TRANSPORT_SND_F_DESCHED = 1 << 0,
41 : TRANSPORT_SND_F_POSTPONE = 1 << 1,
42 : TRANSPORT_SND_N_FLAGS
43 : } __clib_packed transport_snd_flags_t;
44 :
45 : typedef struct transport_send_params_
46 : {
47 : union
48 : {
49 : /* Used to retrieve snd params from transports */
50 : struct
51 : {
52 : u32 snd_space;
53 : u32 tx_offset;
54 : u16 snd_mss;
55 : };
56 : /* Used by custom tx functions */
57 : struct
58 : {
59 : u32 max_burst_size;
60 : u32 bytes_dequeued;
61 : };
62 : };
63 : transport_snd_flags_t flags;
64 : } transport_send_params_t;
65 :
66 : /*
67 : * Transport protocol virtual function table
68 : */
69 : /* *INDENT-OFF* */
70 : typedef struct _transport_proto_vft
71 : {
72 : /*
73 : * Setup
74 : */
75 : u32 (*start_listen) (u32 session_index, transport_endpoint_cfg_t *lcl);
76 : u32 (*stop_listen) (u32 conn_index);
77 : int (*connect) (transport_endpoint_cfg_t * rmt);
78 : void (*half_close) (u32 conn_index, u32 thread_index);
79 : void (*close) (u32 conn_index, u32 thread_index);
80 : void (*reset) (u32 conn_index, u32 thread_index);
81 : void (*cleanup) (u32 conn_index, u32 thread_index);
82 : void (*cleanup_ho) (u32 conn_index);
83 : clib_error_t *(*enable) (vlib_main_t * vm, u8 is_en);
84 :
85 : /*
86 : * Transmission
87 : */
88 :
89 : u32 (*push_header) (transport_connection_t *tconn, vlib_buffer_t **b,
90 : u32 n_bufs);
91 : int (*send_params) (transport_connection_t * tconn,
92 : transport_send_params_t *sp);
93 : void (*update_time) (f64 time_now, u8 thread_index);
94 : void (*flush_data) (transport_connection_t *tconn);
95 : int (*custom_tx) (void *session, transport_send_params_t *sp);
96 : int (*app_rx_evt) (transport_connection_t *tconn);
97 :
98 : /*
99 : * Connection retrieval
100 : */
101 : transport_connection_t *(*get_connection) (u32 conn_idx, u32 thread_idx);
102 : transport_connection_t *(*get_listener) (u32 conn_index);
103 : transport_connection_t *(*get_half_open) (u32 conn_index);
104 :
105 : /*
106 : * Format
107 : */
108 : u8 *(*format_connection) (u8 * s, va_list * args);
109 : u8 *(*format_listener) (u8 * s, va_list * args);
110 : u8 *(*format_half_open) (u8 * s, va_list * args);
111 :
112 : /*
113 : * Properties retrieval/setting
114 : */
115 : void (*get_transport_endpoint) (u32 conn_index, u32 thread_index,
116 : transport_endpoint_t *tep, u8 is_lcl);
117 : void (*get_transport_listener_endpoint) (u32 conn_index,
118 : transport_endpoint_t *tep,
119 : u8 is_lcl);
120 : int (*attribute) (u32 conn_index, u32 thread_index, u8 is_get,
121 : transport_endpt_attr_t *attr);
122 :
123 : /*
124 : * Properties
125 : */
126 : transport_options_t transport_options;
127 : } transport_proto_vft_t;
128 : /* *INDENT-ON* */
129 :
130 : extern transport_proto_vft_t *tp_vfts;
131 :
132 : #define transport_proto_foreach(VAR, VAR_ALLOW_BM) \
133 : for (VAR = 0; VAR < vec_len (tp_vfts); VAR++) \
134 : if (tp_vfts[VAR].push_header != 0) \
135 : if (VAR_ALLOW_BM & (1 << VAR))
136 :
137 : int transport_connect (transport_proto_t tp, transport_endpoint_cfg_t * tep);
138 : void transport_half_close (transport_proto_t tp, u32 conn_index,
139 : u8 thread_index);
140 : void transport_close (transport_proto_t tp, u32 conn_index, u8 thread_index);
141 : void transport_reset (transport_proto_t tp, u32 conn_index, u8 thread_index);
142 : u32 transport_start_listen (transport_proto_t tp, u32 session_index,
143 : transport_endpoint_cfg_t *tep);
144 : u32 transport_stop_listen (transport_proto_t tp, u32 conn_index);
145 : void transport_cleanup (transport_proto_t tp, u32 conn_index,
146 : u8 thread_index);
147 : void transport_cleanup_half_open (transport_proto_t tp, u32 conn_index);
148 : void transport_get_endpoint (transport_proto_t tp, u32 conn_index,
149 : u32 thread_index, transport_endpoint_t * tep,
150 : u8 is_lcl);
151 : void transport_get_listener_endpoint (transport_proto_t tp, u32 conn_index,
152 : transport_endpoint_t * tep, u8 is_lcl);
153 : int transport_connection_attribute (transport_proto_t tp, u32 conn_index,
154 : u8 thread_index, u8 is_get,
155 : transport_endpt_attr_t *attr);
156 :
157 : static inline transport_connection_t *
158 7981727 : transport_get_connection (transport_proto_t tp, u32 conn_index,
159 : u8 thread_index)
160 : {
161 7981727 : return tp_vfts[tp].get_connection (conn_index, thread_index);
162 : }
163 :
164 : static inline transport_connection_t *
165 580 : transport_get_listener (transport_proto_t tp, u32 conn_index)
166 : {
167 580 : return tp_vfts[tp].get_listener (conn_index);
168 : }
169 :
170 : static inline transport_connection_t *
171 304 : transport_get_half_open (transport_proto_t tp, u32 conn_index)
172 : {
173 304 : return tp_vfts[tp].get_half_open (conn_index);
174 : }
175 :
176 : static inline int
177 1472660 : transport_custom_tx (transport_proto_t tp, void *s,
178 : transport_send_params_t * sp)
179 : {
180 1472660 : return tp_vfts[tp].custom_tx (s, sp);
181 : }
182 :
183 : static inline int
184 5604 : transport_app_rx_evt (transport_proto_t tp, u32 conn_index, u32 thread_index)
185 : {
186 : transport_connection_t *tc;
187 5604 : if (!tp_vfts[tp].app_rx_evt)
188 0 : return 0;
189 5604 : tc = transport_get_connection (tp, conn_index, thread_index);
190 5604 : return tp_vfts[tp].app_rx_evt (tc);
191 : }
192 :
193 : /**
194 : * Get send parameters for transport connection
195 : *
196 : * These include maximum tx burst, mss, tx offset and other flags
197 : * transport might want to provide to sessin layer
198 : *
199 : * @param tc transport connection
200 : * @param sp send paramaters
201 : *
202 : */
203 : static inline u32
204 101796 : transport_connection_snd_params (transport_connection_t * tc,
205 : transport_send_params_t * sp)
206 : {
207 101796 : return tp_vfts[tc->proto].send_params (tc, sp);
208 : }
209 :
210 : static inline u8
211 1221424 : transport_connection_is_descheduled (transport_connection_t * tc)
212 : {
213 1221424 : return ((tc->flags & TRANSPORT_CONNECTION_F_DESCHED) ? 1 : 0);
214 : }
215 :
216 : static inline void
217 63454 : transport_connection_deschedule (transport_connection_t * tc)
218 : {
219 63454 : tc->flags |= TRANSPORT_CONNECTION_F_DESCHED;
220 63454 : }
221 :
222 : static inline u8
223 59143 : transport_connection_is_cless (transport_connection_t * tc)
224 : {
225 59143 : return ((tc->flags & TRANSPORT_CONNECTION_F_CLESS) ? 1 : 0);
226 : }
227 :
228 : void transport_connection_reschedule (transport_connection_t * tc);
229 : void transport_fifos_init_ooo (transport_connection_t * tc);
230 :
231 : /**
232 : * Register transport virtual function table.
233 : *
234 : * @param transport_proto - transport protocol type (i.e., TCP, UDP ..)
235 : * @param vft - virtual function table for transport proto
236 : * @param fib_proto - network layer protocol
237 : * @param output_node - output node index that session layer will hand off
238 : * buffers to, for requested fib proto
239 : */
240 : void transport_register_protocol (transport_proto_t transport_proto,
241 : const transport_proto_vft_t * vft,
242 : fib_protocol_t fib_proto, u32 output_node);
243 : transport_proto_t
244 : transport_register_new_protocol (const transport_proto_vft_t * vft,
245 : fib_protocol_t fib_proto, u32 output_node);
246 : transport_proto_vft_t *transport_protocol_get_vft (transport_proto_t tp);
247 : void transport_update_time (clib_time_type_t time_now, u8 thread_index);
248 :
249 : int transport_alloc_local_port (u8 proto, ip46_address_t *ip,
250 : transport_endpoint_cfg_t *rmt);
251 : int transport_alloc_local_endpoint (u8 proto, transport_endpoint_cfg_t *rmt,
252 : ip46_address_t *lcl_addr, u16 *lcl_port);
253 : void transport_share_local_endpoint (u8 proto, ip46_address_t * lcl_ip,
254 : u16 port);
255 : int transport_release_local_endpoint (u8 proto, ip46_address_t *lcl_ip,
256 : u16 port);
257 : void transport_enable_disable (vlib_main_t * vm, u8 is_en);
258 : void transport_init (void);
259 :
260 : always_inline u32
261 0 : transport_elog_track_index (transport_connection_t * tc)
262 : {
263 : #if TRANSPORT_DEBUG
264 : return tc->elog_track.track_index_plus_one - 1;
265 : #else
266 0 : return ~0;
267 : #endif
268 : }
269 :
270 : void transport_connection_tx_pacer_reset (transport_connection_t * tc,
271 : u64 rate_bytes_per_sec,
272 : u32 initial_bucket,
273 : clib_us_time_t rtt);
274 : /**
275 : * Initialize tx pacer for connection
276 : *
277 : * @param tc transport connection
278 : * @param rate_bytes_per_second initial byte rate
279 : * @param burst_bytes initial burst size in bytes
280 : */
281 : void transport_connection_tx_pacer_init (transport_connection_t * tc,
282 : u64 rate_bytes_per_sec,
283 : u32 initial_bucket);
284 :
285 : /**
286 : * Update tx pacer pacing rate
287 : *
288 : * @param tc transport connection
289 : * @param bytes_per_sec new pacing rate
290 : * @param rtt connection rtt that is used to compute
291 : * inactivity time after which pacer bucket is
292 : * reset to 1 mtu
293 : */
294 : void transport_connection_tx_pacer_update (transport_connection_t * tc,
295 : u64 bytes_per_sec,
296 : clib_us_time_t rtt);
297 :
298 : /**
299 : * Get tx pacer max burst
300 : *
301 : * @param tc transport connection
302 : * @param time_now current cpu time
303 : * @return max burst for connection
304 : */
305 : u32 transport_connection_tx_pacer_burst (transport_connection_t * tc);
306 :
307 : /**
308 : * Get tx pacer current rate
309 : *
310 : * @param tc transport connection
311 : * @return rate for connection in bytes/s
312 : */
313 : u64 transport_connection_tx_pacer_rate (transport_connection_t * tc);
314 :
315 : /**
316 : * Reset tx pacer bucket
317 : *
318 : * @param tc transport connection
319 : * @param bucket value the bucket will be reset to
320 : */
321 : void transport_connection_tx_pacer_reset_bucket (transport_connection_t * tc,
322 : u32 bucket);
323 :
324 : /**
325 : * Check if transport connection is paced
326 : */
327 : always_inline u8
328 210616 : transport_connection_is_tx_paced (transport_connection_t * tc)
329 : {
330 210616 : return (tc->flags & TRANSPORT_CONNECTION_F_IS_TX_PACED);
331 : }
332 :
333 : /**
334 : * Clear descheduled flag and update pacer if needed
335 : *
336 : * To add session to scheduler use @ref transport_connection_reschedule
337 : */
338 : always_inline void
339 22214 : transport_connection_clear_descheduled (transport_connection_t *tc)
340 : {
341 22214 : tc->flags &= ~TRANSPORT_CONNECTION_F_DESCHED;
342 22214 : if (transport_connection_is_tx_paced (tc))
343 9446 : transport_connection_tx_pacer_reset_bucket (tc, 0 /* bucket */);
344 22214 : }
345 :
346 : u8 *format_transport_pacer (u8 * s, va_list * args);
347 :
348 : /**
349 : * Update tx bytes for paced transport connection
350 : *
351 : * If tx pacing is enabled, this update pacer bucket to account for the
352 : * amount of bytes that have been sent.
353 : *
354 : * @param tc transport connection
355 : * @param bytes bytes recently sent
356 : */
357 : void transport_connection_update_tx_bytes (transport_connection_t * tc,
358 : u32 bytes);
359 :
360 : void
361 : transport_connection_tx_pacer_update_bytes (transport_connection_t * tc,
362 : u32 bytes);
363 :
364 : /**
365 : * Request pacer time update
366 : *
367 : * @param thread_index thread for which time is updated
368 : * @param now time now
369 : */
370 : void transport_update_pacer_time (u32 thread_index, clib_time_type_t now);
371 :
372 : #endif /* SRC_VNET_SESSION_TRANSPORT_H_ */
373 :
374 : /*
375 : * fd.io coding-style-patch-verification: ON
376 : *
377 : * Local Variables:
378 : * eval: (c-set-style "gnu")
379 : * End:
380 : */
|