FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
transport.c
Go to the documentation of this file.
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 #include <vnet/session/transport.h>
17 #include <vnet/session/session.h>
18 #include <vnet/fib/fib.h>
19 
20 /**
21  * Per-type vector of transport protocol virtual function tables
22  */
24 
25 /*
26  * Port allocator seed
27  */
29 
30 /*
31  * Local endpoints table
32  */
34 
35 /*
36  * Pool of local endpoints
37  */
39 
40 /*
41  * Local endpoints pool lock
42  */
44 
45 /*
46  * Period used by transport pacers. Initialized by session layer
47  */
48 static double transport_pacer_period;
49 
50 #define TRANSPORT_PACER_MIN_MSS 1460
51 #define TRANSPORT_PACER_MIN_BURST TRANSPORT_PACER_MIN_MSS
52 #define TRANSPORT_PACER_MAX_BURST (32 * TRANSPORT_PACER_MIN_MSS)
53 
54 u8 *
55 format_transport_proto (u8 * s, va_list * args)
56 {
57  u32 transport_proto = va_arg (*args, u32);
58  switch (transport_proto)
59  {
61  s = format (s, "TCP");
62  break;
64  s = format (s, "UDP");
65  break;
67  s = format (s, "SCTP");
68  break;
70  s = format (s, "UDPC");
71  break;
73  s = format (s, "QUIC");
74  break;
75  }
76  return s;
77 }
78 
79 u8 *
80 format_transport_proto_short (u8 * s, va_list * args)
81 {
82  u32 transport_proto = va_arg (*args, u32);
83  switch (transport_proto)
84  {
86  s = format (s, "T");
87  break;
89  s = format (s, "U");
90  break;
92  s = format (s, "S");
93  break;
95  s = format (s, "U");
96  break;
98  s = format (s, "Q");
99  break;
100  }
101  return s;
102 }
103 
104 u8 *
105 format_transport_connection (u8 * s, va_list * args)
106 {
107  u32 transport_proto = va_arg (*args, u32);
108  u32 conn_index = va_arg (*args, u32);
109  u32 thread_index = va_arg (*args, u32);
110  u32 verbose = va_arg (*args, u32);
111  transport_proto_vft_t *tp_vft;
113  u32 indent;
114 
115  tp_vft = transport_protocol_get_vft (transport_proto);
116  if (!tp_vft)
117  return s;
118 
119  s = format (s, "%U", tp_vft->format_connection, conn_index, thread_index,
120  verbose);
121  tc = tp_vft->get_connection (conn_index, thread_index);
122  if (tc && transport_connection_is_tx_paced (tc) && verbose > 1)
123  {
124  indent = format_get_indent (s) + 1;
125  s = format (s, "%Upacer: %U\n", format_white_space, indent,
126  format_transport_pacer, &tc->pacer);
127  }
128  return s;
129 }
130 
131 u8 *
133 {
134  u32 transport_proto = va_arg (*args, u32);
135  transport_proto_vft_t *tp_vft;
136 
137  tp_vft = transport_protocol_get_vft (transport_proto);
138  if (!tp_vft)
139  return s;
140 
141  s = (tp_vft->format_listener) (s, args);
142  return s;
143 }
144 
145 u8 *
147 {
148  u32 transport_proto = va_arg (*args, u32);
149  u32 listen_index = va_arg (*args, u32);
150  transport_proto_vft_t *tp_vft;
151 
152  tp_vft = transport_protocol_get_vft (transport_proto);
153  if (!tp_vft)
154  return s;
155 
156  s = format (s, "%U", tp_vft->format_half_open, listen_index);
157  return s;
158 }
159 
160 uword
162 {
163  u32 *proto = va_arg (*args, u32 *);
164  if (unformat (input, "tcp"))
165  *proto = TRANSPORT_PROTO_TCP;
166  else if (unformat (input, "TCP"))
167  *proto = TRANSPORT_PROTO_TCP;
168  else if (unformat (input, "udpc"))
169  *proto = TRANSPORT_PROTO_UDPC;
170  else if (unformat (input, "UDPC"))
171  *proto = TRANSPORT_PROTO_UDPC;
172  else if (unformat (input, "udp"))
173  *proto = TRANSPORT_PROTO_UDP;
174  else if (unformat (input, "UDP"))
175  *proto = TRANSPORT_PROTO_UDP;
176  else if (unformat (input, "sctp"))
177  *proto = TRANSPORT_PROTO_SCTP;
178  else if (unformat (input, "SCTP"))
179  *proto = TRANSPORT_PROTO_SCTP;
180  else if (unformat (input, "tls"))
181  *proto = TRANSPORT_PROTO_TLS;
182  else if (unformat (input, "TLS"))
183  *proto = TRANSPORT_PROTO_TLS;
184  else if (unformat (input, "quic"))
185  *proto = TRANSPORT_PROTO_QUIC;
186  else if (unformat (input, "QUIC"))
187  *proto = TRANSPORT_PROTO_QUIC;
188  else
189  return 0;
190  return 1;
191 }
192 
193 u32
195  ip46_address_t * ip, u16 port)
196 {
198  int rv;
199 
200  kv.key[0] = ip->as_u64[0];
201  kv.key[1] = ip->as_u64[1];
202  kv.key[2] = (u64) port << 8 | (u64) proto;
203 
204  rv = clib_bihash_search_inline_24_8 (ht, &kv);
205  if (rv == 0)
206  return kv.value;
207 
208  return ENDPOINT_INVALID_INDEX;
209 }
210 
211 void
213  transport_endpoint_t * te, u32 value)
214 {
216 
217  kv.key[0] = te->ip.as_u64[0];
218  kv.key[1] = te->ip.as_u64[1];
219  kv.key[2] = (u64) te->port << 8 | (u64) proto;
220  kv.value = value;
221 
222  clib_bihash_add_del_24_8 (ht, &kv, 1);
223 }
224 
225 void
228 {
230 
231  kv.key[0] = te->ip.as_u64[0];
232  kv.key[1] = te->ip.as_u64[1];
233  kv.key[2] = (u64) te->port << 8 | (u64) proto;
234 
235  clib_bihash_add_del_24_8 (ht, &kv, 0);
236 }
237 
238 /**
239  * Register transport virtual function table.
240  *
241  * @param transport_proto - transport protocol type (i.e., TCP, UDP ..)
242  * @param vft - virtual function table for transport proto
243  * @param fib_proto - network layer protocol
244  * @param output_node - output node index that session layer will hand off
245  * buffers to, for requested fib proto
246  */
247 void
249  const transport_proto_vft_t * vft,
250  fib_protocol_t fib_proto, u32 output_node)
251 {
252  u8 is_ip4 = fib_proto == FIB_PROTOCOL_IP4;
253 
254  vec_validate (tp_vfts, transport_proto);
255  tp_vfts[transport_proto] = *vft;
256 
257  session_register_transport (transport_proto, vft, is_ip4, output_node);
258 }
259 
260 /**
261  * Get transport virtual function table
262  *
263  * @param type - session type (not protocol type)
264  */
267 {
268  if (transport_proto >= vec_len (tp_vfts))
269  return 0;
270  return &tp_vfts[transport_proto];
271 }
272 
275 {
276  return tp_vfts[tp].service_type;
277 }
278 
281 {
282  return tp_vfts[tp].tx_type;
283 }
284 
285 void
286 transport_cleanup (transport_proto_t tp, u32 conn_index, u8 thread_index)
287 {
288  tp_vfts[tp].cleanup (conn_index, thread_index);
289 }
290 
291 int
293 {
294  return tp_vfts[tp].connect (tep);
295 }
296 
297 void
298 transport_close (transport_proto_t tp, u32 conn_index, u8 thread_index)
299 {
300  tp_vfts[tp].close (conn_index, thread_index);
301 }
302 
303 u32
305  transport_endpoint_t * tep)
306 {
307  return tp_vfts[tp].start_listen (session_index, tep);
308 }
309 
310 u32
312 {
313  return tp_vfts[tp].stop_listen (conn_index);
314 }
315 
316 u8
318 {
319  return (tp_vfts[tp].service_type == TRANSPORT_SERVICE_CL);
320 }
321 
322 #define PORT_MASK ((1 << 16)- 1)
323 
324 void
326 {
327  clib_spinlock_lock_if_init (&local_endpoints_lock);
328  pool_put_index (local_endpoints, tepi);
329  clib_spinlock_unlock_if_init (&local_endpoints_lock);
330 }
331 
334 {
336  pool_get_zero (local_endpoints, tep);
337  return tep;
338 }
339 
340 void
341 transport_endpoint_cleanup (u8 proto, ip46_address_t * lcl_ip, u16 port)
342 {
343  u32 tepi;
345 
346  /* Cleanup local endpoint if this was an active connect */
347  tepi = transport_endpoint_lookup (&local_endpoints_table, proto, lcl_ip,
348  clib_net_to_host_u16 (port));
349  if (tepi != ENDPOINT_INVALID_INDEX)
350  {
351  tep = pool_elt_at_index (local_endpoints, tepi);
353  transport_endpoint_del (tepi);
354  }
355 }
356 
357 static void
358 transport_endpoint_mark_used (u8 proto, ip46_address_t * ip, u16 port)
359 {
361  clib_spinlock_lock_if_init (&local_endpoints_lock);
362  tep = transport_endpoint_new ();
363  clib_memcpy_fast (&tep->ip, ip, sizeof (*ip));
364  tep->port = port;
366  tep - local_endpoints);
367  clib_spinlock_unlock_if_init (&local_endpoints_lock);
368 }
369 
370 /**
371  * Allocate local port and add if successful add entry to local endpoint
372  * table to mark the pair as used.
373  */
374 int
375 transport_alloc_local_port (u8 proto, ip46_address_t * ip)
376 {
377  u16 min = 1024, max = 65535; /* XXX configurable ? */
378  int tries, limit;
379  u32 tei;
380 
381  limit = max - min;
382 
383  /* Only support active opens from thread 0 */
384  ASSERT (vlib_get_thread_index () == 0);
385 
386  /* Search for first free slot */
387  for (tries = 0; tries < limit; tries++)
388  {
389  u16 port = 0;
390 
391  /* Find a port in the specified range */
392  while (1)
393  {
395  if (PREDICT_TRUE (port >= min && port < max))
396  break;
397  }
398 
399  /* Look it up. If not found, we're done */
401  port);
402  if (tei == ENDPOINT_INVALID_INDEX)
403  {
404  transport_endpoint_mark_used (proto, ip, port);
405  return port;
406  }
407  }
408  return -1;
409 }
410 
411 static clib_error_t *
412 transport_get_interface_ip (u32 sw_if_index, u8 is_ip4, ip46_address_t * addr)
413 {
414  if (is_ip4)
415  {
416  ip4_address_t *ip4;
417  ip4 = ip_interface_get_first_ip (sw_if_index, 1);
418  if (!ip4)
419  return clib_error_return (0, "no routable ip4 address on %U",
421  vnet_get_main (), sw_if_index);
422  addr->ip4.as_u32 = ip4->as_u32;
423  }
424  else
425  {
426  ip6_address_t *ip6;
427  ip6 = ip_interface_get_first_ip (sw_if_index, 0);
428  if (ip6 == 0)
429  return clib_error_return (0, "no routable ip6 addresses on %U",
431  vnet_get_main (), sw_if_index);
432  clib_memcpy_fast (&addr->ip6, ip6, sizeof (*ip6));
433  }
434  return 0;
435 }
436 
437 static clib_error_t *
439  transport_endpoint_t * rmt,
440  ip46_address_t * lcl_addr)
441 {
442  fib_node_index_t fei;
444 
445  if (sw_if_index == ENDPOINT_INVALID_INDEX)
446  {
447  /* Find a FIB path to the destination */
448  clib_memcpy_fast (&prefix.fp_addr, &rmt->ip, sizeof (rmt->ip));
449  prefix.fp_proto = rmt->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
450  prefix.fp_len = rmt->is_ip4 ? 32 : 128;
451 
452  ASSERT (rmt->fib_index != ENDPOINT_INVALID_INDEX);
453  fei = fib_table_lookup (rmt->fib_index, &prefix);
454 
455  /* Couldn't find route to destination. Bail out. */
456  if (fei == FIB_NODE_INDEX_INVALID)
457  return clib_error_return (0, "no route to %U", format_ip46_address,
458  &rmt->ip, (rmt->is_ip4 == 0) + 1);
459 
460  sw_if_index = fib_entry_get_resolving_interface (fei);
461  if (sw_if_index == ENDPOINT_INVALID_INDEX)
462  return clib_error_return (0, "no resolving interface for %U",
463  format_ip46_address, &rmt->ip,
464  (rmt->is_ip4 == 0) + 1);
465  }
466 
467  clib_memset (lcl_addr, 0, sizeof (*lcl_addr));
468  return transport_get_interface_ip (sw_if_index, rmt->is_ip4, lcl_addr);
469 }
470 
471 int
473  ip46_address_t * lcl_addr, u16 * lcl_port)
474 {
475  transport_endpoint_t *rmt = (transport_endpoint_t *) rmt_cfg;
476  clib_error_t *error;
477  int port;
478  u32 tei;
479 
480  /*
481  * Find the local address
482  */
483  if (ip_is_zero (&rmt_cfg->peer.ip, rmt_cfg->peer.is_ip4))
484  {
485  error = transport_find_local_ip_for_remote (rmt_cfg->peer.sw_if_index,
486  rmt, lcl_addr);
487  if (error)
488  {
489  clib_error_report (error);
490  return -1;
491  }
492  }
493  else
494  {
495  /* Assume session layer vetted this address */
496  clib_memcpy_fast (lcl_addr, &rmt_cfg->peer.ip,
497  sizeof (rmt_cfg->peer.ip));
498  }
499 
500  /*
501  * Allocate source port
502  */
503  if (rmt_cfg->peer.port == 0)
504  {
505  port = transport_alloc_local_port (proto, lcl_addr);
506  if (port < 1)
507  {
508  clib_warning ("Failed to allocate src port");
509  return -1;
510  }
511  *lcl_port = port;
512  }
513  else
514  {
515  port = clib_net_to_host_u16 (rmt_cfg->peer.port);
517  lcl_addr, port);
518  if (tei != ENDPOINT_INVALID_INDEX)
519  return -1;
520 
521  transport_endpoint_mark_used (proto, lcl_addr, port);
522  *lcl_port = port;
523  }
524 
525  return 0;
526 }
527 
528 #define SPACER_CPU_TICKS_PER_PERIOD_SHIFT 10
529 #define SPACER_CPU_TICKS_PER_PERIOD (1 << SPACER_CPU_TICKS_PER_PERIOD_SHIFT)
530 
531 u8 *
532 format_transport_pacer (u8 * s, va_list * args)
533 {
534  spacer_t *pacer = va_arg (*args, spacer_t *);
535 
536  s = format (s, "bucket %u max_burst %u tokens/period %.3f last_update %x",
537  pacer->bucket, pacer->max_burst_size, pacer->tokens_per_period,
538  pacer->last_update);
539  return s;
540 }
541 
542 static inline u32
543 spacer_max_burst (spacer_t * pacer, u64 norm_time_now)
544 {
545  u64 n_periods = norm_time_now - pacer->last_update;
546  u64 inc;
547 
548  if (n_periods > 0 && (inc = n_periods * pacer->tokens_per_period) > 10)
549  {
550  pacer->last_update = norm_time_now;
551  pacer->bucket += inc;
552  }
553 
554  return clib_min (pacer->bucket, TRANSPORT_PACER_MAX_BURST);
555 }
556 
557 static inline void
559 {
560  ASSERT (pacer->bucket >= bytes);
561  pacer->bucket -= bytes;
562 }
563 
564 static inline void
565 spacer_set_pace_rate (spacer_t * pacer, u64 rate_bytes_per_sec)
566 {
567  ASSERT (rate_bytes_per_sec != 0);
568  pacer->tokens_per_period = rate_bytes_per_sec / transport_pacer_period;
569 }
570 
571 void
573  u32 rate_bytes_per_sec,
574  u32 start_bucket, u64 time_now)
575 {
576  spacer_t *pacer = &tc->pacer;
577  spacer_set_pace_rate (&tc->pacer, rate_bytes_per_sec);
578  pacer->last_update = time_now >> SPACER_CPU_TICKS_PER_PERIOD_SHIFT;
579  pacer->bucket = start_bucket;
580 }
581 
582 void
584  u32 rate_bytes_per_sec,
585  u32 initial_bucket)
586 {
589  transport_connection_tx_pacer_reset (tc, rate_bytes_per_sec,
590  initial_bucket,
592 }
593 
594 void
596  u64 bytes_per_sec)
597 {
598  spacer_set_pace_rate (&tc->pacer, bytes_per_sec);
599 }
600 
601 u32
603  u64 time_now)
604 {
606  return spacer_max_burst (&tc->pacer, time_now);
607 }
608 
609 u32
611  u16 mss)
612 {
613  u32 snd_space, max_paced_burst;
614 
615  snd_space = tp_vfts[tc->proto].send_space (tc);
617  {
619  max_paced_burst = spacer_max_burst (&tc->pacer, time_now);
620  max_paced_burst = (max_paced_burst < mss) ? 0 : max_paced_burst;
621  snd_space = clib_min (snd_space, max_paced_burst);
622  snd_space = snd_space - snd_space % mss;
623  }
624  return snd_space;
625 }
626 
627 void
629 {
630  tc->stats.tx_bytes += bytes;
632  spacer_update_bucket (&tc->pacer, bytes);
633 }
634 
635 void
637  u32 bytes)
638 {
639  spacer_update_bucket (&tc->pacer, bytes);
640 }
641 
642 void
644 {
645  f64 cpu_freq = os_cpu_clock_frequency ();
647 }
648 
649 void
650 transport_update_time (f64 time_now, u8 thread_index)
651 {
653  vec_foreach (vft, tp_vfts)
654  {
655  if (vft->update_time)
656  (vft->update_time) (time_now, thread_index);
657  }
658 }
659 
660 void
662 {
664  vec_foreach (vft, tp_vfts)
665  {
666  if (vft->enable)
667  (vft->enable) (vm, is_en);
668  }
669 }
670 
671 void
673 {
676  u32 num_threads;
677 
678  if (smm->local_endpoints_table_buckets == 0)
679  smm->local_endpoints_table_buckets = 250000;
680  if (smm->local_endpoints_table_memory == 0)
681  smm->local_endpoints_table_memory = 512 << 20;
682 
683  /* Initialize [port-allocator] random number seed */
685 
686  clib_bihash_init_24_8 (&local_endpoints_table, "local endpoints table",
689  num_threads = 1 /* main thread */ + vtm->n_threads;
690  if (num_threads > 1)
691  clib_spinlock_init (&local_endpoints_lock);
692 }
693 
694 /*
695  * fd.io coding-style-patch-verification: ON
696  *
697  * Local Variables:
698  * eval: (c-set-style "gnu")
699  * End:
700  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
u32 sw_if_index
Definition: ipsec_gre.api:37
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
void transport_close(transport_proto_t tp, u32 conn_index, u8 thread_index)
Definition: transport.c:298
#define ENDPOINT_INVALID_INDEX
u8 * format_transport_connection(u8 *s, va_list *args)
Definition: transport.c:105
u32 transport_endpoint_lookup(transport_endpoint_table_t *ht, u8 proto, ip46_address_t *ip, u16 port)
Definition: transport.c:194
#define clib_min(x, y)
Definition: clib.h:295
u8 * format_transport_proto_short(u8 *s, va_list *args)
Definition: transport.c:80
static void transport_endpoint_mark_used(u8 proto, ip46_address_t *ip, u16 port)
Definition: transport.c:358
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:239
void transport_endpoint_table_add(transport_endpoint_table_t *ht, u8 proto, transport_endpoint_t *te, u32 value)
Definition: transport.c:212
#define PREDICT_TRUE(x)
Definition: clib.h:112
unsigned long u64
Definition: types.h:89
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static transport_endpoint_table_t local_endpoints_table
Definition: transport.c:33
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:98
static u64 clib_cpu_time_now(void)
Definition: time.h:75
format_function_t format_ip46_address
Definition: format.h:61
static u32 format_get_indent(u8 *s)
Definition: format.h:72
transport_tx_fn_type_t transport_protocol_tx_fn_type(transport_proto_t tp)
Definition: transport.c:280
void * ip_interface_get_first_ip(u32 sw_if_index, u8 is_ip4)
Definition: ip.c:134
u32 transport_start_listen(transport_proto_t tp, u32 session_index, transport_endpoint_t *tep)
Definition: transport.c:304
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
clib_time_t clib_time
Definition: main.h:72
u32 local_endpoints_table_memory
Transport table (preallocation) size parameters.
Definition: session.h:165
void transport_endpoint_del(u32 tepi)
Definition: transport.c:325
vhost_vring_addr_t addr
Definition: vhost_user.h:121
struct _spacer spacer_t
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u32 transport_connection_tx_pacer_burst(transport_connection_t *tc, u64 time_now)
Definition: transport.c:602
void transport_update_time(f64 time_now, u8 thread_index)
Definition: transport.c:650
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
double f64
Definition: types.h:142
#define TRANSPORT_CONNECTION_F_IS_TX_PACED
static clib_error_t * transport_get_interface_ip(u32 sw_if_index, u8 is_ip4, ip46_address_t *addr)
Definition: transport.c:412
#define always_inline
Definition: clib.h:98
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
Aggregrate type for a prefix.
Definition: fib_types.h:203
#define clib_error_return(e, args...)
Definition: error.h:99
int transport_alloc_local_endpoint(u8 proto, transport_endpoint_cfg_t *rmt_cfg, ip46_address_t *lcl_addr, u16 *lcl_port)
Definition: transport.c:472
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:207
static clib_spinlock_t local_endpoints_lock
Definition: transport.c:43
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
Definition: fib_table.c:66
void transport_connection_tx_pacer_init(transport_connection_t *tc, u32 rate_bytes_per_sec, u32 initial_bucket)
Initialize tx pacer for connection.
Definition: transport.c:583
struct _transport_proto_vft transport_proto_vft_t
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:57
transport_proto_vft_t * transport_protocol_get_vft(transport_proto_t transport_proto)
Get transport virtual function table.
Definition: transport.c:266
static void spacer_set_pace_rate(spacer_t *pacer, u64 rate_bytes_per_sec)
Definition: transport.c:565
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
void transport_endpoint_table_del(transport_endpoint_table_t *ht, u8 proto, transport_endpoint_t *te)
Definition: transport.c:226
#define SPACER_CPU_TICKS_PER_PERIOD
Definition: transport.c:529
transport_service_type_t transport_protocol_service_type(transport_proto_t tp)
Definition: transport.c:274
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
static transport_endpoint_t * local_endpoints
Definition: transport.c:38
enum transport_service_type_ transport_service_type_t
transport_proto_vft_t * tp_vfts
Per-type vector of transport protocol virtual function tables.
Definition: transport.c:23
static u8 transport_connection_is_tx_paced(transport_connection_t *tc)
Check if transport connection is paced.
Definition: transport.h:186
void transport_cleanup(transport_proto_t tp, u32 conn_index, u8 thread_index)
Definition: transport.c:286
u32 transport_stop_listen(transport_proto_t tp, u32 conn_index)
Definition: transport.c:311
void transport_connection_tx_pacer_update(transport_connection_t *tc, u64 bytes_per_sec)
Update tx pacer pacing rate.
Definition: transport.c:595
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1461
void transport_init(void)
Definition: transport.c:672
static double transport_pacer_period
Definition: transport.c:48
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:212
int transport_connect(transport_proto_t tp, transport_endpoint_cfg_t *tep)
Definition: transport.c:292
vlib_main_t * vm
Definition: buffer.c:312
#define clib_warning(format, args...)
Definition: error.h:59
#define PORT_MASK
Definition: transport.c:322
void transport_init_tx_pacers_period(void)
Initialize period for tx pacers.
Definition: transport.c:643
struct _transport_connection transport_connection_t
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
void transport_connection_update_tx_stats(transport_connection_t *tc, u32 bytes)
Update tx byte stats for transport connection.
Definition: transport.c:628
void transport_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: transport.c:661
void transport_endpoint_cleanup(u8 proto, ip46_address_t *lcl_ip, u16 port)
Definition: transport.c:341
void transport_register_protocol(transport_proto_t transport_proto, const transport_proto_vft_t *vft, fib_protocol_t fib_proto, u32 output_node)
Register transport virtual function table.
Definition: transport.c:248
#define SPACER_CPU_TICKS_PER_PERIOD_SHIFT
Definition: transport.c:528
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:311
#define ASSERT(truth)
u64 last_cpu_time
Definition: time.h:50
uword unformat_transport_proto(unformat_input_t *input, va_list *args)
Definition: transport.c:161
static transport_endpoint_t * transport_endpoint_new(void)
Definition: transport.c:333
u8 * format_transport_half_open_connection(u8 *s, va_list *args)
Definition: transport.c:146
enum _transport_proto transport_proto_t
#define clib_error_report(e)
Definition: error.h:113
u32 transport_connection_snd_space(transport_connection_t *tc, u64 time_now, u16 mss)
Get maximum tx burst allowed for transport connection.
Definition: transport.c:610
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
Definition: ip.c:20
void transport_connection_tx_pacer_update_bytes(transport_connection_t *tc, u32 bytes)
Definition: transport.c:636
static u32 port_allocator_seed
Definition: transport.c:28
void transport_connection_tx_pacer_reset(transport_connection_t *tc, u32 rate_bytes_per_sec, u32 start_bucket, u64 time_now)
Definition: transport.c:572
u32 local_endpoints_table_buckets
Definition: session.h:166
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void spacer_update_bucket(spacer_t *pacer, u32 bytes)
Definition: transport.c:558
u64 uword
Definition: types.h:112
static u32 spacer_max_burst(spacer_t *pacer, u64 norm_time_now)
Definition: transport.c:543
connectionless service
u8 * format_transport_listen_connection(u8 *s, va_list *args)
Definition: transport.c:132
u8 * format_transport_pacer(u8 *s, va_list *args)
Definition: transport.c:532
typedef prefix
Definition: ip_types.api:35
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define vec_foreach(var, vec)
Vector iterator.
static clib_error_t * transport_find_local_ip_for_remote(u32 sw_if_index, transport_endpoint_t *rmt, ip46_address_t *lcl_addr)
Definition: transport.c:438
clib_bihash_24_8_t transport_endpoint_table_t
static session_main_t * vnet_get_session_main()
Definition: session.h:493
#define TRANSPORT_PACER_MAX_BURST
Definition: transport.c:52
int transport_alloc_local_port(u8 proto, ip46_address_t *ip)
Allocate local port and add if successful add entry to local endpoint table to mark the pair as used...
Definition: transport.c:375
void session_register_transport(transport_proto_t transport_proto, const transport_proto_vft_t *vft, u8 is_ip4, u32 output_node)
Initialize session layer for given transport proto and ip version.
Definition: session.c:1254
enum transport_dequeue_type_ transport_tx_fn_type_t
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:82
u8 transport_protocol_is_cl(transport_proto_t tp)
Definition: transport.c:317
u8 * format_transport_proto(u8 *s, va_list *args)
Definition: transport.c:55
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
f64 os_cpu_clock_frequency(void)
Definition: time.c:143