FD.io VPP  v17.07-30-g839fa73
Vector Packet Processing
ip4_input.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/ip4_input.c: IP v4 input node
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 <vnet/ip/ip.h>
41 #include <vnet/ethernet/ethernet.h>
42 #include <vnet/ppp/ppp.h>
43 #include <vnet/hdlc/hdlc.h>
44 
45 typedef struct
46 {
47  u8 packet_data[64];
49 
50 static u8 *
51 format_ip4_input_trace (u8 * s, va_list * va)
52 {
53  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
54  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
55  ip4_input_trace_t *t = va_arg (*va, ip4_input_trace_t *);
56 
57  s = format (s, "%U",
58  format_ip4_header, t->packet_data, sizeof (t->packet_data));
59 
60  return s;
61 }
62 
63 typedef enum
64 {
72 
73 /* Validate IP v4 packets and pass them either to forwarding code
74  or drop/punt exception packets. */
77  vlib_node_runtime_t * node,
78  vlib_frame_t * frame, int verify_checksum)
79 {
80  ip4_main_t *im = &ip4_main;
81  vnet_main_t *vnm = vnet_get_main ();
82  ip_lookup_main_t *lm = &im->lookup_main;
83  u32 n_left_from, *from, *to_next;
84  ip4_input_next_t next_index;
85  vlib_node_runtime_t *error_node =
88  u32 thread_index = vlib_get_thread_index ();
89 
90  from = vlib_frame_vector_args (frame);
91  n_left_from = frame->n_vectors;
92  next_index = node->cached_next_index;
93 
94  if (node->flags & VLIB_NODE_FLAG_TRACE)
95  vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
96  /* stride */ 1,
97  sizeof (ip4_input_trace_t));
98 
101 
102  while (n_left_from > 0)
103  {
104  u32 n_left_to_next;
105 
106  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
107 
108  while (n_left_from >= 4 && n_left_to_next >= 2)
109  {
110  vlib_buffer_t *p0, *p1;
111  ip4_header_t *ip0, *ip1;
112  u32 sw_if_index0, pi0, ip_len0, cur_len0, next0;
113  u32 sw_if_index1, pi1, ip_len1, cur_len1, next1;
114  i32 len_diff0, len_diff1;
115  u8 error0, error1, arc0, arc1;
116 
117  /* Prefetch next iteration. */
118  {
119  vlib_buffer_t *p2, *p3;
120 
121  p2 = vlib_get_buffer (vm, from[2]);
122  p3 = vlib_get_buffer (vm, from[3]);
123 
124  vlib_prefetch_buffer_header (p2, LOAD);
125  vlib_prefetch_buffer_header (p3, LOAD);
126 
127  CLIB_PREFETCH (p2->data, sizeof (ip0[0]), LOAD);
128  CLIB_PREFETCH (p3->data, sizeof (ip1[0]), LOAD);
129  }
130 
131  to_next[0] = pi0 = from[0];
132  to_next[1] = pi1 = from[1];
133  from += 2;
134  to_next += 2;
135  n_left_from -= 2;
136  n_left_to_next -= 2;
137 
138  p0 = vlib_get_buffer (vm, pi0);
139  p1 = vlib_get_buffer (vm, pi1);
140 
141  ip0 = vlib_buffer_get_current (p0);
142  ip1 = vlib_buffer_get_current (p1);
143 
144  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
145  sw_if_index1 = vnet_buffer (p1)->sw_if_index[VLIB_RX];
146 
147  error0 = error1 = IP4_ERROR_NONE;
148 
150  {
151  arc0 = lm->mcast_feature_arc_index;
153  }
154  else
155  {
156  arc0 = lm->ucast_feature_arc_index;
157  next0 = IP4_INPUT_NEXT_LOOKUP;
158  if (PREDICT_FALSE (ip0->ttl < 1))
159  error0 = IP4_ERROR_TIME_EXPIRED;
160  }
161 
163  {
164  arc1 = lm->mcast_feature_arc_index;
166  }
167  else
168  {
169  arc1 = lm->ucast_feature_arc_index;
170  next1 = IP4_INPUT_NEXT_LOOKUP;
171  if (PREDICT_FALSE (ip1->ttl < 1))
172  error1 = IP4_ERROR_TIME_EXPIRED;
173  }
174 
175  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
176  vnet_buffer (p1)->ip.adj_index[VLIB_RX] = ~0;
177 
178  vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0);
179  vnet_feature_arc_start (arc1, sw_if_index1, &next1, p1);
180 
181  vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1);
182  vlib_increment_simple_counter (cm, thread_index, sw_if_index1, 1);
183 
184  /* Punt packets with options or wrong version. */
185  if (PREDICT_FALSE (ip0->ip_version_and_header_length != 0x45))
186  error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ?
187  IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
188 
189  if (PREDICT_FALSE (ip1->ip_version_and_header_length != 0x45))
190  error1 = (ip1->ip_version_and_header_length & 0xf) != 5 ?
191  IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
192 
193  /* Verify header checksum. */
194  if (verify_checksum)
195  {
196  ip_csum_t sum0, sum1;
197 
198  ip4_partial_header_checksum_x1 (ip0, sum0);
199  ip4_partial_header_checksum_x1 (ip1, sum1);
200 
201  error0 = 0xffff != ip_csum_fold (sum0) ?
202  IP4_ERROR_BAD_CHECKSUM : error0;
203  error1 = 0xffff != ip_csum_fold (sum1) ?
204  IP4_ERROR_BAD_CHECKSUM : error1;
205  }
206 
207  /* Drop fragmentation offset 1 packets. */
208  error0 = ip4_get_fragment_offset (ip0) == 1 ?
209  IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
210  error1 = ip4_get_fragment_offset (ip1) == 1 ?
211  IP4_ERROR_FRAGMENT_OFFSET_ONE : error1;
212 
213  /* Verify lengths. */
214  ip_len0 = clib_net_to_host_u16 (ip0->length);
215  ip_len1 = clib_net_to_host_u16 (ip1->length);
216 
217  /* IP length must be at least minimal IP header. */
218  error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
219  error1 = ip_len1 < sizeof (ip1[0]) ? IP4_ERROR_TOO_SHORT : error1;
220 
221  cur_len0 = vlib_buffer_length_in_chain (vm, p0);
222  cur_len1 = vlib_buffer_length_in_chain (vm, p1);
223 
224  len_diff0 = cur_len0 - ip_len0;
225  len_diff1 = cur_len1 - ip_len1;
226 
227  error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
228  error1 = len_diff1 < 0 ? IP4_ERROR_BAD_LENGTH : error1;
229 
230  p0->error = error_node->errors[error0];
231  p1->error = error_node->errors[error1];
232 
233  if (PREDICT_FALSE (error0 != IP4_ERROR_NONE))
234  {
235  if (error0 == IP4_ERROR_TIME_EXPIRED)
236  {
237  icmp4_error_set_vnet_buffer (p0, ICMP4_time_exceeded,
238  ICMP4_time_exceeded_ttl_exceeded_in_transit,
239  0);
241  }
242  else
243  next0 = error0 != IP4_ERROR_OPTIONS ?
245  }
246  if (PREDICT_FALSE (error1 != IP4_ERROR_NONE))
247  {
248  if (error1 == IP4_ERROR_TIME_EXPIRED)
249  {
250  icmp4_error_set_vnet_buffer (p1, ICMP4_time_exceeded,
251  ICMP4_time_exceeded_ttl_exceeded_in_transit,
252  0);
254  }
255  else
256  next1 = error1 != IP4_ERROR_OPTIONS ?
258  }
259 
260  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
261  to_next, n_left_to_next,
262  pi0, pi1, next0, next1);
263  }
264  while (n_left_from > 0 && n_left_to_next > 0)
265  {
266  vlib_buffer_t *p0;
267  ip4_header_t *ip0;
268  u32 sw_if_index0, pi0, ip_len0, cur_len0, next0;
269  i32 len_diff0;
270  u8 error0, arc0;
271 
272  pi0 = from[0];
273  to_next[0] = pi0;
274  from += 1;
275  to_next += 1;
276  n_left_from -= 1;
277  n_left_to_next -= 1;
278 
279  p0 = vlib_get_buffer (vm, pi0);
280  ip0 = vlib_buffer_get_current (p0);
281 
282  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
283 
284  error0 = IP4_ERROR_NONE;
285 
287  {
288  arc0 = lm->mcast_feature_arc_index;
290  }
291  else
292  {
293  arc0 = lm->ucast_feature_arc_index;
294  next0 = IP4_INPUT_NEXT_LOOKUP;
295  if (PREDICT_FALSE (ip0->ttl < 1))
296  error0 = IP4_ERROR_TIME_EXPIRED;
297  }
298 
299  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
300  vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0);
301 
302  vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1);
303 
304  /* Punt packets with options or wrong version. */
305  if (PREDICT_FALSE (ip0->ip_version_and_header_length != 0x45))
306  error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ?
307  IP4_ERROR_OPTIONS : IP4_ERROR_VERSION;
308 
309  /* Verify header checksum. */
310  if (verify_checksum)
311  {
312  ip_csum_t sum0;
313 
314  ip4_partial_header_checksum_x1 (ip0, sum0);
315  error0 =
316  0xffff !=
317  ip_csum_fold (sum0) ? IP4_ERROR_BAD_CHECKSUM : error0;
318  }
319 
320  /* Drop fragmentation offset 1 packets. */
321  error0 =
322  ip4_get_fragment_offset (ip0) ==
323  1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
324 
325  /* Verify lengths. */
326  ip_len0 = clib_net_to_host_u16 (ip0->length);
327 
328  /* IP length must be at least minimal IP header. */
329  error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
330 
331  cur_len0 = vlib_buffer_length_in_chain (vm, p0);
332  len_diff0 = cur_len0 - ip_len0;
333  error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
334 
335  p0->error = error_node->errors[error0];
336  if (PREDICT_FALSE (error0 != IP4_ERROR_NONE))
337  {
338  if (error0 == IP4_ERROR_TIME_EXPIRED)
339  {
340  icmp4_error_set_vnet_buffer (p0, ICMP4_time_exceeded,
341  ICMP4_time_exceeded_ttl_exceeded_in_transit,
342  0);
344  }
345  else
346  next0 = error0 != IP4_ERROR_OPTIONS ?
348  }
349 
350  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
351  to_next, n_left_to_next,
352  pi0, next0);
353  }
354 
355  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
356  }
357 
358  return frame->n_vectors;
359 }
360 
361 /** \brief IPv4 input node.
362  @node ip4-input
363 
364  This is the IPv4 input node: validates ip4 header checksums,
365  verifies ip header lengths, discards pkts with expired TTLs,
366  and sends pkts to the set of ip feature nodes configured on
367  the rx interface.
368 
369  @param vm vlib_main_t corresponding to the current thread
370  @param node vlib_node_runtime_t
371  @param frame vlib_frame_t whose contents should be dispatched
372 
373  @par Graph mechanics: buffer metadata, next index usage
374 
375  @em Uses:
376  - vnet_feature_config_main_t cm corresponding to each pkt's dst address unicast /
377  multicast status.
378  - <code>b->current_config_index</code> corresponding to each pkt's
379  rx sw_if_index.
380  - This sets the per-packet graph trajectory, ensuring that
381  each packet visits the per-interface features in order.
382 
383  - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
384  - Indicates the @c sw_if_index value of the interface that the
385  packet was received on.
386 
387  @em Sets:
388  - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
389  - The lookup result adjacency index.
390 
391  <em>Next Indices:</em>
392  - Dispatches pkts to the (first) feature node:
393  <code> vnet_get_config_data (... &next0 ...); </code>
394  or @c error-drop
395 */
396 static uword
398 {
399  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 1);
400 }
401 
402 static uword
404  vlib_node_runtime_t * node, vlib_frame_t * frame)
405 {
406  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 0);
407 }
408 
409 static char *ip4_error_strings[] = {
410 #define _(sym,string) string,
412 #undef _
413 };
414 
415 /* *INDENT-OFF* */
417  .function = ip4_input,
418  .name = "ip4-input",
419  .vector_size = sizeof (u32),
420 
421  .n_errors = IP4_N_ERROR,
422  .error_strings = ip4_error_strings,
423 
424  .n_next_nodes = IP4_INPUT_N_NEXT,
425  .next_nodes = {
426  [IP4_INPUT_NEXT_DROP] = "error-drop",
427  [IP4_INPUT_NEXT_PUNT] = "error-punt",
428  [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
429  [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-mfib-forward-lookup",
430  [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
431  },
432 
433  .format_buffer = format_ip4_header,
434  .format_trace = format_ip4_input_trace,
435 };
436 /* *INDENT-ON* */
437 
439 
440 /* *INDENT-OFF* */
442  .function = ip4_input_no_checksum,
443  .name = "ip4-input-no-checksum",
444  .vector_size = sizeof (u32),
445 
446  .n_next_nodes = IP4_INPUT_N_NEXT,
447  .next_nodes = {
448  [IP4_INPUT_NEXT_DROP] = "error-drop",
449  [IP4_INPUT_NEXT_PUNT] = "error-punt",
450  [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
451  [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-mfib-forward-lookup",
452  [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
453  },
454 
455  .format_buffer = format_ip4_header,
456  .format_trace = format_ip4_input_trace,
457 };
458 /* *INDENT-ON* */
459 
462 
463 static clib_error_t *
465 {
466  clib_error_t *error;
467 
468  ethernet_register_input_type (vm, ETHERNET_TYPE_IP4, ip4_input_node.index);
469  ppp_register_input_protocol (vm, PPP_PROTOCOL_ip4, ip4_input_node.index);
470  hdlc_register_input_protocol (vm, HDLC_PROTOCOL_ip4, ip4_input_node.index);
471 
472  {
473  pg_node_t *pn;
474  pn = pg_get_node (ip4_input_node.index);
478  }
479 
480  if ((error = vlib_call_init_function (vm, ip4_cli_init)))
481  return error;
482 
484  return error;
485 
486  if ((error = vlib_call_init_function
488  return error;
489 
490  /* Set flow hash to something non-zero. */
491  ip4_main.flow_hash_seed = 0xdeadbeef;
492 
493  /* Default TTL for packets we generate. */
494  ip4_main.host_config.ttl = 64;
495 
496  return error;
497 }
498 
500 
501 /*
502  * fd.io coding-style-patch-verification: ON
503  *
504  * Local Variables:
505  * eval: (c-set-style "gnu")
506  * End:
507  */
#define CLIB_UNUSED(x)
Definition: clib.h:79
static uword ip4_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
IPv4 input node.
Definition: ip4_input.c:397
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vnet_interface_main_t interface_main
Definition: vnet.h:56
format_function_t format_ip4_header
Definition: format.h:86
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:459
unformat_function_t unformat_pg_ip4_header
Definition: format.h:91
ip_lookup_main_t lookup_main
Definition: ip4.h:85
uword ip_csum_t
Definition: ip_packet.h:90
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 increment)
Increment a simple counter.
Definition: counter.h:78
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:419
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:100
static clib_error_t * ip4_cli_init(vlib_main_t *vm)
Definition: ip46_cli.c:223
u8 mcast_feature_arc_index
Feature arc indices.
Definition: lookup.h:135
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:350
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static clib_error_t * ip4_init(vlib_main_t *vm)
Definition: ip4_input.c:464
#define always_inline
Definition: clib.h:84
ip4_address_t dst_address
Definition: ip4_packet.h:164
static int ip4_get_fragment_offset(ip4_header_t *i)
Definition: ip4_packet.h:192
int i32
Definition: types.h:81
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:164
static char * ip4_error_strings[]
Definition: ip4_input.c:409
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
A collection of simple counters.
Definition: counter.h:58
#define vlib_call_init_function(vm, x)
Definition: init.h:162
static vlib_node_registration_t ip4_input_no_checksum_node
(constructor) VLIB_REGISTER_NODE (ip4_input_no_checksum_node)
Definition: ip4_input.c:441
static u8 * format_ip4_input_trace(u8 *s, va_list *va)
Definition: ip4_input.c:51
struct ip4_main_t::@157 host_config
Template information for VPP generated packets.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:188
static uword ip4_address_is_multicast(ip4_address_t *a)
Definition: ip4_packet.h:310
#define PREDICT_FALSE(x)
Definition: clib.h:97
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:652
#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:216
#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:366
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:113
u8 packet_data[64]
Definition: ip4_input.c:47
#define foreach_ip4_error
Definition: ip4_error.h:43
static uword ip4_input_no_checksum(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip4_input.c:403
u16 n_vectors
Definition: node.h:345
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:185
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
clib_error_t * ip4_source_check_init(vlib_main_t *vm)
void icmp4_error_set_vnet_buffer(vlib_buffer_t *b, u8 type, u8 code, u32 data)
Definition: icmp4.c:431
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:88
unformat_function_t * unformat_edit
Definition: pg.h:307
void hdlc_register_input_protocol(vlib_main_t *vm, hdlc_protocol_t protocol, u32 node_index)
Definition: node.c:326
static uword ip4_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int verify_checksum)
Definition: ip4_input.c:76
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:460
ip4_input_next_t
Definition: ip4_input.c:63
unsigned int u32
Definition: types.h:88
IPv4 main type.
Definition: ip4.h:83
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:260
void ethernet_register_input_type(vlib_main_t *vm, ethernet_type_t type, u32 node_index)
Definition: node.c:1301
u64 uword
Definition: types.h:112
u8 ucast_feature_arc_index
Definition: lookup.h:136
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:45
clib_error_t * ip4_source_and_port_range_check_init(vlib_main_t *vm)
unsigned char u8
Definition: types.h:56
#define ip4_partial_header_checksum_x1(ip0, sum0)
Definition: ip4_packet.h:265
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:269
#define vnet_buffer(b)
Definition: buffer.h:303
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:144
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1168
u8 data[0]
Packet data.
Definition: buffer.h:152
vlib_node_registration_t ip4_input_node
(constructor) VLIB_REGISTER_NODE (ip4_input_node)
Definition: ip4_input.c:416
void ppp_register_input_protocol(vlib_main_t *vm, ppp_protocol_t protocol, u32 node_index)
Definition: node.c:338
u16 flags
Copy of main node flags.
Definition: node.h:454
u32 flow_hash_seed
Seed for Jenkins hash used to compute ip4 flow hash.
Definition: ip4.h:123
u8 ip_version_and_header_length
Definition: ip4_packet.h:132
u8 ttl
TTL to use for host generated packets.
Definition: ip4.h:129
VLIB_NODE_FUNCTION_MULTIARCH(ip4_input_node, ip4_input)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
Definition: pg.h:304
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:145
Definition: defs.h:46
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:201