FD.io VPP  v16.09
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  u8 packet_data[64];
48 
49 static u8 * format_ip4_input_trace (u8 * s, va_list * va)
50 {
51  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
52  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
53  ip4_input_trace_t * t = va_arg (*va, ip4_input_trace_t *);
54 
55  s = format (s, "%U",
57  t->packet_data, sizeof (t->packet_data));
58 
59  return s;
60 }
61 
62 typedef enum {
70 
71 /* Validate IP v4 packets and pass them either to forwarding code
72  or drop/punt exception packets. */
75  vlib_node_runtime_t * node,
76  vlib_frame_t * frame,
77  int verify_checksum)
78 {
79  ip4_main_t * im = &ip4_main;
80  vnet_main_t * vnm = vnet_get_main();
81  ip_lookup_main_t * lm = &im->lookup_main;
82  u32 n_left_from, * from, * to_next;
83  ip4_input_next_t next_index;
84  vlib_node_runtime_t * error_node = vlib_node_get_runtime (vm, ip4_input_node.index);
86  u32 cpu_index = os_get_cpu_number();
87 
88  from = vlib_frame_vector_args (frame);
89  n_left_from = frame->n_vectors;
90  next_index = node->cached_next_index;
91 
92  if (node->flags & VLIB_NODE_FLAG_TRACE)
93  vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
94  /* stride */ 1,
95  sizeof (ip4_input_trace_t));
96 
99 
100  while (n_left_from > 0)
101  {
102  u32 n_left_to_next;
103 
104  vlib_get_next_frame (vm, node, next_index,
105  to_next, n_left_to_next);
106 
107  while (n_left_from >= 4 && n_left_to_next >= 2)
108  {
109  vlib_buffer_t * p0, * p1;
110  ip4_header_t * ip0, * ip1;
111  ip_config_main_t * cm0, * cm1;
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, cast0, cast1;
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 
149 
150  cm0 = lm->rx_config_mains + cast0;
151  cm1 = lm->rx_config_mains + cast1;
152 
153  p0->current_config_index = vec_elt (cm0->config_index_by_sw_if_index, sw_if_index0);
154  p1->current_config_index = vec_elt (cm1->config_index_by_sw_if_index, sw_if_index1);
155 
156  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
157  vnet_buffer (p1)->ip.adj_index[VLIB_RX] = ~0;
158 
161  &next0,
162  /* # bytes of config data */ 0);
165  &next1,
166  /* # bytes of config data */ 0);
167 
168  vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1);
169  vlib_increment_simple_counter (cm, cpu_index, sw_if_index1, 1);
170 
171  error0 = error1 = IP4_ERROR_NONE;
172 
173  /* Punt packets with options. */
174  error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ? IP4_ERROR_OPTIONS : error0;
175  error1 = (ip1->ip_version_and_header_length & 0xf) != 5 ? IP4_ERROR_OPTIONS : error1;
176 
177  /* Version != 4? Drop it. */
178  error0 = (ip0->ip_version_and_header_length >> 4) != 4 ? IP4_ERROR_VERSION : error0;
179  error1 = (ip1->ip_version_and_header_length >> 4) != 4 ? IP4_ERROR_VERSION : error1;
180 
181  /* Verify header checksum. */
182  if (verify_checksum)
183  {
184  ip_csum_t sum0, sum1;
185 
186  ip4_partial_header_checksum_x1 (ip0, sum0);
187  ip4_partial_header_checksum_x1 (ip1, sum1);
188 
189  error0 = 0xffff != ip_csum_fold (sum0) ? IP4_ERROR_BAD_CHECKSUM : error0;
190  error1 = 0xffff != ip_csum_fold (sum1) ? IP4_ERROR_BAD_CHECKSUM : error1;
191  }
192 
193  /* Drop fragmentation offset 1 packets. */
194  error0 = ip4_get_fragment_offset (ip0) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
195  error1 = ip4_get_fragment_offset (ip1) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error1;
196 
197  /* TTL < 1? Drop it. */
198  error0 = (ip0->ttl < 1 && cast0 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error0;
199  error1 = (ip1->ttl < 1 && cast1 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error1;
200 
201  /* Verify lengths. */
202  ip_len0 = clib_net_to_host_u16 (ip0->length);
203  ip_len1 = clib_net_to_host_u16 (ip1->length);
204 
205  /* IP length must be at least minimal IP header. */
206  error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
207  error1 = ip_len1 < sizeof (ip1[0]) ? IP4_ERROR_TOO_SHORT : error1;
208 
209  cur_len0 = vlib_buffer_length_in_chain (vm, p0);
210  cur_len1 = vlib_buffer_length_in_chain (vm, p1);
211 
212  len_diff0 = cur_len0 - ip_len0;
213  len_diff1 = cur_len1 - ip_len1;
214 
215  error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
216  error1 = len_diff1 < 0 ? IP4_ERROR_BAD_LENGTH : error1;
217 
218  p0->error = error_node->errors[error0];
219  p1->error = error_node->errors[error1];
220 
221  if (PREDICT_FALSE(error0 != IP4_ERROR_NONE))
222  {
223  if (error0 == IP4_ERROR_TIME_EXPIRED) {
224  icmp4_error_set_vnet_buffer(p0, ICMP4_time_exceeded,
225  ICMP4_time_exceeded_ttl_exceeded_in_transit, 0);
227  } else
228  next0 = error0 != IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT;
229  }
230  if (PREDICT_FALSE(error1 != IP4_ERROR_NONE))
231  {
232  if (error1 == IP4_ERROR_TIME_EXPIRED) {
233  icmp4_error_set_vnet_buffer(p1, ICMP4_time_exceeded,
234  ICMP4_time_exceeded_ttl_exceeded_in_transit, 0);
236  } else
237  next1 = error1 != IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT;
238  }
239 
240  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
241  to_next, n_left_to_next,
242  pi0, pi1, next0, next1);
243  }
244  while (n_left_from > 0 && n_left_to_next > 0)
245  {
246  vlib_buffer_t * p0;
247  ip4_header_t * ip0;
248  ip_config_main_t * cm0;
249  u32 sw_if_index0, pi0, ip_len0, cur_len0, next0;
250  i32 len_diff0;
251  u8 error0, cast0;
252 
253  pi0 = from[0];
254  to_next[0] = pi0;
255  from += 1;
256  to_next += 1;
257  n_left_from -= 1;
258  n_left_to_next -= 1;
259 
260  p0 = vlib_get_buffer (vm, pi0);
261  ip0 = vlib_buffer_get_current (p0);
262 
263  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
264 
266  cm0 = lm->rx_config_mains + cast0;
267  p0->current_config_index = vec_elt (cm0->config_index_by_sw_if_index, sw_if_index0);
268  vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0;
271  &next0,
272  /* # bytes of config data */ 0);
273 
274  vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1);
275 
276  error0 = IP4_ERROR_NONE;
277 
278  /* Punt packets with options. */
279  error0 = (ip0->ip_version_and_header_length & 0xf) != 5 ? IP4_ERROR_OPTIONS : error0;
280 
281  /* Version != 4? Drop it. */
282  error0 = (ip0->ip_version_and_header_length >> 4) != 4 ? IP4_ERROR_VERSION : error0;
283 
284  /* Verify header checksum. */
285  if (verify_checksum)
286  {
287  ip_csum_t sum0;
288 
289  ip4_partial_header_checksum_x1 (ip0, sum0);
290  error0 = 0xffff != ip_csum_fold (sum0) ? IP4_ERROR_BAD_CHECKSUM : error0;
291  }
292 
293  /* Drop fragmentation offset 1 packets. */
294  error0 = ip4_get_fragment_offset (ip0) == 1 ? IP4_ERROR_FRAGMENT_OFFSET_ONE : error0;
295 
296  /* TTL < 1? Drop it. */
297  error0 = (ip0->ttl < 1 && cast0 == VNET_UNICAST) ? IP4_ERROR_TIME_EXPIRED : error0;
298 
299  /* Verify lengths. */
300  ip_len0 = clib_net_to_host_u16 (ip0->length);
301 
302  /* IP length must be at least minimal IP header. */
303  error0 = ip_len0 < sizeof (ip0[0]) ? IP4_ERROR_TOO_SHORT : error0;
304 
305  cur_len0 = vlib_buffer_length_in_chain (vm, p0);
306  len_diff0 = cur_len0 - ip_len0;
307  error0 = len_diff0 < 0 ? IP4_ERROR_BAD_LENGTH : error0;
308 
309  p0->error = error_node->errors[error0];
310  if (PREDICT_FALSE(error0 != IP4_ERROR_NONE))
311  {
312  if (error0 == IP4_ERROR_TIME_EXPIRED) {
313  icmp4_error_set_vnet_buffer(p0, ICMP4_time_exceeded,
314  ICMP4_time_exceeded_ttl_exceeded_in_transit, 0);
316  } else
317  next0 = error0 != IP4_ERROR_OPTIONS ? IP4_INPUT_NEXT_DROP : IP4_INPUT_NEXT_PUNT;
318  }
319 
320  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
321  to_next, n_left_to_next,
322  pi0, next0);
323  }
324 
325  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
326  }
327 
328  return frame->n_vectors;
329 }
330 
331 /** \brief IPv4 input node.
332  @node ip4-input
333 
334  This is the IPv4 input node: validates ip4 header checksums,
335  verifies ip header lengths, discards pkts with expired TTLs,
336  and sends pkts to the set of ip feature nodes configured on
337  the rx interface.
338 
339  @param vm vlib_main_t corresponding to the current thread
340  @param node vlib_node_runtime_t
341  @param frame vlib_frame_t whose contents should be dispatched
342 
343  @par Graph mechanics: buffer metadata, next index usage
344 
345  @em Uses:
346  - ip_config_main_t cm corresponding to each pkt's dst address unicast /
347  multicast status.
348  - <code>b->current_config_index</code> corresponding to each pkt's
349  rx sw_if_index.
350  - This sets the per-packet graph trajectory, ensuring that
351  each packet visits the per-interface features in order.
352 
353  - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
354  - Indicates the @c sw_if_index value of the interface that the
355  packet was received on.
356 
357  @em Sets:
358  - <code>vnet_buffer(b)->ip.adj_index[VLIB_TX]</code>
359  - The lookup result adjacency index.
360 
361  <em>Next Indices:</em>
362  - Dispatches pkts to the (first) feature node:
363  <code> vnet_get_config_data (... &next0 ...); </code>
364  or @c error-drop
365 */
366 static uword
368  vlib_node_runtime_t * node,
369  vlib_frame_t * frame)
370 {
371  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 1);
372 }
373 
374 static uword
376  vlib_node_runtime_t * node,
377  vlib_frame_t * frame)
378 {
379  return ip4_input_inline (vm, node, frame, /* verify_checksum */ 0);
380 }
381 
382 static char * ip4_error_strings[] = {
383 #define _(sym,string) string,
385 #undef _
386 };
387 
389  .function = ip4_input,
390  .name = "ip4-input",
391  .vector_size = sizeof (u32),
392 
393  .n_errors = IP4_N_ERROR,
394  .error_strings = ip4_error_strings,
395 
396  .n_next_nodes = IP4_INPUT_N_NEXT,
397  .next_nodes = {
398  [IP4_INPUT_NEXT_DROP] = "error-drop",
399  [IP4_INPUT_NEXT_PUNT] = "error-punt",
400  [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
401  [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-lookup-multicast",
402  [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
403  },
404 
405  .format_buffer = format_ip4_header,
406  .format_trace = format_ip4_input_trace,
407 };
408 
410 
412  .function = ip4_input_no_checksum,
413  .name = "ip4-input-no-checksum",
414  .vector_size = sizeof (u32),
415 
416  .n_next_nodes = IP4_INPUT_N_NEXT,
417  .next_nodes = {
418  [IP4_INPUT_NEXT_DROP] = "error-drop",
419  [IP4_INPUT_NEXT_PUNT] = "error-punt",
420  [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup",
421  [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-lookup-multicast",
422  [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
423  },
424 
425  .format_buffer = format_ip4_header,
426  .format_trace = format_ip4_input_trace,
427 };
428 
430 
432 {
433  clib_error_t * error;
434 
435  ethernet_register_input_type (vm, ETHERNET_TYPE_IP4,
436  ip4_input_node.index);
437  ppp_register_input_protocol (vm, PPP_PROTOCOL_ip4,
438  ip4_input_node.index);
439  hdlc_register_input_protocol (vm, HDLC_PROTOCOL_ip4,
440  ip4_input_node.index);
441 
442  {
443  pg_node_t * pn;
444  pn = pg_get_node (ip4_input_node.index);
448  }
449 
450  if ((error = vlib_call_init_function (vm, ip4_cli_init)))
451  return error;
452 
454  return error;
455 
456  if ((error = vlib_call_init_function
458  return error;
459 
460  /* Set flow hash to something non-zero. */
461  ip4_main.flow_hash_seed = 0xdeadbeef;
462 
463  /* Default TTL for packets we generate. */
464  ip4_main.host_config.ttl = 64;
465 
466  return error;
467 }
468 
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:457
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 cpu_index, u32 index, u32 increment)
Increment a simple counter.
Definition: counter.h:78
#define CLIB_UNUSED(x)
Definition: clib.h:79
u32 * config_index_by_sw_if_index
Definition: lookup.h:369
static uword ip4_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
IPv4 input node.
Definition: ip4_input.c:367
u32 current_config_index
Used by feature subgraph arcs to visit enabled feature nodes.
Definition: buffer.h:121
vnet_interface_main_t interface_main
Definition: vnet.h:64
unformat_function_t unformat_pg_ip4_header
Definition: format.h:83
ip_config_main_t rx_config_mains[VNET_N_CAST]
rx/tx interface/feature configuration.
Definition: lookup.h:452
ip_lookup_main_t lookup_main
Definition: ip4.h:115
uword ip_csum_t
Definition: ip_packet.h:86
vlib_error_t * errors
Definition: node.h:418
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:112
static clib_error_t * ip4_cli_init(vlib_main_t *vm)
Definition: ip46_cli.c:187
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:343
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static clib_error_t * ip4_init(vlib_main_t *vm)
Definition: ip4_input.c:431
#define always_inline
Definition: clib.h:84
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:187
ip4_address_t dst_address
Definition: ip4_packet.h:138
static int ip4_get_fragment_offset(ip4_header_t *i)
Definition: ip4_packet.h:162
int i32
Definition: types.h:81
static char * ip4_error_strings[]
Definition: ip4_input.c:382
#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:59
#define vlib_call_init_function(vm, x)
Definition: init.h:161
void ppp_register_input_protocol(vlib_main_t *vm, ppp_protocol_t protocol, u32 node_index)
Definition: node.c:305
static vlib_node_registration_t ip4_input_no_checksum_node
(constructor) VLIB_REGISTER_NODE (ip4_input_no_checksum_node)
Definition: ip4_input.c:411
struct ip4_main_t::@126 host_config
Template information for VPP generated packets.
static u8 * format_ip4_input_trace(u8 *s, va_list *va)
Definition: ip4_input.c:49
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
static void * vnet_get_config_data(vnet_config_main_t *cm, u32 *config_index, u32 *next_index, u32 n_data_bytes)
Definition: config.h:122
static uword ip4_address_is_multicast(ip4_address_t *a)
Definition: ip4_packet.h:263
#define PREDICT_FALSE(x)
Definition: clib.h:97
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:500
#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:130
#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:348
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:118
u8 packet_data[64]
Definition: ip4_input.c:46
#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:375
u16 n_vectors
Definition: node.h:344
#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:416
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:299
void hdlc_register_input_protocol(vlib_main_t *vm, hdlc_protocol_t protocol, u32 node_index)
Definition: node.c:319
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:74
u16 cached_next_index
Definition: node.h:462
ip4_input_next_t
Definition: ip4_input.c:62
format_function_t format_ip4_header
Definition: format.h:78
unsigned int u32
Definition: types.h:88
#define vnet_buffer(b)
Definition: buffer.h:335
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:418
IPv4 main type.
Definition: ip4.h:114
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:259
void ethernet_register_input_type(vlib_main_t *vm, ethernet_type_t type, u32 node_index)
Definition: node.c:1182
u64 uword
Definition: types.h:112
#define vec_elt(v, i)
Get vector value at index i.
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:218
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:251
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:163
#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)
Definition: node.h:158
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1578
u8 data[0]
Packet data.
Definition: buffer.h:151
vlib_node_registration_t ip4_input_node
(constructor) VLIB_REGISTER_NODE (ip4_input_node)
Definition: ip4_input.c:388
u32 flow_hash_seed
Seed for Jenkins hash used to compute ip4 flow hash.
Definition: ip4.h:171
u8 ip_version_and_header_length
Definition: ip4_packet.h:108
u8 ttl
TTL to use for host generated packets.
Definition: ip4.h:176
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69
Definition: pg.h:297
vnet_config_main_t config_main
Definition: lookup.h:367
static u16 ip_csum_fold(ip_csum_t c)
Definition: ip_packet.h:138
Definition: defs.h:46