FD.io VPP  v19.08.3-2-gbabecb413
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 u8 *
46 format_transport_proto (u8 * s, va_list * args)
47 {
48  u32 transport_proto = va_arg (*args, u32);
49  switch (transport_proto)
50  {
51 #define _(sym, str, sstr) \
52  case TRANSPORT_PROTO_ ## sym: \
53  s = format (s, str); \
54  break;
56 #undef _
57  default:
58  s = format (s, "UNKNOWN");
59  break;
60  }
61  return s;
62 }
63 
64 u8 *
65 format_transport_proto_short (u8 * s, va_list * args)
66 {
67  u32 transport_proto = va_arg (*args, u32);
68  switch (transport_proto)
69  {
70 #define _(sym, str, sstr) \
71  case TRANSPORT_PROTO_ ## sym: \
72  s = format (s, sstr); \
73  break;
75 #undef _
76  default:
77  s = format (s, "?");
78  break;
79  }
80  return s;
81 }
82 
83 u8 *
84 format_transport_connection (u8 * s, va_list * args)
85 {
86  u32 transport_proto = va_arg (*args, u32);
87  u32 conn_index = va_arg (*args, u32);
88  u32 thread_index = va_arg (*args, u32);
89  u32 verbose = va_arg (*args, u32);
90  transport_proto_vft_t *tp_vft;
92  u32 indent;
93 
94  tp_vft = transport_protocol_get_vft (transport_proto);
95  if (!tp_vft)
96  return s;
97 
98  s = format (s, "%U", tp_vft->format_connection, conn_index, thread_index,
99  verbose);
100  tc = tp_vft->get_connection (conn_index, thread_index);
101  if (tc && transport_connection_is_tx_paced (tc) && verbose > 1)
102  {
103  indent = format_get_indent (s) + 1;
104  s = format (s, "%Upacer: %U\n", format_white_space, indent,
105  format_transport_pacer, &tc->pacer, tc->thread_index);
106  }
107  return s;
108 }
109 
110 u8 *
112 {
113  u32 transport_proto = va_arg (*args, u32);
114  transport_proto_vft_t *tp_vft;
115 
116  tp_vft = transport_protocol_get_vft (transport_proto);
117  if (!tp_vft)
118  return s;
119 
120  s = (tp_vft->format_listener) (s, args);
121  return s;
122 }
123 
124 u8 *
126 {
127  u32 transport_proto = va_arg (*args, u32);
128  u32 listen_index = va_arg (*args, u32);
129  transport_proto_vft_t *tp_vft;
130 
131  tp_vft = transport_protocol_get_vft (transport_proto);
132  if (!tp_vft)
133  return s;
134 
135  s = format (s, "%U", tp_vft->format_half_open, listen_index);
136  return s;
137 }
138 
139 static u8
141 {
142  int i;
143 
144  if (strlen (str) > vec_len (input->buffer) - input->index)
145  return 0;
146 
147  for (i = 0; i < strlen (str); i++)
148  {
149  if (input->buffer[i + input->index] != str[i])
150  return 0;
151  }
152  return 1;
153 }
154 
155 uword
157 {
158  u32 *proto = va_arg (*args, u32 *);
159  u8 longest_match = 0, match;
160  char *str_match = 0;
161 
162 #define _(sym, str, sstr) \
163  if (unformat_transport_str_match (input, str)) \
164  { \
165  match = strlen (str); \
166  if (match > longest_match) \
167  { \
168  *proto = TRANSPORT_PROTO_ ## sym; \
169  longest_match = match; \
170  str_match = str; \
171  } \
172  }
174 #undef _
175  if (longest_match)
176  {
177  (void) unformat (input, str_match);
178  return 1;
179  }
180 
181  return 0;
182 }
183 
184 u32
186  ip46_address_t * ip, u16 port)
187 {
189  int rv;
190 
191  kv.key[0] = ip->as_u64[0];
192  kv.key[1] = ip->as_u64[1];
193  kv.key[2] = (u64) port << 8 | (u64) proto;
194 
195  rv = clib_bihash_search_inline_24_8 (ht, &kv);
196  if (rv == 0)
197  return kv.value;
198 
199  return ENDPOINT_INVALID_INDEX;
200 }
201 
202 void
205 {
207 
208  kv.key[0] = te->ip.as_u64[0];
209  kv.key[1] = te->ip.as_u64[1];
210  kv.key[2] = (u64) te->port << 8 | (u64) proto;
211  kv.value = value;
212 
213  clib_bihash_add_del_24_8 (ht, &kv, 1);
214 }
215 
216 void
219 {
221 
222  kv.key[0] = te->ip.as_u64[0];
223  kv.key[1] = te->ip.as_u64[1];
224  kv.key[2] = (u64) te->port << 8 | (u64) proto;
225 
226  clib_bihash_add_del_24_8 (ht, &kv, 0);
227 }
228 
229 /**
230  * Register transport virtual function table.
231  *
232  * @param transport_proto - transport protocol type (i.e., TCP, UDP ..)
233  * @param vft - virtual function table for transport proto
234  * @param fib_proto - network layer protocol
235  * @param output_node - output node index that session layer will hand off
236  * buffers to, for requested fib proto
237  */
238 void
240  const transport_proto_vft_t * vft,
241  fib_protocol_t fib_proto, u32 output_node)
242 {
243  u8 is_ip4 = fib_proto == FIB_PROTOCOL_IP4;
244 
245  vec_validate (tp_vfts, transport_proto);
246  tp_vfts[transport_proto] = *vft;
247 
248  session_register_transport (transport_proto, vft, is_ip4, output_node);
249 }
250 
251 /**
252  * Get transport virtual function table
253  *
254  * @param type - session type (not protocol type)
255  */
258 {
259  if (transport_proto >= vec_len (tp_vfts))
260  return 0;
261  return &tp_vfts[transport_proto];
262 }
263 
264 u8
266 {
267  return tp_vfts[tp].transport_options.half_open_has_fifos;
268 }
269 
272 {
273  return tp_vfts[tp].transport_options.service_type;
274 }
275 
278 {
279  return tp_vfts[tp].transport_options.tx_type;
280 }
281 
282 void
283 transport_cleanup (transport_proto_t tp, u32 conn_index, u8 thread_index)
284 {
285  tp_vfts[tp].cleanup (conn_index, thread_index);
286 }
287 
288 int
290 {
291  return tp_vfts[tp].connect (tep);
292 }
293 
294 void
295 transport_close (transport_proto_t tp, u32 conn_index, u8 thread_index)
296 {
297  tp_vfts[tp].close (conn_index, thread_index);
298 }
299 
300 void
301 transport_reset (transport_proto_t tp, u32 conn_index, u8 thread_index)
302 {
303  if (tp_vfts[tp].reset)
304  tp_vfts[tp].reset (conn_index, thread_index);
305  else
306  tp_vfts[tp].close (conn_index, thread_index);
307 }
308 
309 u32
311  transport_endpoint_t * tep)
312 {
313  return tp_vfts[tp].start_listen (session_index, tep);
314 }
315 
316 u32
318 {
319  return tp_vfts[tp].stop_listen (conn_index);
320 }
321 
322 u8
324 {
325  return (tp_vfts[tp].transport_options.service_type == TRANSPORT_SERVICE_CL);
326 }
327 
328 always_inline void
330  transport_endpoint_t * tep, u8 is_lcl)
331 {
332  if (is_lcl)
333  {
334  tep->port = tc->lcl_port;
335  tep->is_ip4 = tc->is_ip4;
336  clib_memcpy_fast (&tep->ip, &tc->lcl_ip, sizeof (tc->lcl_ip));
337  }
338  else
339  {
340  tep->port = tc->rmt_port;
341  tep->is_ip4 = tc->is_ip4;
342  clib_memcpy_fast (&tep->ip, &tc->rmt_ip, sizeof (tc->rmt_ip));
343  }
344 }
345 
346 void
348  u32 thread_index, transport_endpoint_t * tep,
349  u8 is_lcl)
350 {
351  if (tp_vfts[tp].get_transport_endpoint)
352  tp_vfts[tp].get_transport_endpoint (conn_index, thread_index, tep,
353  is_lcl);
354  else
355  {
357  tc = transport_get_connection (tp, conn_index, thread_index);
358  default_get_transport_endpoint (tc, tep, is_lcl);
359  }
360 }
361 
362 void
364  transport_endpoint_t * tep, u8 is_lcl)
365 {
366  if (tp_vfts[tp].get_transport_listener_endpoint)
367  tp_vfts[tp].get_transport_listener_endpoint (conn_index, tep, is_lcl);
368  else
369  {
371  tc = transport_get_listener (tp, conn_index);
372  default_get_transport_endpoint (tc, tep, is_lcl);
373  }
374 }
375 
376 #define PORT_MASK ((1 << 16)- 1)
377 
378 void
380 {
381  clib_spinlock_lock_if_init (&local_endpoints_lock);
382  pool_put_index (local_endpoints, tepi);
383  clib_spinlock_unlock_if_init (&local_endpoints_lock);
384 }
385 
388 {
390  pool_get_zero (local_endpoints, tep);
391  return tep;
392 }
393 
394 void
395 transport_endpoint_cleanup (u8 proto, ip46_address_t * lcl_ip, u16 port)
396 {
397  u32 tepi;
399 
400  /* Cleanup local endpoint if this was an active connect */
401  tepi = transport_endpoint_lookup (&local_endpoints_table, proto, lcl_ip,
402  clib_net_to_host_u16 (port));
403  if (tepi != ENDPOINT_INVALID_INDEX)
404  {
405  tep = pool_elt_at_index (local_endpoints, tepi);
407  transport_endpoint_del (tepi);
408  }
409 }
410 
411 static void
413 {
415  clib_spinlock_lock_if_init (&local_endpoints_lock);
416  tep = transport_endpoint_new ();
417  clib_memcpy_fast (&tep->ip, ip, sizeof (*ip));
418  tep->port = port;
420  tep - local_endpoints);
421  clib_spinlock_unlock_if_init (&local_endpoints_lock);
422 }
423 
424 /**
425  * Allocate local port and add if successful add entry to local endpoint
426  * table to mark the pair as used.
427  */
428 int
430 {
431  u16 min = 1024, max = 65535; /* XXX configurable ? */
432  int tries, limit;
433  u32 tei;
434 
435  limit = max - min;
436 
437  /* Only support active opens from thread 0 */
438  ASSERT (vlib_get_thread_index () == 0);
439 
440  /* Search for first free slot */
441  for (tries = 0; tries < limit; tries++)
442  {
443  u16 port = 0;
444 
445  /* Find a port in the specified range */
446  while (1)
447  {
449  if (PREDICT_TRUE (port >= min && port < max))
450  break;
451  }
452 
453  /* Look it up. If not found, we're done */
455  port);
456  if (tei == ENDPOINT_INVALID_INDEX)
457  {
458  transport_endpoint_mark_used (proto, ip, port);
459  return port;
460  }
461  }
462  return -1;
463 }
464 
465 static clib_error_t *
466 transport_get_interface_ip (u32 sw_if_index, u8 is_ip4, ip46_address_t * addr)
467 {
468  if (is_ip4)
469  {
470  ip4_address_t *ip4;
471  ip4 = ip_interface_get_first_ip (sw_if_index, 1);
472  if (!ip4)
473  return clib_error_return (0, "no routable ip4 address on %U",
475  vnet_get_main (), sw_if_index);
476  addr->ip4.as_u32 = ip4->as_u32;
477  }
478  else
479  {
480  ip6_address_t *ip6;
481  ip6 = ip_interface_get_first_ip (sw_if_index, 0);
482  if (ip6 == 0)
483  return clib_error_return (0, "no routable ip6 addresses on %U",
485  vnet_get_main (), sw_if_index);
486  clib_memcpy_fast (&addr->ip6, ip6, sizeof (*ip6));
487  }
488  return 0;
489 }
490 
491 static clib_error_t *
493  transport_endpoint_t * rmt,
494  ip46_address_t * lcl_addr)
495 {
496  fib_node_index_t fei;
498 
499  if (sw_if_index == ENDPOINT_INVALID_INDEX)
500  {
501  /* Find a FIB path to the destination */
502  clib_memcpy_fast (&prefix.fp_addr, &rmt->ip, sizeof (rmt->ip));
503  prefix.fp_proto = rmt->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
504  prefix.fp_len = rmt->is_ip4 ? 32 : 128;
505 
506  ASSERT (rmt->fib_index != ENDPOINT_INVALID_INDEX);
507  fei = fib_table_lookup (rmt->fib_index, &prefix);
508 
509  /* Couldn't find route to destination. Bail out. */
510  if (fei == FIB_NODE_INDEX_INVALID)
511  return clib_error_return (0, "no route to %U", format_ip46_address,
512  &rmt->ip, (rmt->is_ip4 == 0) + 1);
513 
514  sw_if_index = fib_entry_get_resolving_interface (fei);
515  if (sw_if_index == ENDPOINT_INVALID_INDEX)
516  return clib_error_return (0, "no resolving interface for %U",
517  format_ip46_address, &rmt->ip,
518  (rmt->is_ip4 == 0) + 1);
519  }
520 
521  clib_memset (lcl_addr, 0, sizeof (*lcl_addr));
522  return transport_get_interface_ip (sw_if_index, rmt->is_ip4, lcl_addr);
523 }
524 
525 int
527  ip46_address_t * lcl_addr, u16 * lcl_port)
528 {
529  transport_endpoint_t *rmt = (transport_endpoint_t *) rmt_cfg;
530  clib_error_t *error;
531  int port;
532  u32 tei;
533 
534  /*
535  * Find the local address
536  */
537  if (ip_is_zero (&rmt_cfg->peer.ip, rmt_cfg->peer.is_ip4))
538  {
539  error = transport_find_local_ip_for_remote (rmt_cfg->peer.sw_if_index,
540  rmt, lcl_addr);
541  if (error)
542  {
543  clib_error_report (error);
544  return -1;
545  }
546  }
547  else
548  {
549  /* Assume session layer vetted this address */
550  clib_memcpy_fast (lcl_addr, &rmt_cfg->peer.ip,
551  sizeof (rmt_cfg->peer.ip));
552  }
553 
554  /*
555  * Allocate source port
556  */
557  if (rmt_cfg->peer.port == 0)
558  {
559  port = transport_alloc_local_port (proto, lcl_addr);
560  if (port < 1)
561  {
562  clib_warning ("Failed to allocate src port");
563  return -1;
564  }
565  *lcl_port = port;
566  }
567  else
568  {
569  port = clib_net_to_host_u16 (rmt_cfg->peer.port);
571  lcl_addr, port);
572  if (tei != ENDPOINT_INVALID_INDEX)
573  return -1;
574 
575  transport_endpoint_mark_used (proto, lcl_addr, port);
576  *lcl_port = port;
577  }
578 
579  return 0;
580 }
581 
582 u8 *
583 format_clib_us_time (u8 * s, va_list * args)
584 {
585  clib_us_time_t t = va_arg (*args, clib_us_time_t);
586  if (t < 1e3)
587  s = format (s, "%u us", t);
588  else
589  s = format (s, "%.3f s", (f64) t * CLIB_US_TIME_PERIOD);
590  return s;
591 }
592 
593 u8 *
594 format_transport_pacer (u8 * s, va_list * args)
595 {
596  spacer_t *pacer = va_arg (*args, spacer_t *);
597  u32 thread_index = va_arg (*args, int);
598  clib_us_time_t now, diff;
599 
600  now = transport_us_time_now (thread_index);
601  diff = now - pacer->last_update;
602  s = format (s, "rate %lu bucket %lu t/p %.3f last_update %U",
603  pacer->bytes_per_sec, pacer->bucket, pacer->tokens_per_period,
604  format_clib_us_time, diff);
605  return s;
606 }
607 
608 static inline u32
610 {
611  u64 n_periods = (time_now - pacer->last_update);
612  u64 inc;
613 
614  if (PREDICT_FALSE (n_periods > 5e4))
615  {
616  pacer->last_update = time_now;
617  pacer->bucket = TRANSPORT_PACER_MIN_BURST;
619  }
620 
621  if (n_periods > 0
622  && (inc = (f32) n_periods * pacer->tokens_per_period) > 10)
623  {
624  pacer->last_update = time_now;
625  pacer->bucket = clib_min (pacer->bucket + inc, pacer->bytes_per_sec);
626  }
627 
628  return clib_min (pacer->bucket, TRANSPORT_PACER_MAX_BURST);
629 }
630 
631 static inline void
633 {
634  ASSERT (pacer->bucket >= bytes);
635  pacer->bucket -= bytes;
636 }
637 
638 static inline void
639 spacer_set_pace_rate (spacer_t * pacer, u64 rate_bytes_per_sec)
640 {
641  ASSERT (rate_bytes_per_sec != 0);
642  pacer->bytes_per_sec = rate_bytes_per_sec;
643  pacer->tokens_per_period = rate_bytes_per_sec * CLIB_US_TIME_PERIOD;
644 }
645 
646 static inline u64
648 {
649  return pacer->bytes_per_sec;
650 }
651 
652 static inline void
653 spacer_reset (spacer_t * pacer, clib_us_time_t time_now, u64 bucket)
654 {
655  pacer->last_update = time_now;
656  pacer->bucket = bucket;
657 }
658 
659 void
661  u64 rate_bytes_per_sec, u32 start_bucket)
662 {
663  spacer_set_pace_rate (&tc->pacer, rate_bytes_per_sec);
664  spacer_reset (&tc->pacer, transport_us_time_now (tc->thread_index),
665  start_bucket);
666 }
667 
668 void
670 {
671  spacer_reset (&tc->pacer, transport_us_time_now (tc->thread_index), 0);
672 }
673 
674 void
676  u64 rate_bytes_per_sec,
677  u32 initial_bucket)
678 {
680  transport_connection_tx_pacer_reset (tc, rate_bytes_per_sec,
681  initial_bucket);
682 }
683 
684 void
686  u64 bytes_per_sec)
687 {
688  spacer_set_pace_rate (&tc->pacer, bytes_per_sec);
689 }
690 
691 u32
693 {
694  return spacer_max_burst (&tc->pacer,
695  transport_us_time_now (tc->thread_index));
696 }
697 
698 u32
700 {
701  u32 snd_space, max_paced_burst;
702 
703  snd_space = tp_vfts[tc->proto].send_space (tc);
704  if (snd_space && transport_connection_is_tx_paced (tc))
705  {
706  clib_us_time_t now = transport_us_time_now (tc->thread_index);
707  max_paced_burst = spacer_max_burst (&tc->pacer, now);
708  max_paced_burst =
709  (max_paced_burst < TRANSPORT_PACER_MIN_BURST) ? 0 : max_paced_burst;
710  snd_space = clib_min (snd_space, max_paced_burst);
711  return snd_space >= mss ? snd_space - snd_space % mss : snd_space;
712  }
713  return snd_space;
714 }
715 
716 u64
718 {
719  return spacer_pace_rate (&tc->pacer);
720 }
721 
722 void
724 {
726  spacer_update_bucket (&tc->pacer, bytes);
727 }
728 
729 void
731  u32 bytes)
732 {
733  spacer_update_bucket (&tc->pacer, bytes);
734 }
735 
736 void
737 transport_update_time (clib_time_type_t time_now, u8 thread_index)
738 {
740  vec_foreach (vft, tp_vfts)
741  {
742  if (vft->update_time)
743  (vft->update_time) (time_now, thread_index);
744  }
745 }
746 
747 void
749 {
751  vec_foreach (vft, tp_vfts)
752  {
753  if (vft->enable)
754  (vft->enable) (vm, is_en);
755  }
756 }
757 
758 void
760 {
763  u32 num_threads;
764 
765  if (smm->local_endpoints_table_buckets == 0)
766  smm->local_endpoints_table_buckets = 250000;
767  if (smm->local_endpoints_table_memory == 0)
768  smm->local_endpoints_table_memory = 512 << 20;
769 
770  /* Initialize [port-allocator] random number seed */
772 
773  clib_bihash_init_24_8 (&local_endpoints_table, "local endpoints table",
776  num_threads = 1 /* main thread */ + vtm->n_threads;
777  if (num_threads > 1)
778  clib_spinlock_init (&local_endpoints_lock);
779 }
780 
781 /*
782  * fd.io coding-style-patch-verification: ON
783  *
784  * Local Variables:
785  * eval: (c-set-style "gnu")
786  * End:
787  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
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:295
#define ENDPOINT_INVALID_INDEX
u8 * format_transport_connection(u8 *s, va_list *args)
Definition: transport.c:84
u32 transport_endpoint_lookup(transport_endpoint_table_t *ht, u8 proto, ip46_address_t *ip, u16 port)
Definition: transport.c:185
#define clib_min(x, y)
Definition: clib.h:302
f64 clib_time_type_t
Definition: time.h:203
u8 * format_transport_proto_short(u8 *s, va_list *args)
Definition: transport.c:65
void transport_get_listener_endpoint(transport_proto_t tp, u32 conn_index, transport_endpoint_t *tep, u8 is_lcl)
Definition: transport.c:363
static void transport_endpoint_mark_used(u8 proto, ip46_address_t *ip, u16 port)
Definition: transport.c:412
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#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:203
#define PREDICT_TRUE(x)
Definition: clib.h:113
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:110
static u64 clib_cpu_time_now(void)
Definition: time.h:81
static void spacer_reset(spacer_t *pacer, clib_us_time_t time_now, u64 bucket)
Definition: transport.c:653
int i
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:277
void * ip_interface_get_first_ip(u32 sw_if_index, u8 is_ip4)
Definition: ip.c:140
u32 transport_start_listen(transport_proto_t tp, u32 session_index, transport_endpoint_t *tep)
Definition: transport.c:310
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
vl_api_mprefix_t prefix
Definition: ip.api:456
u32 local_endpoints_table_memory
Transport table (preallocation) size parameters.
Definition: session.h:192
void transport_endpoint_del(u32 tepi)
Definition: transport.c:379
vhost_vring_addr_t addr
Definition: vhost_user.h:147
struct _spacer spacer_t
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
double f64
Definition: types.h:142
void transport_update_time(clib_time_type_t time_now, u8 thread_index)
Definition: transport.c:737
#define foreach_transport_proto
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
u8 transport_half_open_has_fifos(transport_proto_t tp)
Definition: transport.c:265
static clib_error_t * transport_get_interface_ip(u32 sw_if_index, u8 is_ip4, ip46_address_t *addr)
Definition: transport.c:466
#define always_inline
Definition: clib.h:99
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
Aggregate 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:526
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
void transport_reset(transport_proto_t tp, u32 conn_index, u8 thread_index)
Definition: transport.c:301
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
struct _transport_proto_vft transport_proto_vft_t
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:63
transport_proto_vft_t * transport_protocol_get_vft(transport_proto_t transport_proto)
Get transport virtual function table.
Definition: transport.c:257
static void spacer_set_pace_rate(spacer_t *pacer, u64 rate_bytes_per_sec)
Definition: transport.c:639
#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:217
transport_service_type_t transport_protocol_service_type(transport_proto_t tp)
Definition: transport.c:271
void transport_get_endpoint(transport_proto_t tp, u32 conn_index, u32 thread_index, transport_endpoint_t *tep, u8 is_lcl)
Definition: transport.c:347
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
void transport_connection_tx_pacer_init(transport_connection_t *tc, u64 rate_bytes_per_sec, u32 initial_bucket)
Initialize tx pacer for connection.
Definition: transport.c:675
enum transport_service_type_ transport_service_type_t
#define PREDICT_FALSE(x)
Definition: clib.h:112
u16 port
Definition: punt.api:40
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:236
void transport_cleanup(transport_proto_t tp, u32 conn_index, u8 thread_index)
Definition: transport.c:283
u32 transport_stop_listen(transport_proto_t tp, u32 conn_index)
Definition: transport.c:317
u8 * format_clib_us_time(u8 *s, va_list *args)
Definition: transport.c:583
void transport_connection_tx_pacer_update(transport_connection_t *tc, u64 bytes_per_sec)
Update tx pacer pacing rate.
Definition: transport.c:685
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1466
void transport_init(void)
Definition: transport.c:759
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:218
int transport_connect(transport_proto_t tp, transport_endpoint_cfg_t *tep)
Definition: transport.c:289
vlib_main_t * vm
Definition: buffer.c:323
static transport_connection_t * transport_get_connection(transport_proto_t tp, u32 conn_index, u8 thread_index)
Definition: transport.h:117
#define clib_warning(format, args...)
Definition: error.h:59
#define PORT_MASK
Definition: transport.c:376
static void default_get_transport_endpoint(transport_connection_t *tc, transport_endpoint_t *tep, u8 is_lcl)
Definition: transport.c:329
struct _transport_connection transport_connection_t
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
void transport_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: transport.c:748
void transport_endpoint_cleanup(u8 proto, ip46_address_t *lcl_ip, u16 port)
Definition: transport.c:395
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:239
static clib_us_time_t transport_us_time_now(u32 thread_index)
Definition: session.h:519
static u64 spacer_pace_rate(spacer_t *pacer)
Definition: transport.c:647
#define CLIB_US_TIME_PERIOD
Definition: time.h:206
u8 value
Definition: qos.api:53
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:311
#define ASSERT(truth)
uword unformat_transport_proto(unformat_input_t *input, va_list *args)
Definition: transport.c:156
#define TRANSPORT_PACER_MAX_BURST
Definition: transport.h:24
void transport_connection_update_tx_bytes(transport_connection_t *tc, u32 bytes)
Update tx bytes for paced transport connection.
Definition: transport.c:723
static transport_endpoint_t * transport_endpoint_new(void)
Definition: transport.c:387
#define TRANSPORT_PACER_MIN_BURST
Definition: transport.h:23
u8 * format_transport_half_open_connection(u8 *s, va_list *args)
Definition: transport.c:125
enum _transport_proto transport_proto_t
#define clib_error_report(e)
Definition: error.h:113
float f32
Definition: types.h:143
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:730
static u32 port_allocator_seed
Definition: transport.c:28
u32 local_endpoints_table_buckets
Definition: session.h:193
vl_api_address_t ip
Definition: l2.api:489
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
static u32 spacer_max_burst(spacer_t *pacer, clib_us_time_t time_now)
Definition: transport.c:609
#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:632
u64 uword
Definition: types.h:112
connectionless service
u8 * format_transport_listen_connection(u8 *s, va_list *args)
Definition: transport.c:111
u8 * format_transport_pacer(u8 *s, va_list *args)
Definition: transport.c:594
void transport_connection_tx_pacer_reset_bucket(transport_connection_t *tc)
Reset tx pacer bucket.
Definition: transport.c:669
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.
u32 transport_connection_snd_space(transport_connection_t *tc, u16 mss)
Get maximum tx burst allowed for transport connection.
Definition: transport.c:699
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:492
clib_bihash_24_8_t transport_endpoint_table_t
static session_main_t * vnet_get_session_main()
Definition: session.h:587
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:429
static transport_connection_t * transport_get_listener(transport_proto_t tp, u32 conn_index)
Definition: transport.h:124
u64 clib_us_time_t
Definition: time.h:204
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:1438
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:95
u8 transport_protocol_is_cl(transport_proto_t tp)
Definition: transport.c:323
u8 * format_transport_proto(u8 *s, va_list *args)
Definition: transport.c:46
void transport_connection_tx_pacer_reset(transport_connection_t *tc, u64 rate_bytes_per_sec, u32 start_bucket)
Definition: transport.c:660
u32 transport_connection_tx_pacer_burst(transport_connection_t *tc)
Get tx pacer max burst.
Definition: transport.c:692
u64 transport_connection_tx_pacer_rate(transport_connection_t *tc)
Get tx pacer current rate.
Definition: transport.c:717
static u8 unformat_transport_str_match(unformat_input_t *input, const char *str)
Definition: transport.c:140
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
vl_api_fib_path_nh_proto_t proto
Definition: fib_types.api:125