FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * node.c: gre packet processing
3  *
4  * Copyright (c) 2012 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/pg/pg.h>
20 #include <vnet/gre/gre.h>
21 #include <vnet/mpls/mpls.h>
22 #include <vppinfra/sparse_vec.h>
23 
24 #define foreach_gre_input_next \
25 _(PUNT, "error-punt") \
26 _(DROP, "error-drop") \
27 _(ETHERNET_INPUT, "ethernet-input") \
28 _(IP4_INPUT, "ip4-input") \
29 _(IP6_INPUT, "ip6-input") \
30 _(MPLS_INPUT, "mpls-input")
31 
32 typedef enum
33 {
34 #define _(s,n) GRE_INPUT_NEXT_##s,
36 #undef _
39 
40 typedef struct
41 {
44  ip46_address_t src;
45  ip46_address_t dst;
47 
48 extern u8 *format_gre_rx_trace (u8 * s, va_list * args);
49 
50 #ifndef CLIB_MARCH_VARIANT
51 u8 *
52 format_gre_rx_trace (u8 * s, va_list * args)
53 {
54  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
55  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
56  gre_rx_trace_t *t = va_arg (*args, gre_rx_trace_t *);
57 
58  s = format (s, "GRE: tunnel %d len %d src %U dst %U",
59  t->tunnel_id, clib_net_to_host_u16 (t->length),
62  return s;
63 }
64 #endif /* CLIB_MARCH_VARIANT */
65 
66 typedef struct
67 {
68  /* Sparse vector mapping gre protocol in network byte order
69  to next index. */
72 
73 always_inline void
75  u32 tun_sw_if_index, const ip6_header_t * ip6,
76  const ip4_header_t * ip4, int is_ipv6)
77 {
78  gre_rx_trace_t *tr = vlib_add_trace (vm, node,
79  b, sizeof (*tr));
80  tr->tunnel_id = tun_sw_if_index;
81  if (is_ipv6)
82  {
83  tr->length = ip6->payload_length;
84  tr->src.ip6.as_u64[0] = ip6->src_address.as_u64[0];
85  tr->src.ip6.as_u64[1] = ip6->src_address.as_u64[1];
86  tr->dst.ip6.as_u64[0] = ip6->dst_address.as_u64[0];
87  tr->dst.ip6.as_u64[1] = ip6->dst_address.as_u64[1];
88  }
89  else
90  {
91  tr->length = ip4->length;
92  tr->src.as_u64[0] = tr->src.as_u64[1] = 0;
93  tr->dst.as_u64[0] = tr->dst.as_u64[1] = 0;
94  tr->src.ip4.as_u32 = ip4->src_address.as_u32;
95  tr->dst.ip4.as_u32 = ip4->dst_address.as_u32;
96  }
97 }
98 
99 always_inline void
101  vlib_buffer_t * b, u16 * next, const gre_tunnel_key_t * key,
102  gre_tunnel_key_t * cached_key, u32 * tun_sw_if_index,
103  u32 * cached_tun_sw_if_index, int is_ipv6)
104 {
105  const uword *p;
106  p = is_ipv6 ? hash_get_mem (gm->tunnel_by_key6, &key->gtk_v6)
107  : hash_get_mem (gm->tunnel_by_key4, &key->gtk_v4);
108  if (PREDICT_FALSE (!p))
109  {
110  *next = GRE_INPUT_NEXT_DROP;
111  b->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
112  *tun_sw_if_index = ~0;
113  }
114  else
115  {
116  const gre_tunnel_t *tun;
117  tun = pool_elt_at_index (gm->tunnels, *p);
118  *cached_tun_sw_if_index = *tun_sw_if_index = tun->sw_if_index;
119  if (is_ipv6)
120  cached_key->gtk_v6 = key->gtk_v6;
121  else
122  cached_key->gtk_v4 = key->gtk_v4;
123  }
124 }
125 
129  const int is_ipv6)
130 {
131  gre_main_t *gm = &gre_main;
132  u32 *from, n_left_from;
133  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
134  u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
135  u16 cached_protocol = ~0;
136  u32 cached_next_index = SPARSE_VEC_INVALID_INDEX;
137  u32 cached_tun_sw_if_index = ~0;
138  gre_tunnel_key_t cached_key;
139 
140  from = vlib_frame_vector_args (frame);
141  n_left_from = frame->n_vectors;
142  vlib_get_buffers (vm, from, bufs, n_left_from);
143 
144  if (is_ipv6)
145  clib_memset (&cached_key.gtk_v6, 0xff, sizeof (cached_key.gtk_v6));
146  else
147  clib_memset (&cached_key.gtk_v4, 0xff, sizeof (cached_key.gtk_v4));
148 
149  while (n_left_from >= 2)
150  {
151  const ip6_header_t *ip6[2];
152  const ip4_header_t *ip4[2];
153  const gre_header_t *gre[2];
154  u32 nidx[2];
155  next_info_t ni[2];
156  u8 type[2];
157  u16 version[2];
158  u32 len[2];
160  u8 matched[2];
161  u32 tun_sw_if_index[2];
162 
163  if (PREDICT_TRUE (n_left_from >= 6))
164  {
165  vlib_prefetch_buffer_data (b[2], LOAD);
166  vlib_prefetch_buffer_data (b[3], LOAD);
167  vlib_prefetch_buffer_header (b[4], STORE);
168  vlib_prefetch_buffer_header (b[5], STORE);
169  }
170 
171  if (is_ipv6)
172  {
173  /* ip6_local hands us the ip header, not the gre header */
174  ip6[0] = vlib_buffer_get_current (b[0]);
175  ip6[1] = vlib_buffer_get_current (b[1]);
176  gre[0] = (void *) (ip6[0] + 1);
177  gre[1] = (void *) (ip6[1] + 1);
178  vlib_buffer_advance (b[0], sizeof (*ip6[0]) + sizeof (*gre[0]));
179  vlib_buffer_advance (b[1], sizeof (*ip6[0]) + sizeof (*gre[0]));
180  }
181  else
182  {
183  /* ip4_local hands us the ip header, not the gre header */
184  ip4[0] = vlib_buffer_get_current (b[0]);
185  ip4[1] = vlib_buffer_get_current (b[1]);
186  gre[0] = (void *) (ip4[0] + 1);
187  gre[1] = (void *) (ip4[1] + 1);
188  vlib_buffer_advance (b[0], sizeof (*ip4[0]) + sizeof (*gre[0]));
189  vlib_buffer_advance (b[1], sizeof (*ip4[0]) + sizeof (*gre[0]));
190  }
191 
192  if (PREDICT_TRUE (cached_protocol == gre[0]->protocol))
193  {
194  nidx[0] = cached_next_index;
195  }
196  else
197  {
198  cached_next_index = nidx[0] =
200  cached_protocol = gre[0]->protocol;
201  }
202  if (PREDICT_TRUE (cached_protocol == gre[1]->protocol))
203  {
204  nidx[1] = cached_next_index;
205  }
206  else
207  {
208  cached_next_index = nidx[1] =
210  cached_protocol = gre[1]->protocol;
211  }
212 
213  ni[0] = vec_elt (gm->next_by_protocol, nidx[0]);
214  ni[1] = vec_elt (gm->next_by_protocol, nidx[1]);
215  next[0] = ni[0].next_index;
216  next[1] = ni[1].next_index;
217  type[0] = ni[0].tunnel_type;
218  type[1] = ni[1].tunnel_type;
219 
220  b[0]->error = nidx[0] == SPARSE_VEC_INVALID_INDEX
221  ? node->errors[GRE_ERROR_UNKNOWN_PROTOCOL]
222  : node->errors[GRE_ERROR_NONE];
223  b[1]->error = nidx[1] == SPARSE_VEC_INVALID_INDEX
224  ? node->errors[GRE_ERROR_UNKNOWN_PROTOCOL]
225  : node->errors[GRE_ERROR_NONE];
226 
227  version[0] = clib_net_to_host_u16 (gre[0]->flags_and_version);
228  version[1] = clib_net_to_host_u16 (gre[1]->flags_and_version);
229  version[0] &= GRE_VERSION_MASK;
230  version[1] &= GRE_VERSION_MASK;
231 
232  b[0]->error = version[0]
233  ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION] : b[0]->error;
234  next[0] = version[0] ? GRE_INPUT_NEXT_DROP : next[0];
235  b[1]->error = version[1]
236  ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION] : b[1]->error;
237  next[1] = version[1] ? GRE_INPUT_NEXT_DROP : next[1];
238 
239  len[0] = vlib_buffer_length_in_chain (vm, b[0]);
240  len[1] = vlib_buffer_length_in_chain (vm, b[1]);
241 
242  /* always search for P2P types in the DP */
243  if (is_ipv6)
244  {
245  gre_mk_key6 (&ip6[0]->dst_address,
246  &ip6[0]->src_address,
247  vnet_buffer (b[0])->ip.fib_index,
248  type[0], TUNNEL_MODE_P2P, 0, &key[0].gtk_v6);
249  gre_mk_key6 (&ip6[1]->dst_address,
250  &ip6[1]->src_address,
251  vnet_buffer (b[1])->ip.fib_index,
252  type[1], TUNNEL_MODE_P2P, 0, &key[1].gtk_v6);
253  matched[0] = gre_match_key6 (&cached_key.gtk_v6, &key[0].gtk_v6);
254  matched[1] = gre_match_key6 (&cached_key.gtk_v6, &key[1].gtk_v6);
255  }
256  else
257  {
258  gre_mk_key4 (ip4[0]->dst_address,
259  ip4[0]->src_address,
260  vnet_buffer (b[0])->ip.fib_index,
261  type[0], TUNNEL_MODE_P2P, 0, &key[0].gtk_v4);
262  gre_mk_key4 (ip4[1]->dst_address,
263  ip4[1]->src_address,
264  vnet_buffer (b[1])->ip.fib_index,
265  type[1], TUNNEL_MODE_P2P, 0, &key[1].gtk_v4);
266  matched[0] = gre_match_key4 (&cached_key.gtk_v4, &key[0].gtk_v4);
267  matched[1] = gre_match_key4 (&cached_key.gtk_v4, &key[1].gtk_v4);
268  }
269 
270  tun_sw_if_index[0] = cached_tun_sw_if_index;
271  tun_sw_if_index[1] = cached_tun_sw_if_index;
272  if (PREDICT_FALSE (!matched[0]))
273  gre_tunnel_get (gm, node, b[0], &next[0], &key[0], &cached_key,
274  &tun_sw_if_index[0], &cached_tun_sw_if_index,
275  is_ipv6);
276  if (PREDICT_FALSE (!matched[1]))
277  gre_tunnel_get (gm, node, b[1], &next[1], &key[1], &cached_key,
278  &tun_sw_if_index[1], &cached_tun_sw_if_index,
279  is_ipv6);
280 
281  if (PREDICT_TRUE (next[0] > GRE_INPUT_NEXT_DROP))
282  {
284  interface_main.combined_sw_if_counters
286  vm->thread_index,
287  tun_sw_if_index[0],
288  1 /* packets */ ,
289  len[0] /* bytes */ );
290  vnet_buffer (b[0])->sw_if_index[VLIB_RX] = tun_sw_if_index[0];
291  }
292  if (PREDICT_TRUE (next[1] > GRE_INPUT_NEXT_DROP))
293  {
295  interface_main.combined_sw_if_counters
297  vm->thread_index,
298  tun_sw_if_index[1],
299  1 /* packets */ ,
300  len[1] /* bytes */ );
301  vnet_buffer (b[1])->sw_if_index[VLIB_RX] = tun_sw_if_index[1];
302  }
303 
304  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
305  gre_trace (vm, node, b[0], tun_sw_if_index[0], ip6[0], ip4[0],
306  is_ipv6);
307  if (PREDICT_FALSE (b[1]->flags & VLIB_BUFFER_IS_TRACED))
308  gre_trace (vm, node, b[1], tun_sw_if_index[1], ip6[1], ip4[1],
309  is_ipv6);
310 
311  b += 2;
312  next += 2;
313  n_left_from -= 2;
314  }
315 
316  while (n_left_from >= 1)
317  {
318  const ip6_header_t *ip6[1];
319  const ip4_header_t *ip4[1];
320  const gre_header_t *gre[1];
321  u32 nidx[1];
322  next_info_t ni[1];
323  u8 type[1];
324  u16 version[1];
325  u32 len[1];
327  u8 matched[1];
328  u32 tun_sw_if_index[1];
329 
330  if (PREDICT_TRUE (n_left_from >= 3))
331  {
332  vlib_prefetch_buffer_data (b[1], LOAD);
333  vlib_prefetch_buffer_header (b[2], STORE);
334  }
335 
336  if (is_ipv6)
337  {
338  /* ip6_local hands us the ip header, not the gre header */
339  ip6[0] = vlib_buffer_get_current (b[0]);
340  gre[0] = (void *) (ip6[0] + 1);
341  vlib_buffer_advance (b[0], sizeof (*ip6[0]) + sizeof (*gre[0]));
342  }
343  else
344  {
345  /* ip4_local hands us the ip header, not the gre header */
346  ip4[0] = vlib_buffer_get_current (b[0]);
347  gre[0] = (void *) (ip4[0] + 1);
348  vlib_buffer_advance (b[0], sizeof (*ip4[0]) + sizeof (*gre[0]));
349  }
350 
351  if (PREDICT_TRUE (cached_protocol == gre[0]->protocol))
352  {
353  nidx[0] = cached_next_index;
354  }
355  else
356  {
357  cached_next_index = nidx[0] =
359  cached_protocol = gre[0]->protocol;
360  }
361 
362  ni[0] = vec_elt (gm->next_by_protocol, nidx[0]);
363  next[0] = ni[0].next_index;
364  type[0] = ni[0].tunnel_type;
365 
366  b[0]->error = nidx[0] == SPARSE_VEC_INVALID_INDEX
367  ? node->errors[GRE_ERROR_UNKNOWN_PROTOCOL]
368  : node->errors[GRE_ERROR_NONE];
369 
370  version[0] = clib_net_to_host_u16 (gre[0]->flags_and_version);
371  version[0] &= GRE_VERSION_MASK;
372 
373  b[0]->error = version[0]
374  ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION] : b[0]->error;
375  next[0] = version[0] ? GRE_INPUT_NEXT_DROP : next[0];
376 
377  len[0] = vlib_buffer_length_in_chain (vm, b[0]);
378 
379  if (is_ipv6)
380  {
381  gre_mk_key6 (&ip6[0]->dst_address,
382  &ip6[0]->src_address,
383  vnet_buffer (b[0])->ip.fib_index,
384  type[0], TUNNEL_MODE_P2P, 0, &key[0].gtk_v6);
385  matched[0] = gre_match_key6 (&cached_key.gtk_v6, &key[0].gtk_v6);
386  }
387  else
388  {
389  gre_mk_key4 (ip4[0]->dst_address,
390  ip4[0]->src_address,
391  vnet_buffer (b[0])->ip.fib_index,
392  type[0], TUNNEL_MODE_P2P, 0, &key[0].gtk_v4);
393  matched[0] = gre_match_key4 (&cached_key.gtk_v4, &key[0].gtk_v4);
394  }
395 
396  tun_sw_if_index[0] = cached_tun_sw_if_index;
397  if (PREDICT_FALSE (!matched[0]))
398  gre_tunnel_get (gm, node, b[0], &next[0], &key[0], &cached_key,
399  &tun_sw_if_index[0], &cached_tun_sw_if_index,
400  is_ipv6);
401 
402  if (PREDICT_TRUE (next[0] > GRE_INPUT_NEXT_DROP))
403  {
405  interface_main.combined_sw_if_counters
407  vm->thread_index,
408  tun_sw_if_index[0],
409  1 /* packets */ ,
410  len[0] /* bytes */ );
411  vnet_buffer (b[0])->sw_if_index[VLIB_RX] = tun_sw_if_index[0];
412  }
413 
414  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
415  gre_trace (vm, node, b[0], tun_sw_if_index[0], ip6[0], ip4[0],
416  is_ipv6);
417 
418  b += 1;
419  next += 1;
420  n_left_from -= 1;
421  }
422 
423  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
424 
426  is_ipv6 ? gre6_input_node.index :
427  gre4_input_node.index, GRE_ERROR_PKTS_DECAP,
428  n_left_from);
429 
430  return frame->n_vectors;
431 }
432 
435  vlib_frame_t * from_frame)
436 {
437  return gre_input (vm, node, from_frame, /* is_ip6 */ 0);
438 }
439 
442  vlib_frame_t * from_frame)
443 {
444  return gre_input (vm, node, from_frame, /* is_ip6 */ 1);
445 }
446 
447 static char *gre_error_strings[] = {
448 #define gre_error(n,s) s,
449 #include "error.def"
450 #undef gre_error
451 };
452 
453 /* *INDENT-OFF* */
455  .name = "gre4-input",
456  /* Takes a vector of packets. */
457  .vector_size = sizeof (u32),
458 
459  .n_errors = GRE_N_ERROR,
460  .error_strings = gre_error_strings,
461 
462  .n_next_nodes = GRE_INPUT_N_NEXT,
463  .next_nodes = {
464 #define _(s,n) [GRE_INPUT_NEXT_##s] = n,
466 #undef _
467  },
468 
469  .format_buffer = format_gre_header_with_length,
470  .format_trace = format_gre_rx_trace,
471  .unformat_buffer = unformat_gre_header,
472 };
473 
475  .name = "gre6-input",
476  /* Takes a vector of packets. */
477  .vector_size = sizeof (u32),
478 
479  .runtime_data_bytes = sizeof (gre_input_runtime_t),
480 
481  .n_errors = GRE_N_ERROR,
482  .error_strings = gre_error_strings,
483 
484  .n_next_nodes = GRE_INPUT_N_NEXT,
485  .next_nodes = {
486 #define _(s,n) [GRE_INPUT_NEXT_##s] = n,
488 #undef _
489  },
490 
491  .format_buffer = format_gre_header_with_length,
492  .format_trace = format_gre_rx_trace,
493  .unformat_buffer = unformat_gre_header,
494 };
495 /* *INDENT-ON* */
496 
497 #ifndef CLIB_MARCH_VARIANT
498 void
500  gre_protocol_t protocol, u32 node_index,
501  gre_tunnel_type_t tunnel_type)
502 {
503  gre_main_t *em = &gre_main;
505  next_info_t *n;
506  u32 i;
507 
508  {
510  if (error)
511  clib_error_report (error);
512  }
513 
514  pi = gre_get_protocol_info (em, protocol);
515  pi->node_index = node_index;
516  pi->tunnel_type = tunnel_type;
517  pi->next_index = vlib_node_add_next (vm, gre4_input_node.index, node_index);
518  i = vlib_node_add_next (vm, gre6_input_node.index, node_index);
519  ASSERT (i == pi->next_index);
520 
521  /* Setup gre protocol -> next index sparse vector mapping. */
523  clib_host_to_net_u16 (protocol));
524  n->next_index = pi->next_index;
525  n->tunnel_type = tunnel_type;
526 }
527 
528 static void
529 gre_setup_node (vlib_main_t * vm, u32 node_index)
530 {
531  vlib_node_t *n = vlib_get_node (vm, node_index);
532  pg_node_t *pn = pg_get_node (node_index);
533 
537 }
538 
539 static clib_error_t *
541 {
542  gre_main_t *gm = &gre_main;
543  vlib_node_t *ethernet_input, *ip4_input, *ip6_input, *mpls_unicast_input;
544 
545  {
546  clib_error_t *error;
547  error = vlib_call_init_function (vm, gre_init);
548  if (error)
549  clib_error_report (error);
550  }
551 
552  gre_setup_node (vm, gre4_input_node.index);
553  gre_setup_node (vm, gre6_input_node.index);
554 
556  ( /* elt bytes */ sizeof (gm->next_by_protocol[0]),
557  /* bits in index */ BITS (((gre_header_t *) 0)->protocol));
558 
559  /* These could be moved to the supported protocol input node defn's */
560  ethernet_input = vlib_get_node_by_name (vm, (u8 *) "ethernet-input");
561  ASSERT (ethernet_input);
562  ip4_input = vlib_get_node_by_name (vm, (u8 *) "ip4-input");
563  ASSERT (ip4_input);
564  ip6_input = vlib_get_node_by_name (vm, (u8 *) "ip6-input");
565  ASSERT (ip6_input);
566  mpls_unicast_input = vlib_get_node_by_name (vm, (u8 *) "mpls-input");
567  ASSERT (mpls_unicast_input);
568 
569  gre_register_input_protocol (vm, GRE_PROTOCOL_teb,
570  ethernet_input->index, GRE_TUNNEL_TYPE_TEB);
571 
572  gre_register_input_protocol (vm, GRE_PROTOCOL_ip4,
573  ip4_input->index, GRE_TUNNEL_TYPE_L3);
574 
575  gre_register_input_protocol (vm, GRE_PROTOCOL_ip6,
576  ip6_input->index, GRE_TUNNEL_TYPE_L3);
577 
578  gre_register_input_protocol (vm, GRE_PROTOCOL_mpls_unicast,
579  mpls_unicast_input->index, GRE_TUNNEL_TYPE_L3);
580 
581  return 0;
582 }
583 
585 
586 #endif /* CLIB_MARCH_VARIANT */
587 /*
588  * fd.io coding-style-patch-verification: ON
589  *
590  * Local Variables:
591  * eval: (c-set-style "gnu")
592  * End:
593  */
vnet_main_t * vnet_main
Definition: gre.h:286
static void gre_mk_key6(const ip6_address_t *src, const ip6_address_t *dst, u32 fib_index, gre_tunnel_type_t ttype, tunnel_mode_t tmode, u16 session_id, gre_tunnel_key6_t *key)
Definition: gre.h:403
uword * tunnel_by_key6
Hash mapping to tunnels with ipv6 src/dst addr.
Definition: gre.h:268
GRE related global data.
Definition: gre.h:243
format_function_t format_gre_header_with_length
Definition: gre.h:339
#define CLIB_UNUSED(x)
Definition: clib.h:86
static void gre_setup_node(vlib_main_t *vm, u32 node_index)
Definition: node.c:529
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
ip4_address_t src_address
Definition: ip4_packet.h:170
#define PREDICT_TRUE(x)
Definition: clib.h:119
option version
Definition: sample.api:19
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:282
A GRE payload protocol registration.
Definition: gre.h:70
u32 thread_index
Definition: main.h:218
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u16 * next_by_protocol
Definition: node.c:70
#define VLIB_NODE_FN(node)
Definition: node.h:202
gre_input_next_t
Definition: node.c:32
u32 tunnel_id
Definition: node.c:42
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
ip6_address_t src_address
Definition: ip6_packet.h:310
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
static uword gre_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, const int is_ipv6)
Definition: node.c:127
static void gre_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, u32 tun_sw_if_index, const ip6_header_t *ip6, const ip4_header_t *ip4, int is_ipv6)
Definition: node.c:74
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:366
static void gre_mk_key4(ip4_address_t src, ip4_address_t dst, u32 fib_index, gre_tunnel_type_t ttype, tunnel_mode_t tmode, u16 session_id, gre_tunnel_key4_t *key)
Definition: gre.h:380
static clib_error_t * gre_input_init(vlib_main_t *vm)
Definition: node.c:540
vl_api_ip_proto_t protocol
Definition: lb_types.api:71
u32 sw_if_index
Definition: gre.h:206
vlib_node_registration_t gre4_input_node
(constructor) VLIB_REGISTER_NODE (gre4_input_node)
Definition: node.c:454
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
vl_api_ip6_address_t ip6
Definition: one.api:424
ip4_address_t dst_address
Definition: ip4_packet.h:170
#define sparse_vec_validate(v, i)
Definition: sparse_vec.h:231
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
gre_tunnel_type_t tunnel_type
GRE tunnel type.
Definition: gre.h:79
#define GRE_VERSION_MASK
Definition: packet.h:52
unsigned int u32
Definition: types.h:88
ip46_address_t dst
Definition: node.c:45
unformat_function_t unformat_gre_header
Definition: gre.h:353
#define vlib_call_init_function(vm, x)
Definition: init.h:270
#define VLIB_FRAME_SIZE
Definition: node.h:380
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
uword * tunnel_by_key4
Hash mapping to tunnels with ipv4 src/dst addr.
Definition: gre.h:263
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
A representation of a GRE tunnel.
Definition: gre.h:186
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
#define gm
Definition: dlmalloc.c:1219
unsigned short u16
Definition: types.h:57
static int gre_match_key4(const gre_tunnel_key4_t *key1, const gre_tunnel_key4_t *key2)
Definition: gre.h:395
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
gre_tunnel_key4_t gtk_v4
Definition: gre.h:155
u32 node_index
Node which handles this type.
Definition: gre.h:82
#define PREDICT_FALSE(x)
Definition: clib.h:118
#define always_inline
Definition: ipsec.h:28
vl_api_ip4_address_t ip4
Definition: one.api:376
u32 length
Definition: node.c:43
#define foreach_gre_input_next
Definition: node.c:24
vl_api_address_union_t src_address
Definition: ip_types.api:99
format_function_t * format_buffer
Definition: node.h:360
static int gre_match_key6(const gre_tunnel_key6_t *key1, const gre_tunnel_key6_t *key2)
Definition: gre.h:418
vlib_main_t * vm
Definition: in2out_ed.c:1599
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1150
u8 len
Definition: ip_types.api:92
format_function_t format_ip46_address
Definition: ip46_address.h:50
static clib_error_t * gre_init(vlib_main_t *vm)
Definition: gre.c:797
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u32 flags
Definition: vhost_user.h:248
void gre_register_input_protocol(vlib_main_t *vm, gre_protocol_t protocol, u32 node_index, gre_tunnel_type_t tunnel_type)
Definition: node.c:499
u16 n_vectors
Definition: node.h:399
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
Definition: buffer_node.h:339
gre_tunnel_key6_t gtk_v6
Definition: gre.h:156
u8 tunnel_type
Definition: gre.h:237
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
u16 protocol
Definition: packet.h:55
gre_protocol_t
Definition: packet.h:30
unformat_function_t * unformat_buffer
Definition: node.h:361
unformat_function_t * unformat_edit
Definition: pg.h:318
ip46_address_t src
Definition: node.c:44
u8 * format_gre_rx_trace(u8 *s, va_list *args)
Definition: node.c:52
#define vlib_prefetch_buffer_data(b, type)
Definition: buffer.h:204
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
static uword sparse_vec_index(void *v, uword sparse_index)
Definition: sparse_vec.h:161
#define ASSERT(truth)
u32 next_index
Next index for this type.
Definition: gre.h:85
gre_tunnel_t * tunnels
pool of tunnel instances
Definition: gre.h:248
#define clib_error_report(e)
Definition: error.h:113
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
next_info_t * next_by_protocol
Definition: gre.h:282
Union of the two possible key types.
Definition: gre.h:153
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
#define vec_elt(v, i)
Get vector value at index i.
typedef key
Definition: ipsec_types.api:85
u16 payload_length
Definition: ip6_packet.h:301
vl_api_address_t ip
Definition: l2.api:501
vlib_node_registration_t gre6_input_node
(constructor) VLIB_REGISTER_NODE (gre6_input_node)
Definition: node.c:474
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static char * gre_error_strings[]
Definition: node.c:447
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
unformat_function_t unformat_pg_gre_header
Definition: gre.h:354
vl_api_gbp_endpoint_tun_t tun
Definition: gbp.api:126
#define hash_get_mem(h, key)
Definition: hash.h:269
u8 next_index
Definition: gre.h:236
#define vnet_buffer(b)
Definition: buffer.h:417
enum gre_tunnel_type_t_ gre_tunnel_type_t
The GRE tunnel type.
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:59
static void gre_tunnel_get(const gre_main_t *gm, vlib_node_runtime_t *node, vlib_buffer_t *b, u16 *next, const gre_tunnel_key_t *key, gre_tunnel_key_t *cached_key, u32 *tun_sw_if_index, u32 *cached_tun_sw_if_index, int is_ipv6)
Definition: node.c:100
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1600
static gre_protocol_info_t * gre_get_protocol_info(gre_main_t *em, gre_protocol_t protocol)
Definition: gre.h:313
bool is_ipv6
Definition: dhcp.api:202
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:280
static void * sparse_vec_new(uword elt_bytes, uword sparse_index_bits)
Definition: sparse_vec.h:71
#define BITS(x)
Definition: clib.h:65
gre_main_t gre_main
Definition: gre.c:26
Definition: pg.h:315
Definition: defs.h:46
ip6_address_t dst_address
Definition: ip6_packet.h:310
#define SPARSE_VEC_INVALID_INDEX
Definition: sparse_vec.h:68