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