FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
udp_local.c
Go to the documentation of this file.
1 /*
2  * node.c: udp packet processing
3  *
4  * Copyright (c) 2013-2019 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/pg/pg.h>
20 #include <vnet/udp/udp.h>
21 #include <vnet/udp/udp_packet.h>
22 #include <vppinfra/sparse_vec.h>
23 
24 typedef enum
25 {
31 
32 typedef struct
33 {
38 
39 #define UDP_NO_NODE_SET ((u16) ~0)
40 
41 #ifndef CLIB_MARCH_VARIANT
42 u8 *
43 format_udp_rx_trace (u8 * s, va_list * args)
44 {
45  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
46  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
47  udp_local_rx_trace_t *t = va_arg (*args, udp_local_rx_trace_t *);
48 
49  s = format (s, "UDP: src-port %d dst-port %d%s",
50  clib_net_to_host_u16 (t->src_port),
51  clib_net_to_host_u16 (t->dst_port),
52  t->bound ? "" : " (no listener)");
53  return s;
54 }
55 #endif /* CLIB_MARCH_VARIANT */
56 
60  vlib_frame_t * from_frame, int is_ip4)
61 {
62  udp_main_t *um = &udp_main;
63  __attribute__ ((unused)) u32 n_left_from, next_index, *from, *to_next;
64  u8 punt_unknown = is_ip4 ? um->punt_unknown4 : um->punt_unknown6;
65  u16 *next_by_dst_port = (is_ip4 ?
67  from = vlib_frame_vector_args (from_frame);
68  n_left_from = from_frame->n_vectors;
69 
70  next_index = node->cached_next_index;
71 
72  while (n_left_from > 0)
73  {
74  u32 n_left_to_next;
75 
76  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
77 
78  while (n_left_from >= 4 && n_left_to_next >= 2)
79  {
80  u32 bi0, bi1;
81  vlib_buffer_t *b0, *b1;
82  udp_header_t *h0 = 0, *h1 = 0;
83  u32 i0, i1, dst_port0, dst_port1;
84  u32 advance0, advance1;
85  u32 error0, next0, error1, next1;
86 
87  /* Prefetch next iteration. */
88  {
89  vlib_buffer_t *p2, *p3;
90 
91  p2 = vlib_get_buffer (vm, from[2]);
92  p3 = vlib_get_buffer (vm, from[3]);
93 
94  vlib_prefetch_buffer_header (p2, LOAD);
95  vlib_prefetch_buffer_header (p3, LOAD);
96 
97  CLIB_PREFETCH (p2->data, sizeof (h0[0]), LOAD);
98  CLIB_PREFETCH (p3->data, sizeof (h1[0]), LOAD);
99  }
100 
101  bi0 = from[0];
102  bi1 = from[1];
103  to_next[0] = bi0;
104  to_next[1] = bi1;
105  from += 2;
106  to_next += 2;
107  n_left_to_next -= 2;
108  n_left_from -= 2;
109 
110  b0 = vlib_get_buffer (vm, bi0);
111  b1 = vlib_get_buffer (vm, bi1);
112 
113  /* ip4/6_local hands us the ip header, not the udp header */
114  if (is_ip4)
115  {
116  advance0 = sizeof (ip4_header_t);
117  advance1 = sizeof (ip4_header_t);
118  }
119  else
120  {
121  advance0 = sizeof (ip6_header_t);
122  advance1 = sizeof (ip6_header_t);
123  }
124 
125  if (PREDICT_FALSE (b0->current_length < advance0 + sizeof (*h0)))
126  {
127  error0 = UDP_ERROR_LENGTH_ERROR;
128  next0 = UDP_LOCAL_NEXT_DROP;
129  }
130  else
131  {
132  vlib_buffer_advance (b0, advance0);
133  h0 = vlib_buffer_get_current (b0);
134  error0 = UDP_ERROR_NONE;
135  next0 = UDP_LOCAL_NEXT_PUNT;
136  if (PREDICT_FALSE (clib_net_to_host_u16 (h0->length) >
137  vlib_buffer_length_in_chain (vm, b0)))
138  {
139  error0 = UDP_ERROR_LENGTH_ERROR;
140  next0 = UDP_LOCAL_NEXT_DROP;
141  }
142  }
143 
144  if (PREDICT_FALSE (b1->current_length < advance1 + sizeof (*h1)))
145  {
146  error1 = UDP_ERROR_LENGTH_ERROR;
147  next1 = UDP_LOCAL_NEXT_DROP;
148  }
149  else
150  {
151  vlib_buffer_advance (b1, advance1);
152  h1 = vlib_buffer_get_current (b1);
153  error1 = UDP_ERROR_NONE;
154  next1 = UDP_LOCAL_NEXT_PUNT;
155  if (PREDICT_FALSE (clib_net_to_host_u16 (h1->length) >
156  vlib_buffer_length_in_chain (vm, b1)))
157  {
158  error1 = UDP_ERROR_LENGTH_ERROR;
159  next1 = UDP_LOCAL_NEXT_DROP;
160  }
161  }
162 
163  /* Index sparse array with network byte order. */
164  dst_port0 = (error0 == 0) ? h0->dst_port : 0;
165  dst_port1 = (error1 == 0) ? h1->dst_port : 0;
166  sparse_vec_index2 (next_by_dst_port, dst_port0, dst_port1, &i0,
167  &i1);
168  next0 = (error0 == 0) ? vec_elt (next_by_dst_port, i0) : next0;
169  next1 = (error1 == 0) ? vec_elt (next_by_dst_port, i1) : next1;
170 
172  next0 == UDP_NO_NODE_SET))
173  {
174  // move the pointer back so icmp-error can find the
175  // ip packet header
176  vlib_buffer_advance (b0, -(word) advance0);
177 
178  if (PREDICT_FALSE (punt_unknown))
179  {
180  b0->error = node->errors[UDP_ERROR_PUNT];
181  next0 = UDP_LOCAL_NEXT_PUNT;
182  }
183  else if (is_ip4)
184  {
186  ICMP4_destination_unreachable,
187  ICMP4_destination_unreachable_port_unreachable,
188  0);
189  b0->error = node->errors[UDP_ERROR_NO_LISTENER];
190  next0 = UDP_LOCAL_NEXT_ICMP;
191  }
192  else
193  {
195  ICMP6_destination_unreachable,
196  ICMP6_destination_unreachable_port_unreachable,
197  0);
198  b0->error = node->errors[UDP_ERROR_NO_LISTENER];
199  next0 = UDP_LOCAL_NEXT_ICMP;
200  }
201  }
202  else
203  {
204  b0->error = node->errors[UDP_ERROR_NONE];
205  // advance to the payload
206  vlib_buffer_advance (b0, sizeof (*h0));
207  }
208 
210  next1 == UDP_NO_NODE_SET))
211  {
212  // move the pointer back so icmp-error can find the
213  // ip packet header
214  vlib_buffer_advance (b1, -(word) advance1);
215 
216  if (PREDICT_FALSE (punt_unknown))
217  {
218  b1->error = node->errors[UDP_ERROR_PUNT];
219  next1 = UDP_LOCAL_NEXT_PUNT;
220  }
221  else if (is_ip4)
222  {
224  ICMP4_destination_unreachable,
225  ICMP4_destination_unreachable_port_unreachable,
226  0);
227  b1->error = node->errors[UDP_ERROR_NO_LISTENER];
228  next1 = UDP_LOCAL_NEXT_ICMP;
229  }
230  else
231  {
233  ICMP6_destination_unreachable,
234  ICMP6_destination_unreachable_port_unreachable,
235  0);
236  b1->error = node->errors[UDP_ERROR_NO_LISTENER];
237  next1 = UDP_LOCAL_NEXT_ICMP;
238  }
239  }
240  else
241  {
242  b1->error = node->errors[UDP_ERROR_NONE];
243  // advance to the payload
244  vlib_buffer_advance (b1, sizeof (*h1));
245  }
246 
247  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
248  {
249  udp_local_rx_trace_t *tr = vlib_add_trace (vm, node,
250  b0, sizeof (*tr));
251  if (b0->error != node->errors[UDP_ERROR_LENGTH_ERROR])
252  {
253  tr->src_port = h0 ? h0->src_port : 0;
254  tr->dst_port = h0 ? h0->dst_port : 0;
255  tr->bound = (next0 != UDP_LOCAL_NEXT_ICMP);
256  }
257  }
258  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
259  {
260  udp_local_rx_trace_t *tr = vlib_add_trace (vm, node,
261  b1, sizeof (*tr));
262  if (b1->error != node->errors[UDP_ERROR_LENGTH_ERROR])
263  {
264  tr->src_port = h1 ? h1->src_port : 0;
265  tr->dst_port = h1 ? h1->dst_port : 0;
266  tr->bound = (next1 != UDP_LOCAL_NEXT_ICMP);
267  }
268  }
269 
270  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
271  to_next, n_left_to_next,
272  bi0, bi1, next0, next1);
273  }
274 
275  while (n_left_from > 0 && n_left_to_next > 0)
276  {
277  u32 bi0;
278  vlib_buffer_t *b0;
279  udp_header_t *h0 = 0;
280  u32 i0, next0;
281  u32 advance0;
282 
283  bi0 = from[0];
284  to_next[0] = bi0;
285  from += 1;
286  to_next += 1;
287  n_left_from -= 1;
288  n_left_to_next -= 1;
289 
290  b0 = vlib_get_buffer (vm, bi0);
291 
292  /* ip4/6_local hands us the ip header, not the udp header */
293  if (is_ip4)
294  advance0 = sizeof (ip4_header_t);
295  else
296  advance0 = sizeof (ip6_header_t);
297 
298  if (PREDICT_FALSE (b0->current_length < advance0 + sizeof (*h0)))
299  {
300  b0->error = node->errors[UDP_ERROR_LENGTH_ERROR];
301  next0 = UDP_LOCAL_NEXT_DROP;
302  goto trace_x1;
303  }
304 
305  vlib_buffer_advance (b0, advance0);
306 
307  h0 = vlib_buffer_get_current (b0);
308 
309  if (PREDICT_TRUE (clib_net_to_host_u16 (h0->length) <=
310  vlib_buffer_length_in_chain (vm, b0)))
311  {
312  i0 = sparse_vec_index (next_by_dst_port, h0->dst_port);
313  next0 = vec_elt (next_by_dst_port, i0);
314 
316  next0 == UDP_NO_NODE_SET))
317  {
318  // move the pointer back so icmp-error can find the
319  // ip packet header
320  vlib_buffer_advance (b0, -(word) advance0);
321 
322  if (PREDICT_FALSE (punt_unknown))
323  {
324  b0->error = node->errors[UDP_ERROR_PUNT];
325  next0 = UDP_LOCAL_NEXT_PUNT;
326  }
327  else if (is_ip4)
328  {
330  ICMP4_destination_unreachable,
331  ICMP4_destination_unreachable_port_unreachable,
332  0);
333  b0->error = node->errors[UDP_ERROR_NO_LISTENER];
334  next0 = UDP_LOCAL_NEXT_ICMP;
335  }
336  else
337  {
339  ICMP6_destination_unreachable,
340  ICMP6_destination_unreachable_port_unreachable,
341  0);
342  b0->error = node->errors[UDP_ERROR_NO_LISTENER];
343  next0 = UDP_LOCAL_NEXT_ICMP;
344  }
345  }
346  else
347  {
348  b0->error = node->errors[UDP_ERROR_NONE];
349  // advance to the payload
350  vlib_buffer_advance (b0, sizeof (*h0));
351  }
352  }
353  else
354  {
355  b0->error = node->errors[UDP_ERROR_LENGTH_ERROR];
356  next0 = UDP_LOCAL_NEXT_DROP;
357  }
358 
359  trace_x1:
360  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
361  {
362  udp_local_rx_trace_t *tr = vlib_add_trace (vm, node,
363  b0, sizeof (*tr));
364  if (b0->error != node->errors[UDP_ERROR_LENGTH_ERROR])
365  {
366  tr->src_port = h0->src_port;
367  tr->dst_port = h0->dst_port;
368  tr->bound = (next0 != UDP_LOCAL_NEXT_ICMP);
369  }
370  }
371 
372  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
373  to_next, n_left_to_next,
374  bi0, next0);
375  }
376 
377  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
378  }
379  return from_frame->n_vectors;
380 }
381 
382 static char *udp_error_strings[] = {
383 #define udp_error(n,s) s,
384 #include "udp_error.def"
385 #undef udp_error
386 };
387 
390  vlib_frame_t * from_frame)
391 {
392  return udp46_local_inline (vm, node, from_frame, 1 /* is_ip4 */ );
393 }
394 
397  vlib_frame_t * from_frame)
398 {
399  return udp46_local_inline (vm, node, from_frame, 0 /* is_ip4 */ );
400 }
401 
402 /* *INDENT-OFF* */
404  .name = "ip4-udp-lookup",
405  /* Takes a vector of packets. */
406  .vector_size = sizeof (u32),
407 
408  .n_errors = UDP_N_ERROR,
409  .error_strings = udp_error_strings,
410 
411  .n_next_nodes = UDP_LOCAL_N_NEXT,
412  .next_nodes = {
413  [UDP_LOCAL_NEXT_PUNT]= "ip4-punt",
414  [UDP_LOCAL_NEXT_DROP]= "ip4-drop",
415  [UDP_LOCAL_NEXT_ICMP]= "ip4-icmp-error",
416  },
417 
418  .format_buffer = format_udp_header,
419  .format_trace = format_udp_rx_trace,
420  .unformat_buffer = unformat_udp_header,
421 };
422 /* *INDENT-ON* */
423 
424 /* *INDENT-OFF* */
426  .name = "ip6-udp-lookup",
427  /* Takes a vector of packets. */
428  .vector_size = sizeof (u32),
429 
430  .n_errors = UDP_N_ERROR,
431  .error_strings = udp_error_strings,
432 
433  .n_next_nodes = UDP_LOCAL_N_NEXT,
434  .next_nodes = {
435  [UDP_LOCAL_NEXT_PUNT]= "ip6-punt",
436  [UDP_LOCAL_NEXT_DROP]= "ip6-drop",
437  [UDP_LOCAL_NEXT_ICMP]= "ip6-icmp-error",
438  },
439 
440  .format_buffer = format_udp_header,
441  .format_trace = format_udp_rx_trace,
442  .unformat_buffer = unformat_udp_header,
443 };
444 /* *INDENT-ON* */
445 
446 #ifndef CLIB_MARCH_VARIANT
447 void
449  char *dst_port_name, u8 is_ip4)
450 {
452  u32 i;
453 
454  vec_add2 (um->dst_port_infos[is_ip4], pi, 1);
455  i = pi - um->dst_port_infos[is_ip4];
456 
457  pi->name = dst_port_name;
458  pi->dst_port = dst_port;
459  pi->next_index = pi->node_index = ~0;
460 
461  hash_set (um->dst_port_info_by_dst_port[is_ip4], dst_port, i);
462 
463  if (pi->name)
464  hash_set_mem (um->dst_port_info_by_name[is_ip4], pi->name, i);
465 }
466 
467 void
469  udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
470 {
471  udp_main_t *um = &udp_main;
473  u16 *n;
474 
475  {
477  if (error)
478  clib_error_report (error);
479  }
480 
481  pi = udp_get_dst_port_info (um, dst_port, is_ip4);
482  if (!pi)
483  {
484  udp_add_dst_port (um, dst_port, 0, is_ip4);
485  pi = udp_get_dst_port_info (um, dst_port, is_ip4);
486  ASSERT (pi);
487  }
488 
489  pi->node_index = node_index;
490  pi->next_index = vlib_node_add_next (vm,
491  is_ip4 ? udp4_local_node.index
492  : udp6_local_node.index, node_index);
493 
494  /* Setup udp protocol -> next index sparse vector mapping. */
495  if (is_ip4)
497  clib_host_to_net_u16 (dst_port));
498  else
500  clib_host_to_net_u16 (dst_port));
501 
502  n[0] = pi->next_index;
503 }
504 
505 void
507 {
508  udp_main_t *um = &udp_main;
510  u16 *n;
511 
512  pi = udp_get_dst_port_info (um, dst_port, is_ip4);
513  /* Not registered? Fagedaboudit */
514  if (!pi)
515  return;
516 
517  /* Kill the mapping. Don't bother killing the pi, it may be back. */
518  if (is_ip4)
520  clib_host_to_net_u16 (dst_port));
521  else
523  clib_host_to_net_u16 (dst_port));
524 
525  n[0] = UDP_NO_NODE_SET;
526 }
527 
528 bool
530 {
531  udp_main_t *um = &udp_main;
532  u16 *n;
533 
534  if (is_ip4)
536  clib_host_to_net_u16 (dst_port));
537  else
539  clib_host_to_net_u16 (dst_port));
540 
541  return (n[0] != SPARSE_VEC_INVALID_INDEX && n[0] != UDP_NO_NODE_SET);
542 }
543 
544 void
545 udp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add)
546 {
547  udp_main_t *um = &udp_main;
548  {
550  if (error)
551  clib_error_report (error);
552  }
553 
554  if (is_ip4)
555  um->punt_unknown4 = is_add;
556  else
557  um->punt_unknown6 = is_add;
558 }
559 
560 /* Parse a UDP header. */
561 uword
562 unformat_udp_header (unformat_input_t * input, va_list * args)
563 {
564  u8 **result = va_arg (*args, u8 **);
565  udp_header_t *udp;
566  __attribute__ ((unused)) int old_length;
568 
569  /* Allocate space for IP header. */
570  {
571  void *p;
572 
573  old_length = vec_len (*result);
574  vec_add2 (*result, p, sizeof (ip4_header_t));
575  udp = p;
576  }
577 
578  clib_memset (udp, 0, sizeof (udp[0]));
579  if (unformat (input, "src-port %d dst-port %d", &src_port, &dst_port))
580  {
581  udp->src_port = clib_host_to_net_u16 (src_port);
582  udp->dst_port = clib_host_to_net_u16 (dst_port);
583  return 1;
584  }
585  return 0;
586 }
587 
588 static void
589 udp_setup_node (vlib_main_t * vm, u32 node_index)
590 {
591  vlib_node_t *n = vlib_get_node (vm, node_index);
592  pg_node_t *pn = pg_get_node (node_index);
593 
597 }
598 
599 clib_error_t *
601 {
602  udp_main_t *um = &udp_main;
603  int i;
604 
605  {
606  clib_error_t *error;
607  error = vlib_call_init_function (vm, udp_init);
608  if (error)
609  clib_error_report (error);
610  }
611 
612 
613  for (i = 0; i < 2; i++)
614  {
615  um->dst_port_info_by_name[i] = hash_create_string (0, sizeof (uword));
616  um->dst_port_info_by_dst_port[i] = hash_create (0, sizeof (uword));
617  }
618 
619  udp_setup_node (vm, udp4_local_node.index);
620  udp_setup_node (vm, udp6_local_node.index);
621 
622  um->punt_unknown4 = 0;
623  um->punt_unknown6 = 0;
624 
626  ( /* elt bytes */ sizeof (um->next_by_dst_port4[0]),
627  /* bits in index */ BITS (((udp_header_t *) 0)->dst_port));
628 
630  ( /* elt bytes */ sizeof (um->next_by_dst_port6[0]),
631  /* bits in index */ BITS (((udp_header_t *) 0)->dst_port));
632 
633 #define _(n,s) udp_add_dst_port (um, UDP_DST_PORT_##s, #s, 1 /* is_ip4 */);
635 #undef _
636 #define _(n,s) udp_add_dst_port (um, UDP_DST_PORT_##s, #s, 0 /* is_ip4 */);
638 #undef _
639  ip4_register_protocol (IP_PROTOCOL_UDP, udp4_local_node.index);
640  /* Note: ip6 differs from ip4, UDP is hotwired to ip6-udp-lookup */
641  return 0;
642 }
643 
645 #endif /* CLIB_MARCH_VARIANT */
646 
647 /*
648  * fd.io coding-style-patch-verification: ON
649  *
650  * Local Variables:
651  * eval: (c-set-style "gnu")
652  * End:
653  */
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:506
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:22
bool udp_is_valid_dst_port(udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:529
#define hash_set(h, key, value)
Definition: hash.h:255
#define CLIB_UNUSED(x)
Definition: clib.h:86
u16 * next_by_dst_port6
Definition: udp.h:160
format_function_t format_udp_header
Definition: format.h:100
clib_error_t * udp_local_init(vlib_main_t *vm)
Definition: udp_local.c:600
static char * udp_error_strings[]
Definition: udp_local.c:382
#define UDP_NO_NODE_SET
Definition: udp_local.c:39
#define PREDICT_TRUE(x)
Definition: clib.h:119
uword * dst_port_info_by_dst_port[N_UDP_AF]
Definition: udp.h:155
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static clib_error_t * udp_init(vlib_main_t *vm)
Definition: udp.c:467
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
udp_local_next_t
Definition: udp_local.c:24
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:628
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:468
#define hash_set_mem(h, key, value)
Definition: hash.h:275
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:275
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:202
u8 punt_unknown6
Definition: udp.h:162
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1933
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:472
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:402
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1092
unsigned char u8
Definition: types.h:56
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:366
u16 src_port
Definition: udp.api:41
i64 word
Definition: types.h:111
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
vlib_node_registration_t udp6_local_node
(constructor) VLIB_REGISTER_NODE (udp6_local_node)
Definition: udp_local.c:425
u8 punt_unknown4
Definition: udp.h:161
#define sparse_vec_validate(v, i)
Definition: sparse_vec.h:231
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
unsigned int u32
Definition: types.h:88
static void sparse_vec_index2(void *v, u32 si0, u32 si1, u32 *i0_return, u32 *i1_return)
Definition: sparse_vec.h:169
#define vlib_call_init_function(vm, x)
Definition: init.h:270
#define hash_create_string(elts, value_bytes)
Definition: hash.h:690
void icmp6_error_set_vnet_buffer(vlib_buffer_t *b, u8 type, u8 code, u32 data)
Definition: icmp6.c:446
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
u16 * next_by_dst_port4
Definition: udp.h:159
udp_dst_port_info_t * dst_port_infos[N_UDP_AF]
Definition: udp.h:151
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
static uword udp46_local_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
Definition: udp_local.c:58
uword * dst_port_info_by_name[N_UDP_AF]
Definition: udp.h:154
#define PREDICT_FALSE(x)
Definition: clib.h:118
#define always_inline
Definition: ipsec.h:28
format_function_t * format_buffer
Definition: node.h:360
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:224
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:338
vlib_main_t * vm
Definition: in2out_ed.c:1599
static void udp_setup_node(vlib_main_t *vm, u32 node_index)
Definition: udp_local.c:589
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:399
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
u8 data[]
Packet data.
Definition: buffer.h:181
unformat_function_t unformat_pg_udp_header
Definition: format.h:102
unformat_function_t * unformat_buffer
Definition: node.h:361
unformat_function_t * unformat_edit
Definition: pg.h:318
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:483
void udp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: udp_local.c:545
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
udp_dst_port_t
Definition: udp.h:107
vlib_node_registration_t udp4_local_node
(constructor) VLIB_REGISTER_NODE (udp4_local_node)
Definition: udp_local.c:403
#define hash_create(elts, value_bytes)
Definition: hash.h:696
static uword sparse_vec_index(void *v, uword sparse_index)
Definition: sparse_vec.h:161
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:517
#define foreach_udp4_dst_port
Definition: udp.h:70
#define ASSERT(truth)
udp_dst_port_t dst_port
Definition: udp.h:127
char * name
Definition: udp.h:124
#define clib_error_report(e)
Definition: error.h:113
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
#define vec_elt(v, i)
Get vector value at index i.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
uword unformat_udp_header(unformat_input_t *input, va_list *args)
Definition: udp_local.c:562
u8 * format_udp_rx_trace(u8 *s, va_list *args)
Definition: udp_local.c:43
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:59
u16 dst_port
Definition: udp.api:42
static void * sparse_vec_new(uword elt_bytes, uword sparse_index_bits)
Definition: sparse_vec.h:71
#define BITS(x)
Definition: clib.h:65
static_always_inline void icmp4_error_set_vnet_buffer(vlib_buffer_t *b, u8 type, u8 code, u32 data)
Definition: icmp4.h:51
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
Definition: pg.h:315
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
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
#define SPARSE_VEC_INVALID_INDEX
Definition: sparse_vec.h:68