FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
icmp4.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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  * ip/icmp4.c: ipv4 icmp
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vlib/vlib.h>
41 #include <vnet/ip/ip.h>
42 #include <vnet/pg/pg.h>
43 #include <vnet/ip/ip_sas.h>
44 
45 static char *icmp_error_strings[] = {
46 #define _(f,s) s,
48 #undef _
49 };
50 
51 static u8 *
52 format_ip4_icmp_type_and_code (u8 * s, va_list * args)
53 {
54  icmp4_type_t type = va_arg (*args, int);
55  u8 code = va_arg (*args, int);
56  char *t = 0;
57 
58 #define _(n,f) case n: t = #f; break;
59 
60  switch (type)
61  {
63 
64  default:
65  break;
66  }
67 
68 #undef _
69 
70  if (!t)
71  return format (s, "unknown 0x%x", type);
72 
73  s = format (s, "%s", t);
74 
75  t = 0;
76  switch ((type << 8) | code)
77  {
78 #define _(a,n,f) case (ICMP4_##a << 8) | (n): t = #f; break;
79 
81 
82 #undef _
83  }
84 
85  if (t)
86  s = format (s, " %s", t);
87 
88  return s;
89 }
90 
91 static u8 *
92 format_ip4_icmp_header (u8 * s, va_list * args)
93 {
94  icmp46_header_t *icmp = va_arg (*args, icmp46_header_t *);
95  u32 max_header_bytes = va_arg (*args, u32);
96 
97  /* Nothing to do. */
98  if (max_header_bytes < sizeof (icmp[0]))
99  return format (s, "ICMP header truncated");
100 
101  s = format (s, "ICMP %U checksum 0x%x",
103  clib_net_to_host_u16 (icmp->checksum));
104 
105  if ((ICMP4_echo_request == icmp->type || ICMP4_echo_reply == icmp->type)
106  && sizeof (icmp[0]) + sizeof (u16) < max_header_bytes)
107  {
108  s = format (s, " id %u", clib_net_to_host_u16 (*(u16 *) (icmp + 1)));
109  }
110 
111  return s;
112 }
113 
114 static u8 *
115 format_icmp_input_trace (u8 * s, va_list * va)
116 {
117  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
118  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
119  icmp_input_trace_t *t = va_arg (*va, icmp_input_trace_t *);
120 
121  s = format (s, "%U",
122  format_ip4_header, t->packet_data, sizeof (t->packet_data));
123 
124  return s;
125 }
126 
127 typedef enum
128 {
132 
133 typedef struct
134 {
136 
138 
139  /* Vector dispatch table indexed by [icmp type]. */
140  u8 ip4_input_next_index_by_type[256];
141 } icmp4_main_t;
142 
144 
145 static uword
148 {
150  uword n_packets = frame->n_vectors;
151  u32 *from, *to_next;
152  u32 n_left_from, n_left_to_next, next;
153 
155  n_left_from = n_packets;
156  next = node->cached_next_index;
157 
158  if (node->flags & VLIB_NODE_FLAG_TRACE)
160  /* stride */ 1,
161  sizeof (icmp_input_trace_t));
162 
163  while (n_left_from > 0)
164  {
165  vlib_get_next_frame (vm, node, next, to_next, n_left_to_next);
166 
167  while (n_left_from > 0 && n_left_to_next > 0)
168  {
169  vlib_buffer_t *p0;
170  ip4_header_t *ip0;
171  icmp46_header_t *icmp0;
172  icmp4_type_t type0;
173  u32 bi0, next0;
174 
175  if (PREDICT_TRUE (n_left_from > 2))
176  {
178  p0 = vlib_get_buffer (vm, from[1]);
179  ip0 = vlib_buffer_get_current (p0);
180  clib_prefetch_load (ip0);
181  }
182 
183  bi0 = to_next[0] = from[0];
184 
185  from += 1;
186  n_left_from -= 1;
187  to_next += 1;
188  n_left_to_next -= 1;
189 
190  p0 = vlib_get_buffer (vm, bi0);
191  ip0 = vlib_buffer_get_current (p0);
192  icmp0 = ip4_next_header (ip0);
193  type0 = icmp0->type;
194  next0 = im->ip4_input_next_index_by_type[type0];
195 
196  p0->error = node->errors[ICMP4_ERROR_UNKNOWN_TYPE];
197 
198  /* Verify speculative enqueue, maybe switch current next frame */
200  n_left_to_next, bi0, next0);
201  }
202 
203  vlib_put_next_frame (vm, node, next, n_left_to_next);
204  }
205 
206  return frame->n_vectors;
207 }
208 
209 /* *INDENT-OFF* */
211  .function = ip4_icmp_input,
212  .name = "ip4-icmp-input",
213 
214  .vector_size = sizeof (u32),
215 
216  .format_trace = format_icmp_input_trace,
217 
218  .n_errors = ARRAY_LEN (icmp_error_strings),
219  .error_strings = icmp_error_strings,
220 
221  .n_next_nodes = 1,
222  .next_nodes = {
223  [ICMP_INPUT_NEXT_ERROR] = "ip4-punt",
224  },
225 };
226 /* *INDENT-ON* */
227 
228 typedef enum
229 {
234 
235 static u8
237 {
238  switch (type)
239  {
240  case ICMP4_destination_unreachable:
241  return ICMP4_ERROR_DEST_UNREACH_SENT;
242  case ICMP4_time_exceeded:
243  return ICMP4_ERROR_TTL_EXPIRE_SENT;
244  case ICMP4_parameter_problem:
245  return ICMP4_ERROR_PARAM_PROBLEM_SENT;
246  default:
247  return ICMP4_ERROR_DROP;
248  }
249 }
250 
251 static uword
254 {
255  u32 *from, *to_next;
256  uword n_left_from, n_left_to_next;
258 
260  n_left_from = frame->n_vectors;
261  next_index = node->cached_next_index;
262 
263  if (node->flags & VLIB_NODE_FLAG_TRACE)
265  /* stride */ 1,
266  sizeof (icmp_input_trace_t));
267 
268  while (n_left_from > 0)
269  {
270  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
271 
272  while (n_left_from > 0 && n_left_to_next > 0)
273  {
274  /*
275  * Duplicate first buffer and free the original chain. Keep
276  * as much of the original packet as possible, within the
277  * minimum MTU. We chat "a little" here by keeping whatever
278  * is available in the first buffer.
279  */
280 
281  u32 pi0 = ~0;
282  u32 org_pi0 = from[0];
284  u8 error0 = ICMP4_ERROR_NONE;
285  vlib_buffer_t *p0, *org_p0;
286  ip4_header_t *ip0, *out_ip0;
287  icmp46_header_t *icmp0;
288  u32 sw_if_index0;
289  ip_csum_t sum;
290 
291  org_p0 = vlib_get_buffer (vm, org_pi0);
292  p0 = vlib_buffer_copy_no_chain (vm, org_p0, &pi0);
293  if (!p0 || pi0 == ~0) /* Out of buffers */
294  continue;
295 
296  /* Speculatively enqueue p0 to the current next frame */
297  to_next[0] = pi0;
298  from += 1;
299  to_next += 1;
300  n_left_from -= 1;
301  n_left_to_next -= 1;
302 
303  ip0 = vlib_buffer_get_current (p0);
304  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
305 
306  /* Add IP header and ICMPv4 header including a 4 byte data field */
308  -sizeof (ip4_header_t) -
309  sizeof (icmp46_header_t) - 4);
310 
311  p0->current_length =
312  p0->current_length > 576 ? 576 : p0->current_length;
313  out_ip0 = vlib_buffer_get_current (p0);
314  icmp0 = (icmp46_header_t *) & out_ip0[1];
315 
316  /* Fill ip header fields */
317  out_ip0->ip_version_and_header_length = 0x45;
318  out_ip0->tos = 0;
319  out_ip0->length = clib_host_to_net_u16 (p0->current_length);
320  out_ip0->fragment_id = 0;
321  out_ip0->flags_and_fragment_offset = 0;
322  out_ip0->ttl = 0xff;
323  out_ip0->protocol = IP_PROTOCOL_ICMP;
324  out_ip0->dst_address = ip0->src_address;
325  /* Prefer a source address from "offending interface" */
326  if (!ip4_sas_by_sw_if_index (sw_if_index0, &out_ip0->dst_address,
327  &out_ip0->src_address))
328  { /* interface has no IP6 address - should not happen */
329  next0 = IP4_ICMP_ERROR_NEXT_DROP;
330  error0 = ICMP4_ERROR_DROP;
331  }
332 
333  out_ip0->checksum = ip4_header_checksum (out_ip0);
334 
335  /* Fill icmp header fields */
336  icmp0->type = vnet_buffer (p0)->ip.icmp.type;
337  icmp0->code = vnet_buffer (p0)->ip.icmp.code;
338  *((u32 *) (icmp0 + 1)) =
339  clib_host_to_net_u32 (vnet_buffer (p0)->ip.icmp.data);
340  icmp0->checksum = 0;
341  sum =
342  ip_incremental_checksum (0, icmp0,
343  p0->current_length -
344  sizeof (ip4_header_t));
345  icmp0->checksum = ~ip_csum_fold (sum);
346 
347  /* Update error status */
348  if (error0 == ICMP4_ERROR_NONE)
349  error0 = icmp4_icmp_type_to_error (icmp0->type);
350 
351  vlib_error_count (vm, node->node_index, error0, 1);
352 
353  /* Verify speculative enqueue, maybe switch current next frame */
355  to_next, n_left_to_next,
356  pi0, next0);
357  }
358  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
359  }
360 
361  /*
362  * push the original buffers to error-drop, so that
363  * they can get the error counters handled, then freed
364  */
368  frame->n_vectors);
369 
370  return frame->n_vectors;
371 }
372 
373 /* *INDENT-OFF* */
375  .function = ip4_icmp_error,
376  .name = "ip4-icmp-error",
377  .vector_size = sizeof (u32),
378 
379  .n_errors = ARRAY_LEN (icmp_error_strings),
380  .error_strings = icmp_error_strings,
381 
382  .n_next_nodes = IP4_ICMP_ERROR_N_NEXT,
383  .next_nodes = {
384  [IP4_ICMP_ERROR_NEXT_DROP] = "ip4-drop",
385  [IP4_ICMP_ERROR_NEXT_LOOKUP] = "ip4-lookup",
386  },
387 
388  .format_trace = format_icmp_input_trace,
389 };
390 /* *INDENT-ON* */
391 
392 
393 static uword
395 {
396  icmp46_header_t *h = va_arg (*args, icmp46_header_t *);
398  u32 i;
399 
401  cm->type_and_code_by_name, &i))
402  {
403  h->type = (i >> 8) & 0xff;
404  h->code = (i >> 0) & 0xff;
405  }
407  cm->type_by_name, &i))
408  {
409  h->type = i;
410  h->code = 0;
411  }
412  else
413  return 0;
414 
415  return 1;
416 }
417 
418 static void
420  pg_stream_t * s,
421  pg_edit_group_t * g, u32 * packets, u32 n_packets)
422 {
424  u32 ip_offset, icmp_offset;
425 
426  icmp_offset = g->start_byte_offset;
427  ip_offset = (g - 1)->start_byte_offset;
428 
429  while (n_packets >= 1)
430  {
431  vlib_buffer_t *p0;
432  ip4_header_t *ip0;
433  icmp46_header_t *icmp0;
434  u32 len0;
435 
436  p0 = vlib_get_buffer (vm, packets[0]);
437  n_packets -= 1;
438  packets += 1;
439 
440  ASSERT (p0->current_data == 0);
441  ip0 = (void *) (p0->data + ip_offset);
442  icmp0 = (void *) (p0->data + icmp_offset);
443 
444  /* if IP length has been specified, then calculate the length based on buffer */
445  if (ip0->length == 0)
446  len0 = vlib_buffer_length_in_chain (vm, p0) - icmp_offset;
447  else
448  len0 = clib_net_to_host_u16 (ip0->length) - icmp_offset;
449 
450  icmp0->checksum =
451  ~ip_csum_fold (ip_incremental_checksum (0, icmp0, len0));
452  }
453 }
454 
455 typedef struct
456 {
460 
461 always_inline void
463 {
464  /* Initialize fields that are not bit fields in the IP header. */
465 #define _(f) pg_edit_init (&p->f, icmp46_header_t, f);
466  _(type);
467  _(code);
468  _(checksum);
469 #undef _
470 }
471 
472 static uword
473 unformat_pg_icmp_header (unformat_input_t * input, va_list * args)
474 {
475  pg_stream_t *s = va_arg (*args, pg_stream_t *);
477  u32 group_index;
478 
479  p = pg_create_edit_group (s, sizeof (p[0]), sizeof (icmp46_header_t),
480  &group_index);
482 
484 
485  {
486  icmp46_header_t tmp;
487 
488  if (!unformat (input, "ICMP %U", unformat_icmp_type_and_code, &tmp))
489  goto error;
490 
491  pg_edit_set_fixed (&p->type, tmp.type);
492  pg_edit_set_fixed (&p->code, tmp.code);
493  }
494 
495  /* Parse options. */
496  while (1)
497  {
498  if (unformat (input, "checksum %U",
500  ;
501 
502  /* Can't parse input: try next protocol level. */
503  else
504  break;
505  }
506 
507  if (!unformat_user (input, unformat_pg_payload, s))
508  goto error;
509 
511  {
512  pg_edit_group_t *g = pg_stream_get_group (s, group_index);
514  g->edit_function_opaque = 0;
515  }
516 
517  return 1;
518 
519 error:
520  /* Free up any edits we may have added. */
521  pg_free_edit_group (s);
522  return 0;
523 }
524 
525 void
527 {
529  u32 old_next_index;
530 
531  ASSERT ((int) type < ARRAY_LEN (im->ip4_input_next_index_by_type));
532  old_next_index = im->ip4_input_next_index_by_type[type];
533 
534  im->ip4_input_next_index_by_type[type]
536 
537  if (old_next_index &&
538  (old_next_index != im->ip4_input_next_index_by_type[type]))
539  clib_warning ("WARNING: changed next_by_type[%d]", (int) type);
540 }
541 
542 static clib_error_t *
544 {
545  ip_main_t *im = &ip_main;
546  ip_protocol_info_t *pi;
549 
551 
552  if (error)
553  return error;
554 
555  pi = ip_get_protocol_info (im, IP_PROTOCOL_ICMP);
558 
559  cm->type_by_name = hash_create_string (0, sizeof (uword));
560 #define _(n,t) hash_set_mem (cm->type_by_name, #t, (n));
562 #undef _
563 
564  cm->type_and_code_by_name = hash_create_string (0, sizeof (uword));
565 #define _(a,n,t) hash_set_mem (cm->type_by_name, #t, (n) | (ICMP4_##a << 8));
567 #undef _
568 
569  clib_memset (cm->ip4_input_next_index_by_type,
571  sizeof (cm->ip4_input_next_index_by_type));
572 
573  return 0;
574 }
575 
577 
578 /*
579  * fd.io coding-style-patch-verification: ON
580  *
581  * Local Variables:
582  * eval: (c-set-style "gnu")
583  * End:
584  */
vlib.h
tmp
u32 * tmp
Definition: interface_output.c:1096
icmp_input_trace_t
Definition: icmp4.h:41
format_icmp_input_trace
static u8 * format_icmp_input_trace(u8 *s, va_list *va)
Definition: icmp4.c:115
im
vnet_interface_main_t * im
Definition: interface_output.c:415
pg_icmp46_header_t
Definition: icmp4.c:455
pg_edit_set_fixed
static void pg_edit_set_fixed(pg_edit_t *e, u64 value)
Definition: edit.h:153
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
pg_edit_group_t::start_byte_offset
u32 start_byte_offset
Definition: pg.h:69
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
vlib_node_add_next
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
pg_icmp46_header_t::checksum
pg_edit_t checksum
Definition: icmp4.c:458
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
pg.h
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
icmp4_main_t
Definition: icmp4.c:133
next
u16 * next
Definition: nat44_ei_out2in.c:718
vlib_trace_frame_buffers_only
void vlib_trace_frame_buffers_only(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, uword n_buffers, uword next_buffer_stride, uword n_buffer_data_bytes_in_trace)
Definition: trace.c:48
foreach_icmp4_error
@ foreach_icmp4_error
Definition: icmp4.h:37
ICMP_INPUT_NEXT_ERROR
@ ICMP_INPUT_NEXT_ERROR
Definition: icmp4.c:129
icmp4_main_t::type_by_name
uword * type_by_name
Definition: icmp4.c:137
PG_EDIT_UNSPECIFIED
@ PG_EDIT_UNSPECIFIED
Definition: edit.h:61
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
icmp_input_trace_t::packet_data
u8 packet_data[64]
Definition: icmp4.h:43
ip_main
ip_main_t ip_main
Definition: ip_init.c:42
ip_get_protocol_info
static ip_protocol_info_t * ip_get_protocol_info(ip_main_t *im, u32 protocol)
Definition: ip.h:134
hash_create_string
#define hash_create_string(elts, value_bytes)
Definition: hash.h:689
ip_protocol_info_t::format_header
format_function_t * format_header
Definition: ip.h:79
ip_sas.h
u16
unsigned short u16
Definition: types.h:57
vlib_call_init_function
#define vlib_call_init_function(vm, x)
Definition: init.h:259
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
format_ip4_icmp_header
static u8 * format_ip4_icmp_header(u8 *s, va_list *args)
Definition: icmp4.c:92
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
node_index
node node_index
Definition: interface_output.c:440
unformat_pg_number
uword unformat_pg_number(unformat_input_t *input, va_list *args)
Definition: edit.c:85
unformat_input_t
struct _unformat_input_t unformat_input_t
ip4_icmp_error_next_t
ip4_icmp_error_next_t
Definition: icmp4.c:228
vlib_error_count
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
Definition: error_funcs.h:57
vlib_frame_t
Definition: node.h:372
vlib_buffer_length_in_chain
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:433
ip4_header_t
Definition: ip4_packet.h:87
ip4_header_t::tos
ip_dscp_t tos
Definition: ip4_packet.h:96
h
h
Definition: flowhash_template.h:372
error
Definition: cJSON.c:88
ip4_header_t::length
u16 length
Definition: ip4_packet.h:99
ip4_icmp_register_type
void ip4_icmp_register_type(vlib_main_t *vm, icmp4_type_t type, u32 node_index)
Definition: icmp4.c:526
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
icmp4_pg_edit_function
static void icmp4_pg_edit_function(pg_main_t *pg, pg_stream_t *s, pg_edit_group_t *g, u32 *packets, u32 n_packets)
Definition: icmp4.c:419
vlib_buffer_t::current_data
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
Definition: buffer.h:119
ip4_sas_by_sw_if_index
bool ip4_sas_by_sw_if_index(u32 sw_if_index, const ip4_address_t *dst, ip4_address_t *src)
Definition: ip_sas.c:112
vlib_buffer_enqueue_to_single_next
static_always_inline void vlib_buffer_enqueue_to_single_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 next_index, u32 count)
Definition: buffer_node.h:373
pg_edit_group_t::edit_function_opaque
uword edit_function_opaque
Definition: pg.h:81
vlib_buffer_advance
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
pg_edit_group_t
Definition: pg.h:56
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
IP4_ICMP_ERROR_N_NEXT
@ IP4_ICMP_ERROR_N_NEXT
Definition: icmp4.c:232
IP4_ICMP_ERROR_NEXT_LOOKUP
@ IP4_ICMP_ERROR_NEXT_LOOKUP
Definition: icmp4.c:231
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
ip_incremental_checksum
static ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
Definition: ip_packet.h:319
ARRAY_LEN
#define ARRAY_LEN(x)
Definition: clib.h:70
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
pg_edit_t::type
pg_edit_type_t type
Definition: edit.h:66
vlib_prefetch_buffer_with_index
#define vlib_prefetch_buffer_with_index(vm, bi, type)
Prefetch buffer metadata by buffer index The first 64 bytes of buffer contains most header informatio...
Definition: buffer_funcs.h:507
uword
u64 uword
Definition: types.h:112
icmp4_icmp_type_to_error
static u8 icmp4_icmp_type_to_error(u8 type)
Definition: icmp4.c:236
cm
vnet_feature_config_main_t * cm
Definition: nat44_ei_hairpinning.c:594
ip4_header_t::checksum
u16 checksum
Definition: ip4_packet.h:118
pg_stream_get_group
static pg_edit_group_t * pg_stream_get_group(pg_stream_t *s, u32 group_index)
Definition: pg.h:233
pg_free_edit_group
static void pg_free_edit_group(pg_stream_t *s)
Definition: pg.h:292
ip_main_init
clib_error_t * ip_main_init(vlib_main_t *vm)
Definition: ip_init.c:45
vlib_buffer_copy_no_chain
static vlib_buffer_t * vlib_buffer_copy_no_chain(vlib_main_t *vm, vlib_buffer_t *b, u32 *di)
Definition: buffer_funcs.h:1137
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
ip4_header_t::dst_address
ip4_address_t dst_address
Definition: ip4_packet.h:125
unformat_pg_edit
uword unformat_pg_edit(unformat_input_t *input, va_list *args)
Definition: edit.c:106
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
ip4_header_t::fragment_id
u16 fragment_id
Definition: ip4_packet.h:102
unformat_pg_payload
uword unformat_pg_payload(unformat_input_t *input, va_list *args)
Definition: edit.c:127
vlib_validate_buffer_enqueue_x1
#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
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
ip4_header_t::src_address
ip4_address_t src_address
Definition: ip4_packet.h:125
icmp
icmp
Definition: map.api:387
icmp4_init
static clib_error_t * icmp4_init(vlib_main_t *vm)
Definition: icmp4.c:543
pg_main_t
Definition: pg.h:338
pg_icmp46_header_t::code
pg_edit_t code
Definition: icmp4.c:457
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
pg_create_edit_group
static void * pg_create_edit_group(pg_stream_t *s, int n_edit_bytes, int n_packet_bytes, u32 *group_index)
Definition: pg.h:239
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
ip.h
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
ip4_header_t::ttl
u8 ttl
Definition: ip4_packet.h:112
ip_protocol_info_t
Definition: ip.h:70
format_ip4_icmp_type_and_code
static u8 * format_ip4_icmp_type_and_code(u8 *s, va_list *args)
Definition: icmp4.c:52
clib_prefetch_load
static_always_inline void clib_prefetch_load(void *p)
Definition: cache.h:92
icmp4_main_t::type_and_code_by_name
uword * type_and_code_by_name
Definition: icmp4.c:135
ip4_header_t::flags_and_fragment_offset
u16 flags_and_fragment_offset
Definition: ip4_packet.h:106
pg_icmp_header_init
static void pg_icmp_header_init(pg_icmp46_header_t *p)
Definition: icmp4.c:462
format_ip4_header
format_function_t format_ip4_header
Definition: format.h:81
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
ip4_icmp_error
static uword ip4_icmp_error(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: icmp4.c:252
ip4_header_t::ip_version_and_header_length
u8 ip_version_and_header_length
Definition: ip4_packet.h:93
vlib_node_t
Definition: node.h:247
foreach_icmp4_code
@ foreach_icmp4_code
Definition: icmp46_packet.h:172
ip4_icmp_input_node
vlib_node_registration_t ip4_icmp_input_node
(constructor) VLIB_REGISTER_NODE (ip4_icmp_input_node)
Definition: icmp4.c:210
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
foreach_icmp4_type
@ foreach_icmp4_type
Definition: icmp46_packet.h:165
ip4_header_checksum
static u16 ip4_header_checksum(ip4_header_t *i)
Definition: ip4_packet.h:314
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
ip_csum_t
uword ip_csum_t
Definition: ip_packet.h:245
vlib_buffer_t::data
u8 data[]
Packet data.
Definition: buffer.h:204
unformat_pg_icmp_header
static uword unformat_pg_icmp_header(unformat_input_t *input, va_list *args)
Definition: icmp4.c:473
i
int i
Definition: flowhash_template.h:376
clib_warning
#define clib_warning(format, args...)
Definition: error.h:59
pg_edit_t
Definition: edit.h:64
icmp_input_next_t
icmp_input_next_t
Definition: icmp4.c:127
ICMP_INPUT_N_NEXT
@ ICMP_INPUT_N_NEXT
Definition: icmp4.c:130
pg_stream_t
Definition: pg.h:96
icmp4_main
icmp4_main_t icmp4_main
Definition: icmp4.c:143
icmp4_type_t
icmp4_type_t
Definition: icmp46_packet.h:162
ip_main_t
Definition: ip.h:107
vlib_node_runtime_t
Definition: node.h:454
pg_icmp46_header_t::type
pg_edit_t type
Definition: icmp4.c:457
from
from
Definition: nat44_ei_hairpinning.c:415
ip4_icmp_input
static uword ip4_icmp_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: icmp4.c:146
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
unformat_vlib_number_by_name
uword unformat_vlib_number_by_name(unformat_input_t *input, va_list *args)
Definition: format.c:157
pg_edit_group_t::edit_function
void(* edit_function)(struct pg_main_t *pg, struct pg_stream_t *s, struct pg_edit_group_t *g, u32 *buffers, u32 n_buffers)
Definition: pg.h:75
icmp_error_strings
static char * icmp_error_strings[]
Definition: icmp4.c:45
unformat_icmp_type_and_code
static uword unformat_icmp_type_and_code(unformat_input_t *input, va_list *args)
Definition: icmp4.c:394
vlib_get_next_frame
#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:395
ip_csum_fold
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:301
ip_protocol_info_t::unformat_pg_edit
unformat_function_t * unformat_pg_edit
Definition: ip.h:88
IP4_ICMP_ERROR_NEXT_DROP
@ IP4_ICMP_ERROR_NEXT_DROP
Definition: icmp4.c:230
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
ip4_header_t::protocol
u8 protocol
Definition: ip4_packet.h:115
ip4_next_header
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:196
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
packets
units packets
Definition: map.api:366
ip4_icmp_error_node
vlib_node_registration_t ip4_icmp_error_node
(constructor) VLIB_REGISTER_NODE (ip4_icmp_error_node)
Definition: icmp4.c:374
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169