FD.io VPP  v21.01.1
Vector Packet Processing
decap.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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  * @brief L2 LISP-GPE decap code.
18  *
19  */
20 #include <vlib/vlib.h>
21 #include <lisp/lisp-gpe/lisp_gpe.h>
22 
23 typedef struct
24 {
30 
31 static u8 *
32 format_lisp_gpe_rx_trace (u8 * s, va_list * args)
33 {
34  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
35  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
36  lisp_gpe_rx_trace_t *t = va_arg (*args, lisp_gpe_rx_trace_t *);
37 
38  if (t->tunnel_index != ~0)
39  {
40  s = format (s, "LISP-GPE: tunnel %d next %d error %d", t->tunnel_index,
41  t->next_index, t->error);
42  }
43  else
44  {
45  s = format (s, "LISP-GPE: no tunnel next %d error %d\n", t->next_index,
46  t->error);
47  }
48  s = format (s, "\n %U", format_lisp_gpe_header_with_length, &t->h,
49  (u32) sizeof (t->h) /* max size */ );
50  return s;
51 }
52 
54  LISP_GPE_INPUT_NEXT_DROP,
55  LISP_GPE_INPUT_NEXT_IP4_INPUT,
56  LISP_GPE_INPUT_NEXT_IP6_INPUT,
57  LISP_GPE_INPUT_NEXT_L2_INPUT,
58  LISP_GPE_INPUT_NEXT_DROP
59 };
60 
63 {
65 
66  /* lisp-gpe router */
67  if (PREDICT_TRUE ((lgh->flags & LISP_GPE_FLAGS_P)
68  || GPE_ENCAP_VXLAN == lgm->encap_mode))
69  {
71  return LISP_GPE_INPUT_NEXT_DROP;
72 
74  }
75  /* legacy lisp router */
76  else if ((lgh->flags & LISP_GPE_FLAGS_P) == 0)
77  {
78  ip4_header_t *iph = (ip4_header_t *) next_header;
79  if ((iph->ip_version_and_header_length & 0xF0) == 0x40)
80  return LISP_GPE_INPUT_NEXT_IP4_INPUT;
81  else if ((iph->ip_version_and_header_length & 0xF0) == 0x60)
82  return LISP_GPE_INPUT_NEXT_IP6_INPUT;
83  else
84  return LISP_GPE_INPUT_NEXT_DROP;
85  }
86  else
87  return LISP_GPE_INPUT_NEXT_DROP;
88 }
89 
92 {
93  if (LISP_GPE_INPUT_NEXT_IP4_INPUT == next_index
94  || LISP_GPE_INPUT_NEXT_IP6_INPUT == next_index)
95  return &lgm->l3_ifaces;
96  else if (LISP_GPE_INPUT_NEXT_L2_INPUT == next_index)
97  return &lgm->l2_ifaces;
98  else if (LISP_GPE_INPUT_NEXT_NSH_INPUT == next_index)
99  return &lgm->nsh_ifaces;
100  clib_warning ("next_index not associated to an interface!");
101  return 0;
102 }
103 
105 incr_decap_stats (vnet_main_t * vnm, u32 thread_index, u32 length,
106  u32 sw_if_index, u32 * last_sw_if_index, u32 * n_packets,
107  u32 * n_bytes)
108 {
110 
111  if (PREDICT_TRUE (sw_if_index == *last_sw_if_index))
112  {
113  *n_packets += 1;
114  *n_bytes += length;
115  }
116  else
117  {
118  if (PREDICT_TRUE (*last_sw_if_index != ~0))
119  {
120  im = &vnm->interface_main;
121 
124  thread_index, *last_sw_if_index,
125  *n_packets, *n_bytes);
126  }
127  *last_sw_if_index = sw_if_index;
128  *n_packets = 1;
129  *n_bytes = length;
130  }
131 }
132 
133 /**
134  * @brief LISP-GPE decap dispatcher.
135  * @node lisp_gpe_input_inline
136  *
137  * LISP-GPE decap dispatcher.
138  *
139  * Decaps IP-UDP-LISP-GPE header and based on the next protocol and in the
140  * GPE header and the vni decides the next node to forward the packet to.
141  *
142  * @param[in] vm vlib_main_t corresponding to current thread.
143  * @param[in] node vlib_node_runtime_t data for this node.
144  * @param[in] frame vlib_frame_t whose contents should be dispatched.
145  *
146  * @return number of vectors in frame.
147  */
148 static uword
150  vlib_frame_t * from_frame, u8 is_v4)
151 {
152  u32 n_left_from, next_index, *from, *to_next, thread_index;
153  u32 n_bytes = 0, n_packets = 0, last_sw_if_index = ~0, drops = 0;
155 
156  thread_index = vm->thread_index;
157  from = vlib_frame_vector_args (from_frame);
158  n_left_from = from_frame->n_vectors;
159 
160  next_index = node->cached_next_index;
161 
162  while (n_left_from > 0)
163  {
164  u32 n_left_to_next;
165 
166  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
167 
168  while (n_left_from >= 4 && n_left_to_next >= 2)
169  {
170  u32 bi0, bi1;
171  vlib_buffer_t *b0, *b1;
172  ip4_udp_lisp_gpe_header_t *iul4_0, *iul4_1;
173  ip6_udp_lisp_gpe_header_t *iul6_0, *iul6_1;
174  lisp_gpe_header_t *lh0, *lh1;
175  u32 next0, next1, error0, error1;
176  uword *si0, *si1;
177  tunnel_lookup_t *tl0, *tl1;
178 
179  /* Prefetch next iteration. */
180  {
181  vlib_buffer_t *p2, *p3;
182 
183  p2 = vlib_get_buffer (vm, from[2]);
184  p3 = vlib_get_buffer (vm, from[3]);
185 
186  vlib_prefetch_buffer_header (p2, LOAD);
187  vlib_prefetch_buffer_header (p3, LOAD);
188 
189  CLIB_PREFETCH (p2->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
190  CLIB_PREFETCH (p3->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
191  }
192 
193  bi0 = from[0];
194  bi1 = from[1];
195  to_next[0] = bi0;
196  to_next[1] = bi1;
197  from += 2;
198  to_next += 2;
199  n_left_to_next -= 2;
200  n_left_from -= 2;
201 
202  b0 = vlib_get_buffer (vm, bi0);
203  b1 = vlib_get_buffer (vm, bi1);
204 
205  /* udp leaves current_data pointing at the lisp header */
206  if (is_v4)
207  {
209  -(word) (sizeof (udp_header_t) +
210  sizeof (ip4_header_t)));
212  -(word) (sizeof (udp_header_t) +
213  sizeof (ip4_header_t)));
214 
215  iul4_0 = vlib_buffer_get_current (b0);
216  iul4_1 = vlib_buffer_get_current (b1);
217 
218  /* pop (ip, udp, lisp-gpe) */
219  vlib_buffer_advance (b0, sizeof (*iul4_0));
220  vlib_buffer_advance (b1, sizeof (*iul4_1));
221 
222  lh0 = &iul4_0->lisp;
223  lh1 = &iul4_1->lisp;
224  }
225  else
226  {
228  -(word) (sizeof (udp_header_t) +
229  sizeof (ip6_header_t)));
231  -(word) (sizeof (udp_header_t) +
232  sizeof (ip6_header_t)));
233 
234  iul6_0 = vlib_buffer_get_current (b0);
235  iul6_1 = vlib_buffer_get_current (b1);
236 
237  /* pop (ip, udp, lisp-gpe) */
238  vlib_buffer_advance (b0, sizeof (*iul6_0));
239  vlib_buffer_advance (b1, sizeof (*iul6_1));
240 
241  lh0 = &iul6_0->lisp;
242  lh1 = &iul6_1->lisp;
243  }
244 
245  /* determine next_index from lisp-gpe header */
246  next0 = next_protocol_to_next_index (lh0,
248  next1 = next_protocol_to_next_index (lh1,
250 
251  /* determine if tunnel is l2 or l3 */
252  tl0 = next_index_to_iface (lgm, next0);
253  tl1 = next_index_to_iface (lgm, next1);
254 
255  /* map iid/vni to lisp-gpe sw_if_index which is used by ipx_input to
256  * decide the rx vrf and the input features to be applied */
257  si0 = hash_get (tl0->sw_if_index_by_vni,
258  clib_net_to_host_u32 (lh0->iid << 8));
259  si1 = hash_get (tl1->sw_if_index_by_vni,
260  clib_net_to_host_u32 (lh1->iid << 8));
261 
262 
263  /* Required to make the l2 tag push / pop code work on l2 subifs */
264  vnet_update_l2_len (b0);
265  vnet_update_l2_len (b1);
266 
267  if (si0)
268  {
269  incr_decap_stats (lgm->vnet_main, thread_index,
270  vlib_buffer_length_in_chain (vm, b0), si0[0],
271  &last_sw_if_index, &n_packets, &n_bytes);
272  vnet_buffer (b0)->sw_if_index[VLIB_RX] = si0[0];
273  error0 = 0;
274  }
275  else
276  {
277  next0 = LISP_GPE_INPUT_NEXT_DROP;
278  error0 = LISP_GPE_ERROR_NO_TUNNEL;
279  drops++;
280  }
281 
282  if (si1)
283  {
284  incr_decap_stats (lgm->vnet_main, thread_index,
285  vlib_buffer_length_in_chain (vm, b1), si1[0],
286  &last_sw_if_index, &n_packets, &n_bytes);
287  vnet_buffer (b1)->sw_if_index[VLIB_RX] = si1[0];
288  error1 = 0;
289  }
290  else
291  {
292  next1 = LISP_GPE_INPUT_NEXT_DROP;
293  error1 = LISP_GPE_ERROR_NO_TUNNEL;
294  drops++;
295  }
296 
297  b0->error = error0 ? node->errors[error0] : 0;
298  b1->error = error1 ? node->errors[error1] : 0;
299 
300  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
301  {
302  lisp_gpe_rx_trace_t *tr = vlib_add_trace (vm, node, b0,
303  sizeof (*tr));
304  tr->next_index = next0;
305  tr->error = error0;
306  tr->h = lh0[0];
307  }
308 
309  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
310  {
311  lisp_gpe_rx_trace_t *tr = vlib_add_trace (vm, node, b1,
312  sizeof (*tr));
313  tr->next_index = next1;
314  tr->error = error1;
315  tr->h = lh1[0];
316  }
317 
318  vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next,
319  n_left_to_next, bi0, bi1, next0,
320  next1);
321  }
322 
323  while (n_left_from > 0 && n_left_to_next > 0)
324  {
325  u32 bi0;
326  vlib_buffer_t *b0;
327  u32 next0;
328  ip4_udp_lisp_gpe_header_t *iul4_0;
329  ip6_udp_lisp_gpe_header_t *iul6_0;
330  lisp_gpe_header_t *lh0;
331  u32 error0;
332  uword *si0;
333  tunnel_lookup_t *tl0;
334 
335  bi0 = from[0];
336  to_next[0] = bi0;
337  from += 1;
338  to_next += 1;
339  n_left_from -= 1;
340  n_left_to_next -= 1;
341 
342  b0 = vlib_get_buffer (vm, bi0);
343 
344  /* udp leaves current_data pointing at the lisp header
345  * TODO: there's no difference in processing between v4 and v6
346  * encapsulated packets so the code should be simplified if ip header
347  * info is not going to be used for dp smrs/dpsec */
348  if (is_v4)
349  {
351  -(word) (sizeof (udp_header_t) +
352  sizeof (ip4_header_t)));
353 
354  iul4_0 = vlib_buffer_get_current (b0);
355 
356  /* pop (ip, udp, lisp-gpe) */
357  vlib_buffer_advance (b0, sizeof (*iul4_0));
358 
359  lh0 = &iul4_0->lisp;
360  }
361  else
362  {
364  -(word) (sizeof (udp_header_t) +
365  sizeof (ip6_header_t)));
366 
367  iul6_0 = vlib_buffer_get_current (b0);
368 
369  /* pop (ip, udp, lisp-gpe) */
370  vlib_buffer_advance (b0, sizeof (*iul6_0));
371 
372  lh0 = &iul6_0->lisp;
373  }
374 
375  /* TODO if security is to be implemented, something similar to RPF,
376  * probably we'd like to check that the peer is allowed to send us
377  * packets. For this, we should use the tunnel table OR check that
378  * we have a mapping for the source eid and that the outer source of
379  * the packet is one of its locators */
380 
381  /* determine next_index from lisp-gpe header */
382  next0 = next_protocol_to_next_index (lh0,
384 
385  /* determine if tunnel is l2 or l3 */
386  tl0 = next_index_to_iface (lgm, next0);
387 
388  /* map iid/vni to lisp-gpe sw_if_index which is used by ipx_input to
389  * decide the rx vrf and the input features to be applied.
390  * NOTE: vni uses only the first 24 bits */
391  si0 = hash_get (tl0->sw_if_index_by_vni,
392  clib_net_to_host_u32 (lh0->iid << 8));
393 
394  /* Required to make the l2 tag push / pop code work on l2 subifs */
395  vnet_update_l2_len (b0);
396 
397  if (si0)
398  {
399  incr_decap_stats (lgm->vnet_main, thread_index,
400  vlib_buffer_length_in_chain (vm, b0), si0[0],
401  &last_sw_if_index, &n_packets, &n_bytes);
402  vnet_buffer (b0)->sw_if_index[VLIB_RX] = si0[0];
403  error0 = 0;
404  }
405  else
406  {
407  next0 = LISP_GPE_INPUT_NEXT_DROP;
408  error0 = LISP_GPE_ERROR_NO_TUNNEL;
409  drops++;
410  }
411 
412  /* TODO error handling if security is implemented */
413  b0->error = error0 ? node->errors[error0] : 0;
414 
415  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
416  {
417  lisp_gpe_rx_trace_t *tr = vlib_add_trace (vm, node, b0,
418  sizeof (*tr));
419  tr->next_index = next0;
420  tr->error = error0;
421  tr->h = lh0[0];
422  }
423 
424  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
425  n_left_to_next, bi0, next0);
426  }
427 
428  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
429  }
430 
431  /* flush iface stats */
432  incr_decap_stats (lgm->vnet_main, thread_index, 0, ~0, &last_sw_if_index,
433  &n_packets, &n_bytes);
435  LISP_GPE_ERROR_NO_TUNNEL, drops);
436  return from_frame->n_vectors;
437 }
438 
439 static uword
441  vlib_frame_t * from_frame)
442 {
443  return lisp_gpe_input_inline (vm, node, from_frame, 1);
444 }
445 
446 static uword
448  vlib_frame_t * from_frame)
449 {
450  return lisp_gpe_input_inline (vm, node, from_frame, 0);
451 }
452 
454 #define lisp_gpe_error(n,s) s,
456 #undef lisp_gpe_error
457 };
458 
459 /* *INDENT-OFF* */
461  .function = lisp_gpe_ip4_input,
462  .name = "lisp-gpe-ip4-input",
463  /* Takes a vector of packets. */
464  .vector_size = sizeof (u32),
465  .n_next_nodes = LISP_GPE_INPUT_N_NEXT,
466  .next_nodes = {
467 #define _(s,n) [LISP_GPE_INPUT_NEXT_##s] = n,
469 #undef _
470  },
471 
473  .error_strings = lisp_gpe_ip4_input_error_strings,
474 
475  .format_buffer = format_lisp_gpe_header_with_length,
476  .format_trace = format_lisp_gpe_rx_trace,
477  // $$$$ .unformat_buffer = unformat_lisp_gpe_header,
478 };
479 /* *INDENT-ON* */
480 
481 /* *INDENT-OFF* */
483  .function = lisp_gpe_ip6_input,
484  .name = "lisp-gpe-ip6-input",
485  /* Takes a vector of packets. */
486  .vector_size = sizeof (u32),
487  .n_next_nodes = LISP_GPE_INPUT_N_NEXT,
488  .next_nodes = {
489 #define _(s,n) [LISP_GPE_INPUT_NEXT_##s] = n,
491 #undef _
492  },
493 
495  .error_strings = lisp_gpe_ip4_input_error_strings,
496 
497  .format_buffer = format_lisp_gpe_header_with_length,
498  .format_trace = format_lisp_gpe_rx_trace,
499  // $$$$ .unformat_buffer = unformat_lisp_gpe_header,
500 };
501 /* *INDENT-ON* */
502 
503 /**
504  * Adds arc from lisp-gpe-input to nsh-input if nsh-input is available
505  */
506 static void
508 {
510  vlib_main_t *vm = lgm->vlib_main;
511  vlib_node_t *nsh_input;
512 
513  /* Arc already exists */
515  != LISP_GPE_INPUT_NEXT_DROP)
516  return;
517 
518  /* Check if nsh-input is available */
519  if ((nsh_input = vlib_get_node_by_name (vm, (u8 *) "nsh-input")))
520  {
521  u32 slot4, slot6;
523  nsh_input->index,
526  nsh_input->index,
528  ASSERT (slot4 == slot6 && slot4 == LISP_GPE_INPUT_NEXT_NSH_INPUT);
529 
531  }
532 }
533 
534 /** GPE decap init function. */
535 clib_error_t *
537 {
538  clib_error_t *error = 0;
539 
540  if ((error = vlib_call_init_function (vm, lisp_gpe_init)))
541  return error;
542 
544  return 0;
545 }
546 
547 static uword
549  vlib_frame_t * from_frame)
550 {
551  vlib_node_increment_counter (vm, node->node_index, 0, 1);
552  return from_frame->n_vectors;
553 }
554 
556  "lisp gpe placeholder nsh decap",
557 };
558 
559 /* *INDENT-OFF* */
561  .function = lisp_gpe_nsh_placeholder_input,
562  .name = "lisp-gpe-nsh-placeholder-input",
563  .vector_size = sizeof (u32),
565  .n_next_nodes = 1,
566 
567  .n_errors = 1,
569 
570  .next_nodes = {
571  [0] = "error-drop",
572  },
573 };
574 /* *INDENT-ON* */
575 
576 static clib_error_t *
578  unformat_input_t * input,
579  vlib_cli_command_t * cmd)
580 {
586  return 0;
587 }
588 
589 /* *INDENT-OFF* */
590 VLIB_CLI_COMMAND (lisp_add_placeholder_nsh_node_command, static) = {
591  .path = "test one nsh add-placeholder-decap-node",
593 };
594 /* *INDENT-ON* */
595 
597 
598 /*
599  * fd.io coding-style-patch-verification: ON
600  *
601  * Local Variables:
602  * eval: (c-set-style "gnu")
603  * End:
604  */
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
#define foreach_lisp_gpe_ip_input_next
Definition: lisp_gpe.h:56
#define CLIB_UNUSED(x)
Definition: clib.h:87
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:239
vnet_interface_main_t interface_main
Definition: vnet.h:65
static void gpe_add_arc_from_input_to_nsh()
Adds arc from lisp-gpe-input to nsh-input if nsh-input is available.
Definition: decap.c:507
#define PREDICT_TRUE(x)
Definition: clib.h:122
u32 index
Definition: node.h:280
static uword lisp_gpe_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, u8 is_v4)
LISP-GPE decap dispatcher.
Definition: decap.c:149
LISP-GPE global state.
Definition: lisp_gpe.h:119
u32 thread_index
Definition: main.h:250
u8 * format_lisp_gpe_header_with_length(u8 *s, va_list *args)
Definition: interface.c:171
static uword lisp_gpe_ip4_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: decap.c:440
vlib_main_t * vm
Definition: in2out_ed.c:1580
#define LISP_GPE_INPUT_NEXT_NSH_INPUT
Definition: lisp_gpe.h:72
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:470
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
clib_error_t * gpe_decap_init(vlib_main_t *vm)
GPE decap init function.
Definition: decap.c:536
vlib_node_registration_t lisp_gpe_ip6_input_node
(constructor) VLIB_REGISTER_NODE (lisp_gpe_ip6_input_node)
Definition: decap.c:482
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1173
unsigned char u8
Definition: types.h:56
static char * lisp_gpe_nsh_placeholder_error_strings[]
Definition: decap.c:555
vlib_main_t * vlib_main
convenience
Definition: lisp_gpe.h:172
static uword lisp_gpe_nsh_placeholder_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: decap.c:548
static lisp_gpe_main_t * vnet_lisp_gpe_get_main()
Definition: lisp_gpe.h:184
#define static_always_inline
Definition: clib.h:109
i64 word
Definition: types.h:111
vlib_node_registration_t lisp_gpe_ip4_input_node
(constructor) VLIB_REGISTER_NODE (lisp_gpe_ip4_input_node)
Definition: decap.c:460
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static u32 next_protocol_to_next_index(lisp_gpe_header_t *lgh, u8 *next_header)
Definition: decap.c:62
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:882
description fragment has unexpected format
Definition: map.api:433
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:207
uword vlib_node_add_next_with_slot(vlib_main_t *vm, uword node_index, uword next_node_index, uword slot)
Definition: node.c:172
unsigned int u32
Definition: types.h:88
#define vlib_call_init_function(vm, x)
Definition: init.h:270
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
Definition: cJSON.c:84
#define hash_get(h, key)
Definition: hash.h:249
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
struct _unformat_input_t unformat_input_t
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:233
static tunnel_lookup_t * next_index_to_iface(lisp_gpe_main_t *lgm, u32 next_index)
Definition: decap.c:91
#define PREDICT_FALSE(x)
Definition: clib.h:121
#define always_inline
Definition: ipsec.h:28
u32 node_index
Node index.
Definition: node.h:488
#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:391
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1231
vlib_node_registration_t lisp_gpe_nsh_placeholder_input_node
(constructor) VLIB_REGISTER_NODE (lisp_gpe_nsh_placeholder_input_node)
Definition: decap.c:560
uword * sw_if_index_by_vni
lookup decap tunnel termination sw_if_index by vni and vice versa
Definition: lisp_gpe.h:88
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:170
u16 n_vectors
Definition: node.h:397
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
tunnel_lookup_t l2_ifaces
Definition: lisp_gpe.h:147
vnet_main_t * vnet_main
Definition: lisp_gpe.h:173
#define clib_warning(format, args...)
Definition: error.h:59
u8 data[]
Packet data.
Definition: buffer.h:181
static u8 * format_lisp_gpe_rx_trace(u8 *s, va_list *args)
Definition: decap.c:32
#define ARRAY_LEN(x)
Definition: clib.h:67
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
static u32 next_proto_to_next_index[LISP_GPE_NEXT_PROTOS]
Definition: decap.c:53
LISP-GPE header.
static clib_error_t * lisp_add_placeholder_nsh_node_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: decap.c:577
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:511
#define ASSERT(truth)
clib_error_t * lisp_gpe_init(vlib_main_t *vm)
LISP-GPE init function.
Definition: lisp_gpe.c:600
gpe_encap_mode_t encap_mode
Definition: lisp_gpe.h:161
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:252
char const int length
Definition: cJSON.h:163
lisp_gpe_header_t h
Definition: decap.c:28
tunnel_lookup_t l3_ifaces
Definition: lisp_gpe.h:139
static void vnet_update_l2_len(vlib_buffer_t *b)
Definition: l2_input.h:298
static_always_inline void incr_decap_stats(vnet_main_t *vnm, u32 thread_index, u32 length, u32 sw_if_index, u32 *last_sw_if_index, u32 *n_packets, u32 *n_bytes)
Definition: decap.c:105
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:297
static uword lisp_gpe_ip6_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: decap.c:447
#define vnet_buffer(b)
Definition: buffer.h:417
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:634
u8 ip_version_and_header_length
Definition: ip4_packet.h:93
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
tunnel_lookup_t nsh_ifaces
Definition: lisp_gpe.h:157
static char * lisp_gpe_ip4_input_error_strings[]
Definition: decap.c:453
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
LISP-GPE definitions.
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
Definition: defs.h:46