FD.io VPP  v21.01.1
Vector Packet Processing
udp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2020 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/udp/udp.h>
17 #include <vnet/session/session.h>
18 #include <vnet/dpo/load_balance.h>
19 #include <vnet/ip/ip4_inlines.h>
20 #include <vnet/ip/ip6_inlines.h>
21 #include <vppinfra/sparse_vec.h>
22 
24 
25 static void
27 {
28  udp_main_t *um = &udp_main;
30  u16 *n;
31 
32  pi = udp_get_dst_port_info (um, lcl_port, is_ip4);
33  if (!pi)
34  {
35  udp_add_dst_port (um, lcl_port, 0, is_ip4);
36  pi = udp_get_dst_port_info (um, lcl_port, is_ip4);
37  pi->n_connections = 1;
38  }
39  else
40  {
41  pi->n_connections += 1;
42  /* Do not return. The fact that the pi is valid does not mean
43  * it's up to date */
44  }
45 
46  pi->node_index = is_ip4 ? udp4_input_node.index : udp6_input_node.index;
47  pi->next_index = um->local_to_input_edge[is_ip4];
48 
49  /* Setup udp protocol -> next index sparse vector mapping. */
50  if (is_ip4)
52  clib_host_to_net_u16 (lcl_port));
53  else
55  clib_host_to_net_u16 (lcl_port));
56 
57  n[0] = pi->next_index;
58 }
59 
60 static void
62 {
63  udp_main_t *um = &udp_main;
65 
66  pi = udp_get_dst_port_info (um, lcl_port, is_ip4);
67  if (!pi)
68  return;
69 
70  if (!pi->n_connections)
71  {
72  clib_warning ("no connections using port %u", lcl_port);
73  return;
74  }
75 
76  if (!clib_atomic_sub_fetch (&pi->n_connections, 1))
77  udp_unregister_dst_port (0, lcl_port, is_ip4);
78 }
79 
80 void
81 udp_connection_share_port (u16 lcl_port, u8 is_ip4)
82 {
83  udp_main_t *um = &udp_main;
85 
86  /* Done without a lock but the operation is atomic. Writers to pi hash
87  * table and vector should be guarded by a barrier sync */
88  pi = udp_get_dst_port_info (um, lcl_port, is_ip4);
90 }
91 
93 udp_connection_alloc (u32 thread_index)
94 {
95  udp_main_t *um = &udp_main;
96  udp_connection_t *uc;
97  u32 will_expand = 0;
98  pool_get_aligned_will_expand (um->connections[thread_index], will_expand,
100 
101  if (PREDICT_FALSE (will_expand))
102  {
104  [thread_index]);
105  pool_get_aligned (udp_main.connections[thread_index], uc,
108  [thread_index]);
109  }
110  else
111  {
112  pool_get_aligned (um->connections[thread_index], uc,
114  }
115  clib_memset (uc, 0, sizeof (*uc));
116  uc->c_c_index = uc - um->connections[thread_index];
117  uc->c_thread_index = thread_index;
118  uc->c_proto = TRANSPORT_PROTO_UDP;
120  return uc;
121 }
122 
123 void
125 {
126  u32 thread_index = uc->c_thread_index;
127  if (CLIB_DEBUG)
128  clib_memset (uc, 0xFA, sizeof (*uc));
129  pool_put (udp_main.connections[thread_index], uc);
130 }
131 
132 static void
134 {
135  transport_endpoint_cleanup (TRANSPORT_PROTO_UDP, &uc->c_lcl_ip,
136  uc->c_lcl_port);
137  udp_connection_unregister_port (clib_net_to_host_u16 (uc->c_lcl_port),
138  uc->c_is_ip4);
139  udp_connection_free (uc);
140 }
141 
142 void
144 {
147 }
148 
149 static u8
151 {
152  udp_main_t *um = vnet_get_udp_main ();
154 
155  pi = udp_get_dst_port_info (um, lcl_port, is_ip4);
156  return (pi && !pi->n_connections
157  && udp_is_valid_dst_port (lcl_port, is_ip4));
158 }
159 
160 static u16
162 {
163  u16 ip_hlen = is_ip4 ? sizeof (ip4_header_t) : sizeof (ip6_header_t);
164  return (um->default_mtu - sizeof (udp_header_t) - ip_hlen);
165 }
166 
167 static u32
169 {
170  udp_main_t *um = vnet_get_udp_main ();
172  transport_endpoint_cfg_t *lcl_ext;
174  u16 lcl_port_ho;
175  void *iface_ip;
176 
177  lcl_port_ho = clib_net_to_host_u16 (lcl->port);
178 
179  if (udp_connection_port_used_extern (lcl_port_ho, lcl->is_ip4))
180  {
181  clib_warning ("port already used");
182  return SESSION_E_PORTINUSE;
183  }
184 
185  pool_get (um->listener_pool, listener);
186  clib_memset (listener, 0, sizeof (udp_connection_t));
187 
188  listener->c_lcl_port = lcl->port;
189  listener->c_c_index = listener - um->listener_pool;
190 
191  /* If we are provided a sw_if_index, bind using one of its ips */
192  if (ip_is_zero (&lcl->ip, 1) && lcl->sw_if_index != ENDPOINT_INVALID_INDEX)
193  {
194  if ((iface_ip = ip_interface_get_first_ip (lcl->sw_if_index,
195  lcl->is_ip4)))
196  ip_set (&lcl->ip, iface_ip, lcl->is_ip4);
197  }
198  ip_copy (&listener->c_lcl_ip, &lcl->ip, lcl->is_ip4);
199  listener->c_is_ip4 = lcl->is_ip4;
200  listener->c_proto = TRANSPORT_PROTO_UDP;
201  listener->c_s_index = session_index;
202  listener->c_fib_index = lcl->fib_index;
203  listener->mss = udp_default_mtu (um, listener->c_is_ip4);
204  listener->flags |= UDP_CONN_F_OWNS_PORT | UDP_CONN_F_LISTEN;
205  lcl_ext = (transport_endpoint_cfg_t *) lcl;
206  if (lcl_ext->transport_flags & TRANSPORT_CFG_F_CONNECTED)
207  listener->flags |= UDP_CONN_F_CONNECTED;
208  else
209  listener->c_flags |= TRANSPORT_CONNECTION_F_CLESS;
210  clib_spinlock_init (&listener->rx_lock);
211 
212  udp_connection_register_port (vm, lcl_port_ho, lcl->is_ip4);
213  return listener->c_c_index;
214 }
215 
216 static u32
217 udp_session_unbind (u32 listener_index)
218 {
219  udp_main_t *um = &udp_main;
221 
222  listener = udp_listener_get (listener_index);
223  udp_connection_unregister_port (clib_net_to_host_u16 (listener->c_lcl_port),
224  listener->c_is_ip4);
225  pool_put (um->listener_pool, listener);
226  return 0;
227 }
228 
229 static transport_connection_t *
231 {
232  udp_connection_t *us;
233 
234  us = udp_listener_get (listener_index);
235  return &us->connection;
236 }
237 
238 static u32
240 {
241  udp_connection_t *uc;
243 
245 
246  vlib_buffer_push_udp (b, uc->c_lcl_port, uc->c_rmt_port, 1);
247  if (tc->is_ip4)
248  vlib_buffer_push_ip4_custom (vm, b, &uc->c_lcl_ip4, &uc->c_rmt_ip4,
249  IP_PROTOCOL_UDP, 1 /* csum offload */ ,
250  0 /* is_df */ );
251  else
252  vlib_buffer_push_ip6 (vm, b, &uc->c_lcl_ip6, &uc->c_rmt_ip6,
253  IP_PROTOCOL_UDP);
254  vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
255  vnet_buffer (b)->sw_if_index[VLIB_TX] = uc->c_fib_index;
256  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
257 
258  if (PREDICT_FALSE (uc->flags & UDP_CONN_F_CLOSING))
259  {
262  }
263 
264  return 0;
265 }
266 
267 static transport_connection_t *
268 udp_session_get (u32 connection_index, u32 thread_index)
269 {
270  udp_connection_t *uc;
271  uc = udp_connection_get (connection_index, thread_index);
272  if (uc)
273  return &uc->connection;
274  return 0;
275 }
276 
277 static void
278 udp_session_close (u32 connection_index, u32 thread_index)
279 {
280  udp_connection_t *uc;
281 
282  uc = udp_connection_get (connection_index, thread_index);
283  if (!uc)
284  return;
285 
288  else
289  uc->flags |= UDP_CONN_F_CLOSING;
290 }
291 
292 static void
293 udp_session_cleanup (u32 connection_index, u32 thread_index)
294 {
295  udp_connection_t *uc;
296  uc = udp_connection_get (connection_index, thread_index);
297  if (!uc)
298  return;
299  if (uc->flags & UDP_CONN_F_MIGRATED)
300  udp_connection_free (uc);
301  else
303 }
304 
305 static int
308 {
309  udp_connection_t *uc;
310 
311  uc = udp_connection_from_transport (tconn);
312 
313  /* No constraint on TX window */
314  sp->snd_space = ~0;
315  /* TODO figure out MTU of output interface */
316  sp->snd_mss = uc->mss;
317  sp->tx_offset = 0;
318  sp->flags = 0;
319  return 0;
320 }
321 
322 static int
324 {
326  u32 thread_index = vm->thread_index;
327  udp_main_t *um = &udp_main;
328  ip46_address_t lcl_addr;
329  udp_connection_t *uc;
330  u16 lcl_port;
331  int rv;
332 
333  rv = transport_alloc_local_endpoint (TRANSPORT_PROTO_UDP, rmt, &lcl_addr,
334  &lcl_port);
335  if (rv)
336  {
337  if (rv != SESSION_E_PORTINUSE)
338  return rv;
339 
340  if (udp_connection_port_used_extern (lcl_port, rmt->is_ip4))
341  return SESSION_E_PORTINUSE;
342 
343  /* If port in use, check if 5-tuple is also in use */
344  if (session_lookup_connection (rmt->fib_index, &lcl_addr, &rmt->ip,
345  lcl_port, rmt->port, TRANSPORT_PROTO_UDP,
346  rmt->is_ip4))
347  return SESSION_E_PORTINUSE;
348 
349  /* 5-tuple is available so increase lcl endpoint refcount and proceed
350  * with connection allocation */
351  transport_share_local_endpoint (TRANSPORT_PROTO_UDP, &lcl_addr,
352  lcl_port);
353  goto conn_alloc;
354  }
355 
356  if (udp_is_valid_dst_port (lcl_port, rmt->is_ip4))
357  {
358  /* If specific source port was requested abort */
359  if (rmt->peer.port)
360  return SESSION_E_PORTINUSE;
361 
362  /* Try to find a port that's not used */
363  while (udp_is_valid_dst_port (lcl_port, rmt->is_ip4))
364  {
365  lcl_port = transport_alloc_local_port (TRANSPORT_PROTO_UDP,
366  &lcl_addr);
367  if (lcl_port < 1)
368  return SESSION_E_PORTINUSE;
369  }
370  }
371 
372 conn_alloc:
373 
374  udp_connection_register_port (vm, lcl_port, rmt->is_ip4);
375 
376  /* We don't poll main thread if we have workers */
377  if (vlib_num_workers ())
378  thread_index = 1;
379 
380  uc = udp_connection_alloc (thread_index);
381  ip_copy (&uc->c_rmt_ip, &rmt->ip, rmt->is_ip4);
382  ip_copy (&uc->c_lcl_ip, &lcl_addr, rmt->is_ip4);
383  uc->c_rmt_port = rmt->port;
384  uc->c_lcl_port = clib_host_to_net_u16 (lcl_port);
385  uc->c_is_ip4 = rmt->is_ip4;
386  uc->c_proto = TRANSPORT_PROTO_UDP;
387  uc->c_fib_index = rmt->fib_index;
388  uc->mss = rmt->mss ? rmt->mss : udp_default_mtu (um, uc->c_is_ip4);
389  uc->flags |= UDP_CONN_F_OWNS_PORT;
390  if (rmt->transport_flags & TRANSPORT_CFG_F_CONNECTED)
391  uc->flags |= UDP_CONN_F_CONNECTED;
392  else
393  uc->c_flags |= TRANSPORT_CONNECTION_F_CLESS;
394 
395  return uc->c_c_index;
396 }
397 
398 static transport_connection_t *
400 {
401  udp_connection_t *uc;
402  u32 thread_index;
403 
404  /* We don't poll main thread if we have workers */
405  thread_index = vlib_num_workers ()? 1 : 0;
406  uc = udp_connection_get (conn_index, thread_index);
407  if (!uc)
408  return 0;
409  return &uc->connection;
410 }
411 
412 static u8 *
413 format_udp_session (u8 * s, va_list * args)
414 {
415  u32 uci = va_arg (*args, u32);
416  u32 thread_index = va_arg (*args, u32);
417  u32 verbose = va_arg (*args, u32);
418  udp_connection_t *uc;
419 
420  uc = udp_connection_get (uci, thread_index);
421  return format (s, "%U", format_udp_connection, uc, verbose);
422 }
423 
424 static u8 *
425 format_udp_half_open_session (u8 * s, va_list * args)
426 {
427  u32 __clib_unused tci = va_arg (*args, u32);
428  u32 __clib_unused thread_index = va_arg (*args, u32);
429  clib_warning ("BUG");
430  return 0;
431 }
432 
433 static u8 *
434 format_udp_listener_session (u8 * s, va_list * args)
435 {
436  u32 tci = va_arg (*args, u32);
437  u32 __clib_unused thread_index = va_arg (*args, u32);
438  u32 verbose = va_arg (*args, u32);
440  return format (s, "%U", format_udp_connection, uc, verbose);
441 }
442 
443 /* *INDENT-OFF* */
445  .start_listen = udp_session_bind,
446  .connect = udp_open_connection,
447  .stop_listen = udp_session_unbind,
448  .push_header = udp_push_header,
449  .get_connection = udp_session_get,
450  .get_listener = udp_session_get_listener,
451  .get_half_open = udp_session_get_half_open,
452  .close = udp_session_close,
453  .cleanup = udp_session_cleanup,
454  .send_params = udp_session_send_params,
455  .format_connection = format_udp_session,
456  .format_half_open = format_udp_half_open_session,
457  .format_listener = format_udp_listener_session,
458  .transport_options = {
459  .name = "udp",
460  .short_name = "U",
461  .tx_type = TRANSPORT_TX_DGRAM,
462  .service_type = TRANSPORT_SERVICE_CL,
463  },
464 };
465 /* *INDENT-ON* */
466 
467 static clib_error_t *
469 {
470  udp_main_t *um = vnet_get_udp_main ();
471  ip_main_t *im = &ip_main;
473  u32 num_threads;
474  ip_protocol_info_t *pi;
475  int i;
476 
477  /*
478  * Registrations
479  */
480 
481  /* IP registration */
482  pi = ip_get_protocol_info (im, IP_PROTOCOL_UDP);
483  if (pi == 0)
484  return clib_error_return (0, "UDP protocol info AWOL");
487 
488  /* Register as transport with URI */
489  transport_register_protocol (TRANSPORT_PROTO_UDP, &udp_proto,
491  transport_register_protocol (TRANSPORT_PROTO_UDP, &udp_proto,
493 
494  /*
495  * Initialize data structures
496  */
497 
498  num_threads = 1 /* main thread */ + tm->n_threads;
499  vec_validate (um->connections, num_threads - 1);
500  vec_validate (um->connection_peekers, num_threads - 1);
501  vec_validate (um->peekers_readers_locks, num_threads - 1);
502  vec_validate (um->peekers_write_locks, num_threads - 1);
503 
504  if (num_threads > 1)
505  for (i = 0; i < num_threads; i++)
506  {
509  }
510 
515 
516  um->default_mtu = 1500;
517  return 0;
518 }
519 
520 /* *INDENT-OFF* */
522 {
523  .runs_after = VLIB_INITS("ip_main_init", "ip4_lookup_init",
524  "ip6_lookup_init"),
525 };
526 /* *INDENT-ON* */
527 
528 /*
529  * fd.io coding-style-patch-verification: ON
530  *
531  * Local Variables:
532  * eval: (c-set-style "gnu")
533  * End:
534  */
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:506
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
static void udp_connection_cleanup(udp_connection_t *uc)
Definition: udp.c:133
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
udp_main_t udp_main
Definition: udp.c:23
static udp_connection_t * udp_connection_from_transport(transport_connection_t *tc)
Definition: udp.h:157
#define ENDPOINT_INVALID_INDEX
static udp_connection_t * udp_listener_get(u32 conn_index)
Definition: udp.h:145
u16 * next_by_dst_port6
Definition: udp.h:108
void ip_copy(ip46_address_t *dst, ip46_address_t *src, u8 is_ip4)
Definition: ip.c:81
format_function_t format_udp_header
Definition: format.h:100
u32 n_connections
Definition: udp.h:84
void udp_connection_share_port(u16 lcl_port, u8 is_ip4)
Definition: udp.c:81
static void udp_session_close(u32 connection_index, u32 thread_index)
Definition: udp.c:278
u32 * connection_peekers
Definition: udp.h:119
void transport_share_local_endpoint(u8 proto, ip46_address_t *lcl_ip, u16 port)
Definition: transport.c:456
void * ip_interface_get_first_ip(u32 sw_if_index, u8 is_ip4)
Definition: ip_interface.c:174
void ip_set(ip46_address_t *dst, void *src, u8 is_ip4)
Definition: ip.c:93
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
void session_transport_delete_notify(transport_connection_t *tc)
Notification from transport that connection is being deleted.
Definition: session.c:997
static clib_error_t * udp_init(vlib_main_t *vm)
Definition: udp.c:468
static u32 udp_push_header(transport_connection_t *tc, vlib_buffer_t *b)
Definition: udp.c:239
static void udp_connection_unregister_port(u16 lcl_port, u8 is_ip4)
Definition: udp.c:61
static u32 udp_session_bind(u32 session_index, transport_endpoint_t *lcl)
Definition: udp.c:168
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:129
Definition: udp.h:97
u32 thread_index
Definition: main.h:250
#define pool_get_aligned_will_expand(P, YESNO, A)
See if pool_get will expand the pool or not.
Definition: pool.h:257
u32 node_index
Definition: udp.h:78
static udp_dst_port_info_t * udp_get_dst_port_info(udp_main_t *um, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp.h:226
static u8 * format_udp_session(u8 *s, va_list *args)
Definition: udp.c:413
vlib_main_t * vm
Definition: in2out_ed.c:1580
Definition: ip.h:107
vlib_node_registration_t udp4_local_node
(constructor) VLIB_REGISTER_NODE (udp4_local_node)
Definition: udp_local.c:403
u16 mss
connection mss
Definition: udp.h:66
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:251
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1173
unsigned char u8
Definition: types.h:56
static udp_main_t * vnet_get_udp_main()
Definition: udp.h:151
u8 flags
connection flags
Definition: udp.h:65
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:104
unformat_function_t * unformat_pg_edit
Definition: ip.h:88
void udp_connection_free(udp_connection_t *uc)
Definition: udp.c:124
Connection is "connection less".
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
description fragment has unexpected format
Definition: map.api:433
#define sparse_vec_validate(v, i)
Definition: sparse_vec.h:231
void udp_add_dst_port(udp_main_t *um, udp_dst_port_t dst_port, char *dst_port_name, u8 is_ip4)
Definition: udp_local.c:448
#define clib_error_return(e, args...)
Definition: error.h:99
const cJSON *const b
Definition: cJSON.h:255
int transport_alloc_local_endpoint(u8 proto, transport_endpoint_cfg_t *rmt_cfg, ip46_address_t *lcl_addr, u16 *lcl_port)
Definition: transport.c:565
unsigned int u32
Definition: types.h:88
static transport_connection_t * udp_session_get(u32 connection_index, u32 thread_index)
Definition: udp.c:268
struct _transport_proto_vft transport_proto_vft_t
static void * vlib_buffer_push_ip6(vlib_main_t *vm, vlib_buffer_t *b, ip6_address_t *src, ip6_address_t *dst, int proto)
Push IPv6 header to buffer.
Definition: ip6_inlines.h:250
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
static transport_connection_t * udp_session_get_listener(u32 listener_index)
Definition: udp.c:230
vlib_node_registration_t udp4_input_node
(constructor) VLIB_REGISTER_NODE (udp4_input_node)
Definition: udp_input.c:344
u16 * next_by_dst_port4
Definition: udp.h:107
static ip_protocol_info_t * ip_get_protocol_info(ip_main_t *im, u32 protocol)
Definition: ip.h:134
format_function_t * format_header
Definition: ip.h:79
format_function_t format_udp_connection
Definition: udp.h:234
static u8 * format_udp_listener_session(u8 *s, va_list *args)
Definition: udp.c:434
udp_connection_t * udp_connection_alloc(u32 thread_index)
Definition: udp.c:93
unsigned short u16
Definition: types.h:57
u8 udp_is_valid_dst_port(udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:529
clib_spinlock_t * peekers_readers_locks
Definition: udp.h:120
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
vlib_node_registration_t udp6_input_node
(constructor) VLIB_REGISTER_NODE (udp6_input_node)
Definition: udp_input.c:370
#define PREDICT_FALSE(x)
Definition: clib.h:121
static u8 udp_connection_port_used_extern(u16 lcl_port, u8 is_ip4)
Definition: udp.c:150
udp_connection_t * listener_pool
Definition: udp.h:122
#define clib_atomic_fetch_add_rel(a, b)
Definition: atomics.h:54
void udp_connection_delete(udp_connection_t *uc)
Definition: udp.c:143
static void * vlib_buffer_push_ip4_custom(vlib_main_t *vm, vlib_buffer_t *b, ip4_address_t *src, ip4_address_t *dst, int proto, u8 csum_offload, u8 is_df)
Definition: ip4_inlines.h:100
Definition: udp.h:92
#define clib_atomic_sub_fetch(a, b)
Definition: atomics.h:31
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:245
static int udp_session_send_params(transport_connection_t *tconn, transport_send_params_t *sp)
Definition: udp.c:306
ip_main_t ip_main
Definition: ip_init.c:42
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define clib_warning(format, args...)
Definition: error.h:59
unformat_function_t unformat_pg_udp_header
Definition: format.h:102
static udp_connection_t * udp_connection_get(u32 conn_index, u32 thread_index)
Definition: udp.h:137
static int udp_open_connection(transport_endpoint_cfg_t *rmt)
Definition: udp.c:323
struct _transport_connection transport_connection_t
void transport_endpoint_cleanup(u8 proto, ip46_address_t *lcl_ip, u16 port)
Definition: transport.c:421
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:246
transport_snd_flags_t flags
Definition: transport.h:62
static u32 transport_max_tx_dequeue(transport_connection_t *tc)
Definition: session.h:509
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
Definition: ip6_forward.c:742
static void udp_connection_register_port(vlib_main_t *vm, u16 lcl_port, u8 is_ip4)
Definition: udp.c:26
datagram mode
static u8 * format_udp_half_open_session(u8 *s, va_list *args)
Definition: udp.c:425
static void * vlib_buffer_push_udp(vlib_buffer_t *b, u16 sp, u16 dp, u8 offload_csum)
Definition: udp_inlines.h:25
clib_spinlock_t * peekers_write_locks
Definition: udp.h:121
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
u32 local_to_input_edge[N_UDP_AF]
Definition: udp.h:113
static u16 udp_default_mtu(udp_main_t *um, u8 is_ip4)
Definition: udp.c:161
Definition: defs.h:47
static u32 udp_session_unbind(u32 listener_index)
Definition: udp.c:217
static const transport_proto_vft_t udp_proto
Definition: udp.c:444
transport_connection_t connection
must be first
Definition: udp.h:63
clib_spinlock_t rx_lock
rx fifo lock
Definition: udp.h:64
VLIB buffer representation.
Definition: buffer.h:102
connectionless service
transport_connection_t * session_lookup_connection(u32 fib_index, ip46_address_t *lcl, ip46_address_t *rmt, u16 lcl_port, u16 rmt_port, u8 proto, u8 is_ip4)
u16 default_mtu
Definition: udp.h:124
vlib_node_registration_t udp6_local_node
(constructor) VLIB_REGISTER_NODE (udp6_local_node)
Definition: udp_local.c:425
#define vnet_buffer(b)
Definition: buffer.h:417
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static u32 vlib_num_workers()
Definition: threads.h:377
u32 next_index
Definition: udp.h:81
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:475
static transport_connection_t * udp_session_get_half_open(u32 conn_index)
Definition: udp.c:399
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
udp_connection_t ** connections
Definition: udp.h:118
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:106
static void udp_session_cleanup(u32 connection_index, u32 thread_index)
Definition: udp.c:293
#define VLIB_INITS(...)
Definition: init.h:357
Definition: udp.h:93
Definition: defs.h:46