FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
udp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-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 /** @file
17  udp state machine, etc.
18 */
19 
20 #include <vnet/udp/udp.h>
21 #include <vnet/session/session.h>
22 #include <vnet/dpo/load_balance.h>
23 #include <vnet/fib/ip4_fib.h>
24 
26 
28 udp_connection_alloc (u32 thread_index)
29 {
30  udp_main_t *um = &udp_main;
31  udp_connection_t *uc;
32  u32 will_expand = 0;
33  pool_get_aligned_will_expand (um->connections[thread_index], will_expand,
35 
36  if (PREDICT_FALSE (will_expand))
37  {
39  [thread_index]);
40  pool_get_aligned (udp_main.connections[thread_index], uc,
43  [thread_index]);
44  }
45  else
46  {
47  pool_get_aligned (um->connections[thread_index], uc,
49  }
50  clib_memset (uc, 0, sizeof (*uc));
51  uc->c_c_index = uc - um->connections[thread_index];
52  uc->c_thread_index = thread_index;
53  uc->c_proto = TRANSPORT_PROTO_UDP;
55  return uc;
56 }
57 
58 void
60 {
61  u32 thread_index = uc->c_thread_index;
62  if (CLIB_DEBUG)
63  clib_memset (uc, 0xFA, sizeof (*uc));
64  pool_put (udp_main.connections[thread_index], uc);
65 }
66 
67 void
69 {
70  if ((uc->flags & UDP_CONN_F_OWNS_PORT)
71  || !(uc->flags & UDP_CONN_F_CONNECTED))
73  clib_net_to_host_u16 (uc->c_lcl_port),
74  uc->c_is_ip4);
77 }
78 
79 u32
81 {
85  u32 node_index;
86  void *iface_ip;
88 
89  pi = udp_get_dst_port_info (um, lcl->port, lcl->is_ip4);
90  if (pi)
91  return -1;
92 
93  pool_get (um->listener_pool, listener);
94  clib_memset (listener, 0, sizeof (udp_connection_t));
95 
96  listener->c_lcl_port = lcl->port;
97  listener->c_c_index = listener - um->listener_pool;
98 
99  /* If we are provided a sw_if_index, bind using one of its ips */
100  if (ip_is_zero (&lcl->ip, 1) && lcl->sw_if_index != ENDPOINT_INVALID_INDEX)
101  {
102  if ((iface_ip = ip_interface_get_first_ip (lcl->sw_if_index,
103  lcl->is_ip4)))
104  ip_set (&lcl->ip, iface_ip, lcl->is_ip4);
105  }
106  ip_copy (&listener->c_lcl_ip, &lcl->ip, lcl->is_ip4);
107  listener->c_is_ip4 = lcl->is_ip4;
108  listener->c_proto = TRANSPORT_PROTO_UDP;
109  listener->c_s_index = session_index;
110  listener->c_fib_index = lcl->fib_index;
111  listener->flags |= UDP_CONN_F_OWNS_PORT;
112  clib_spinlock_init (&listener->rx_lock);
113 
114  node_index = lcl->is_ip4 ? udp4_input_node.index : udp6_input_node.index;
115  udp_register_dst_port (vm, clib_net_to_host_u16 (lcl->port), node_index,
116  1 /* is_ipv4 */ );
117  return listener->c_c_index;
118 }
119 
120 u32
121 udp_session_unbind (u32 listener_index)
122 {
124 
126  listener = udp_listener_get (listener_index);
127  udp_unregister_dst_port (vm, clib_net_to_host_u16 (listener->c_lcl_port),
128  listener->c_is_ip4);
129  return 0;
130 }
131 
134 {
135  udp_connection_t *us;
136 
137  us = udp_listener_get (listener_index);
138  return &us->connection;
139 }
140 
141 u32
143 {
144  udp_connection_t *uc;
146 
148 
149  vlib_buffer_push_udp (b, uc->c_lcl_port, uc->c_rmt_port, 1);
150  if (tc->is_ip4)
151  vlib_buffer_push_ip4 (vm, b, &uc->c_lcl_ip4, &uc->c_rmt_ip4,
152  IP_PROTOCOL_UDP, 1);
153  else
154  {
155  ip6_header_t *ih;
156  ih = vlib_buffer_push_ip6 (vm, b, &uc->c_lcl_ip6, &uc->c_rmt_ip6,
157  IP_PROTOCOL_UDP);
158  vnet_buffer (b)->l3_hdr_offset = (u8 *) ih - b->data;
159  }
160  vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
161  vnet_buffer (b)->sw_if_index[VLIB_TX] = uc->c_fib_index;
162  b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
163 
165  {
168  }
169 
170  return 0;
171 }
172 
174 udp_session_get (u32 connection_index, u32 thread_index)
175 {
176  udp_connection_t *uc;
177  uc = udp_connection_get (connection_index, thread_index);
178  if (uc)
179  return &uc->connection;
180  return 0;
181 }
182 
183 void
184 udp_session_close (u32 connection_index, u32 thread_index)
185 {
186  udp_connection_t *uc;
187 
188  uc = udp_connection_get (connection_index, thread_index);
189  if (!uc)
190  return;
191 
194  else
195  uc->flags |= UDP_CONN_F_CLOSING;
196 }
197 
198 void
199 udp_session_cleanup (u32 connection_index, u32 thread_index)
200 {
201  udp_connection_t *uc;
202  uc = udp_connection_get (connection_index, thread_index);
203  if (uc)
204  udp_connection_free (uc);
205 }
206 
207 u8 *
208 format_udp_connection_id (u8 * s, va_list * args)
209 {
210  udp_connection_t *uc = va_arg (*args, udp_connection_t *);
211  if (!uc)
212  return s;
213  if (uc->c_is_ip4)
214  s = format (s, "[#%d][%s] %U:%d->%U:%d", uc->c_thread_index, "U",
215  format_ip4_address, &uc->c_lcl_ip4,
216  clib_net_to_host_u16 (uc->c_lcl_port), format_ip4_address,
217  &uc->c_rmt_ip4, clib_net_to_host_u16 (uc->c_rmt_port));
218  else
219  s = format (s, "[#%d][%s] %U:%d->%U:%d", uc->c_thread_index, "U",
220  format_ip6_address, &uc->c_lcl_ip6,
221  clib_net_to_host_u16 (uc->c_lcl_port), format_ip6_address,
222  &uc->c_rmt_ip6, clib_net_to_host_u16 (uc->c_rmt_port));
223  return s;
224 }
225 
226 u8 *
227 format_udp_connection (u8 * s, va_list * args)
228 {
229  udp_connection_t *uc = va_arg (*args, udp_connection_t *);
230  u32 verbose = va_arg (*args, u32);
231  if (!uc)
232  return s;
233  s = format (s, "%-50U", format_udp_connection_id, uc);
234  if (verbose)
235  {
236  if (verbose == 1)
237  s = format (s, "%-15s", "-");
238  else
239  s = format (s, "\n");
240  }
241  return s;
242 }
243 
244 u8 *
245 format_udp_session (u8 * s, va_list * args)
246 {
247  u32 uci = va_arg (*args, u32);
248  u32 thread_index = va_arg (*args, u32);
249  u32 verbose = va_arg (*args, u32);
250  udp_connection_t *uc;
251 
252  uc = udp_connection_get (uci, thread_index);
253  return format (s, "%U", format_udp_connection, uc, verbose);
254 }
255 
256 u8 *
257 format_udp_half_open_session (u8 * s, va_list * args)
258 {
259  u32 __clib_unused tci = va_arg (*args, u32);
260  u32 __clib_unused thread_index = va_arg (*args, u32);
261  clib_warning ("BUG");
262  return 0;
263 }
264 
265 u8 *
266 format_udp_listener_session (u8 * s, va_list * args)
267 {
268  u32 tci = va_arg (*args, u32);
269  u32 __clib_unused thread_index = va_arg (*args, u32);
270  u32 verbose = va_arg (*args, u32);
272  return format (s, "%U", format_udp_connection, uc, verbose);
273 }
274 
275 u16
277 {
278  /* TODO figure out MTU of output interface */
279  return 1460;
280 }
281 
282 u32
284 {
285  /* No constraint on TX window */
286  return ~0;
287 }
288 
289 int
291 {
292  udp_main_t *um = vnet_get_udp_main ();
294  u32 thread_index = vm->thread_index;
295  udp_connection_t *uc;
296  ip46_address_t lcl_addr;
297  u32 node_index;
298  u16 lcl_port;
299 
300  if (transport_alloc_local_endpoint (TRANSPORT_PROTO_UDP, rmt, &lcl_addr,
301  &lcl_port))
302  return -1;
303 
304  while (udp_get_dst_port_info (um, lcl_port, rmt->is_ip4))
305  {
306  lcl_port = transport_alloc_local_port (TRANSPORT_PROTO_UDP, &lcl_addr);
307  if (lcl_port < 1)
308  {
309  clib_warning ("Failed to allocate src port");
310  return -1;
311  }
312  }
313 
314  node_index = rmt->is_ip4 ? udp4_input_node.index : udp6_input_node.index;
315  udp_register_dst_port (vm, lcl_port, node_index, 1 /* is_ipv4 */ );
316 
317  /* We don't poll main thread if we have workers */
318  if (vlib_num_workers ())
319  thread_index = 1;
320 
321  uc = udp_connection_alloc (thread_index);
322  ip_copy (&uc->c_rmt_ip, &rmt->ip, rmt->is_ip4);
323  ip_copy (&uc->c_lcl_ip, &lcl_addr, rmt->is_ip4);
324  uc->c_rmt_port = rmt->port;
325  uc->c_lcl_port = clib_host_to_net_u16 (lcl_port);
326  uc->c_is_ip4 = rmt->is_ip4;
327  uc->c_proto = TRANSPORT_PROTO_UDP;
328  uc->c_fib_index = rmt->fib_index;
330 
331  return uc->c_c_index;
332 }
333 
336 {
337  udp_connection_t *uc;
338  u32 thread_index;
339 
340  /* We don't poll main thread if we have workers */
341  thread_index = vlib_num_workers ()? 1 : 0;
342  uc = udp_connection_get (conn_index, thread_index);
343  if (!uc)
344  return 0;
345  return &uc->connection;
346 }
347 
348 /* *INDENT-OFF* */
350  .start_listen = udp_session_bind,
351  .connect = udp_open_connection,
352  .stop_listen = udp_session_unbind,
353  .push_header = udp_push_header,
354  .get_connection = udp_session_get,
355  .get_listener = udp_session_get_listener,
356  .get_half_open = udp_session_get_half_open,
357  .close = udp_session_close,
358  .cleanup = udp_session_cleanup,
359  .send_mss = udp_send_mss,
360  .send_space = udp_send_space,
361  .format_connection = format_udp_session,
362  .format_half_open = format_udp_half_open_session,
363  .format_listener = format_udp_listener_session,
364  .transport_options = {
365  .tx_type = TRANSPORT_TX_DGRAM,
366  .service_type = TRANSPORT_SERVICE_CL,
367  },
368 };
369 /* *INDENT-ON* */
370 
371 
372 int
374 {
375  udp_connection_t *uc;
376  /* Reproduce the logic of udp_open_connection to find the correct thread */
377  u32 thread_index = vlib_num_workers ()? 1 : vlib_get_main ()->thread_index;
378  u32 uc_index;
379  uc_index = udp_open_connection (rmt);
380  if (uc_index == (u32) ~ 0)
381  return -1;
382  uc = udp_connection_get (uc_index, thread_index);
384  return uc_index;
385 }
386 
387 u32
389 {
391  u32 li_index;
392  li_index = udp_session_bind (session_index, lcl);
393  if (li_index == (u32) ~ 0)
394  return -1;
395  listener = udp_listener_get (li_index);
396  listener->flags |= UDP_CONN_F_CONNECTED;
397  /* Fake udp listener, i.e., make sure session layer adds a udp instead of
398  * udpc listener to the lookup table */
399  ((session_endpoint_cfg_t *) lcl)->transport_proto = TRANSPORT_PROTO_UDP;
400  return li_index;
401 }
402 
403 /* *INDENT-OFF* */
405  .start_listen = udpc_connection_listen,
406  .stop_listen = udp_session_unbind,
407  .connect = udpc_connection_open,
408  .push_header = udp_push_header,
409  .get_connection = udp_session_get,
410  .get_listener = udp_session_get_listener,
411  .get_half_open = udp_session_get_half_open,
412  .close = udp_session_close,
413  .cleanup = udp_session_cleanup,
414  .send_mss = udp_send_mss,
415  .send_space = udp_send_space,
416  .format_connection = format_udp_session,
417  .format_half_open = format_udp_half_open_session,
418  .format_listener = format_udp_listener_session,
419  .transport_options = {
420  .tx_type = TRANSPORT_TX_DGRAM,
421  .service_type = TRANSPORT_SERVICE_VC,
422  .half_open_has_fifos = 1
423  },
424 };
425 /* *INDENT-ON* */
426 
427 static clib_error_t *
429 {
430  udp_main_t *um = vnet_get_udp_main ();
431  ip_main_t *im = &ip_main;
433  u32 num_threads;
434  ip_protocol_info_t *pi;
435  int i;
436 
437  /*
438  * Registrations
439  */
440 
441  /* IP registration */
442  pi = ip_get_protocol_info (im, IP_PROTOCOL_UDP);
443  if (pi == 0)
444  return clib_error_return (0, "UDP protocol info AWOL");
447 
448  /* Register as transport with URI */
449  transport_register_protocol (TRANSPORT_PROTO_UDP, &udp_proto,
451  transport_register_protocol (TRANSPORT_PROTO_UDP, &udp_proto,
453  transport_register_protocol (TRANSPORT_PROTO_UDPC, &udpc_proto,
455  transport_register_protocol (TRANSPORT_PROTO_UDPC, &udpc_proto,
457 
458  /*
459  * Initialize data structures
460  */
461 
462  num_threads = 1 /* main thread */ + tm->n_threads;
463  vec_validate (um->connections, num_threads - 1);
464  vec_validate (um->connection_peekers, num_threads - 1);
465  vec_validate (um->peekers_readers_locks, num_threads - 1);
466  vec_validate (um->peekers_write_locks, num_threads - 1);
467 
468  if (num_threads > 1)
469  for (i = 0; i < num_threads; i++)
470  {
473  }
474  return 0;
475 }
476 
477 /* *INDENT-OFF* */
479 {
480  .runs_after = VLIB_INITS("ip_main_init", "ip4_lookup_init",
481  "ip6_lookup_init"),
482 };
483 /* *INDENT-ON* */
484 
485 
486 static clib_error_t *
488  vlib_cli_command_t * cmd_arg)
489 {
490  udp_main_t *um = vnet_get_udp_main ();
491 
492  clib_error_t *error = NULL;
493 
495  return clib_error_return (0, "unknown input `%U'", format_unformat_error,
496  input);
497 
498  udp_dst_port_info_t *port_info;
499  if (um->punt_unknown4)
500  {
501  vlib_cli_output (vm, "IPv4 UDP punt: enabled");
502  }
503  else
504  {
505  u8 *s = NULL;
506  vec_foreach (port_info, um->dst_port_infos[UDP_IP4])
507  {
508  if (udp_is_valid_dst_port (port_info->dst_port, 1))
509  {
510  s = format (s, (!s) ? "%d" : ", %d", port_info->dst_port);
511  }
512  }
513  s = format (s, "%c", 0);
514  vlib_cli_output (vm, "IPV4 UDP ports punt : %s", s);
515  }
516 
517  if (um->punt_unknown6)
518  {
519  vlib_cli_output (vm, "IPv6 UDP punt: enabled");
520  }
521  else
522  {
523  u8 *s = NULL;
524  vec_foreach (port_info, um->dst_port_infos[UDP_IP6])
525  {
526  if (udp_is_valid_dst_port (port_info->dst_port, 01))
527  {
528  s = format (s, (!s) ? "%d" : ", %d", port_info->dst_port);
529  }
530  }
531  s = format (s, "%c", 0);
532  vlib_cli_output (vm, "IPV6 UDP ports punt : %s", s);
533  }
534 
535  return (error);
536 }
537 /* *INDENT-OFF* */
538 VLIB_CLI_COMMAND (show_tcp_punt_command, static) =
539 {
540  .path = "show udp punt",
541  .short_help = "show udp punt [ipv4|ipv6]",
542  .function = show_udp_punt_fn,
543 };
544 /* *INDENT-ON* */
545 
546 /*
547  * fd.io coding-style-patch-verification: ON
548  *
549  * Local Variables:
550  * eval: (c-set-style "gnu")
551  * End:
552  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:440
static clib_error_t * show_udp_punt_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd_arg)
Definition: udp.c:487
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:25
void udp_session_cleanup(u32 connection_index, u32 thread_index)
Definition: udp.c:199
#define ENDPOINT_INVALID_INDEX
port belong to conn (UDPC)
Definition: udp.h:40
static udp_connection_t * udp_listener_get(u32 conn_index)
Definition: udp.h:170
u8 * format_udp_session(u8 *s, va_list *args)
Definition: udp.c:245
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 * connection_peekers
Definition: udp.h:148
static udp_connection_t * udp_get_connection_from_transport(transport_connection_t *tc)
Definition: udp.h:182
void ip_set(ip46_address_t *dst, void *src, u8 is_ip4)
Definition: ip.c:90
#define NULL
Definition: clib.h:58
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:880
static clib_error_t * udp_init(vlib_main_t *vm)
Definition: udp.c:428
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:110
transport_connection_t * udp_session_get_half_open(u32 conn_index)
Definition: udp.c:335
u32 thread_index
Definition: main.h:218
#define pool_get_aligned_will_expand(P, YESNO, A)
See if pool_get will expand the pool or not.
Definition: pool.h:243
u8 data[0]
Packet data.
Definition: buffer.h:181
conn closed with data
Definition: udp.h:41
int i
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:250
int udp_open_connection(transport_endpoint_cfg_t *rmt)
Definition: udp.c:290
transport_connection_t * udp_session_get_listener(u32 listener_index)
Definition: udp.c:133
void * ip_interface_get_first_ip(u32 sw_if_index, u8 is_ip4)
Definition: ip.c:134
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
Definition: ip.h:106
u32 udp_push_header(transport_connection_t *tc, vlib_buffer_t *b)
Definition: udp.c:142
u8 punt_unknown6
Definition: udp.h:142
static void * vlib_buffer_push_udp(vlib_buffer_t *b, u16 sp, u16 dp, u8 offload_csum)
Definition: udp.h:270
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:237
unsigned char u8
Definition: types.h:56
static udp_main_t * vnet_get_udp_main()
Definition: udp.h:176
u8 flags
connection flags
Definition: udp.h:50
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
Definition: ip4_forward.c:102
format_function_t format_ip4_address
Definition: format.h:73
unformat_function_t * unformat_pg_edit
Definition: ip.h:87
void udp_connection_free(udp_connection_t *uc)
Definition: udp.c:59
int udpc_connection_open(transport_endpoint_cfg_t *rmt)
Definition: udp.c:373
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u8 punt_unknown4
Definition: udp.h:141
u32 udp_session_bind(u32 session_index, transport_endpoint_t *lcl)
Definition: udp.c:80
#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
static const transport_proto_vft_t udpc_proto
Definition: udp.c:404
struct _transport_proto_vft transport_proto_vft_t
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:63
struct _session_endpoint_cfg session_endpoint_cfg_t
vlib_node_registration_t udp4_input_node
(constructor) VLIB_REGISTER_NODE (udp4_input_node)
Definition: udp_input.c:299
static ip_protocol_info_t * ip_get_protocol_info(ip_main_t *im, u32 protocol)
Definition: ip.h:133
format_function_t * format_header
Definition: ip.h:78
u32 udp_session_unbind(u32 listener_index)
Definition: udp.c:121
udp_dst_port_info_t * dst_port_infos[N_UDP_AF]
Definition: udp.h:131
udp_connection_t * udp_connection_alloc(u32 thread_index)
Definition: udp.c:28
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
clib_spinlock_t * peekers_readers_locks
Definition: udp.h:149
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
vlib_node_registration_t udp6_input_node
(constructor) VLIB_REGISTER_NODE (udp6_input_node)
Definition: udp_input.c:325
#define PREDICT_FALSE(x)
Definition: clib.h:111
udp_connection_t * listener_pool
Definition: udp.h:151
u16 udp_send_mss(transport_connection_t *t)
Definition: udp.c:276
vlib_main_t * vm
Definition: in2out_ed.c:1810
void udp_connection_delete(udp_connection_t *uc)
Definition: udp.c:68
Definition: udp.h:124
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:231
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
format_function_t format_ip6_address
Definition: format.h:91
ip_main_t ip_main
Definition: ip_init.c:42
virtual circuit service
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:509
#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:162
struct _transport_connection transport_connection_t
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
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
static u32 transport_max_tx_dequeue(transport_connection_t *tc)
Definition: session.h:478
connected mode
Definition: udp.h:39
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
Definition: ip6_forward.c:667
udp_dst_port_t dst_port
Definition: udp.h:110
datagram mode
clib_spinlock_t * peekers_write_locks
Definition: udp.h:150
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u8 * format_udp_connection(u8 *s, va_list *args)
Definition: udp.c:227
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
Definition: ip.c:20
u32 udpc_connection_listen(u32 session_index, transport_endpoint_t *lcl)
Definition: udp.c:388
Definition: defs.h:47
static const transport_proto_vft_t udp_proto
Definition: udp.c:349
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.h:604
transport_connection_t connection
must be first
Definition: udp.h:48
clib_spinlock_t rx_lock
rx fifo lock
Definition: udp.h:49
bool udp_is_valid_dst_port(udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:532
void udp_session_close(u32 connection_index, u32 thread_index)
Definition: udp.c:184
VLIB buffer representation.
Definition: buffer.h:102
connectionless service
u8 * format_udp_half_open_session(u8 *s, va_list *args)
Definition: udp.c:257
u8 * format_udp_connection_id(u8 *s, va_list *args)
Definition: udp.c:208
#define vnet_buffer(b)
Definition: buffer.h:408
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
transport_connection_t * udp_session_get(u32 connection_index, u32 thread_index)
Definition: udp.c:174
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static u32 vlib_num_workers()
Definition: threads.h:372
#define vec_foreach(var, vec)
Vector iterator.
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
Definition: udp_local.c:471
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
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u32 udp_send_space(transport_connection_t *t)
Definition: udp.c:283
udp_connection_t ** connections
Definition: udp.h:147
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:95
static void * vlib_buffer_push_ip4(vlib_main_t *vm, vlib_buffer_t *b, ip4_address_t *src, ip4_address_t *dst, int proto, u8 csum_offload)
Push IPv4 header to buffer.
Definition: ip4.h:378
#define VLIB_INITS(...)
Definition: init.h:344
Definition: udp.h:125
Definition: defs.h:46
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
u8 * format_udp_listener_session(u8 *s, va_list *args)
Definition: udp.c:266