FD.io VPP  v17.07.01-10-g3be13f0
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 #define _(s,n) GRE_INPUT_NEXT_##s,
35 #undef _
38 
39 typedef struct {
42  ip46_address_t src;
43  ip46_address_t dst;
46 
47 u8 * format_gre_rx_trace (u8 * s, va_list * args)
48 {
49  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
50  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
51  gre_rx_trace_t * t = va_arg (*args, gre_rx_trace_t *);
52 
53  s = format (s, "GRE: tunnel %d len %d src %U dst %U",
54  t->tunnel_id, clib_net_to_host_u16(t->length),
57  return s;
58 }
59 
60 typedef struct {
61  /* Sparse vector mapping gre protocol in network byte order
62  to next index. */
65 
68  vlib_node_runtime_t * node,
69  vlib_frame_t * from_frame,
70  u8 is_ipv6)
71 {
72  gre_main_t * gm = &gre_main;
73  __attribute__((unused)) u32 n_left_from, next_index, * from, * to_next;
74  u64 cached_tunnel_key4;
75  u64 cached_tunnel_key6[4];
76  u32 cached_tunnel_sw_if_index = 0, tunnel_sw_if_index = 0;
77 
78  u32 thread_index = vlib_get_thread_index();
79  u32 len;
81 
82  if (!is_ipv6)
83  memset (&cached_tunnel_key4, 0xff, sizeof(cached_tunnel_key4));
84  else
85  memset (&cached_tunnel_key6, 0xff, sizeof(cached_tunnel_key6));
86 
87  from = vlib_frame_vector_args (from_frame);
88  n_left_from = from_frame->n_vectors;
89 
90  next_index = node->cached_next_index;
91 
92  while (n_left_from > 0)
93  {
94  u32 n_left_to_next;
95 
96  vlib_get_next_frame (vm, node, next_index,
97  to_next, n_left_to_next);
98 
99  while (n_left_from >= 4 && n_left_to_next >= 2)
100  {
101  u32 bi0, bi1;
102  vlib_buffer_t * b0, * b1;
103  gre_header_t * h0, * h1;
104  u16 version0, version1;
105  int verr0, verr1;
106  u32 i0, i1, next0, next1, protocol0, protocol1;
107  ip4_header_t *ip4_0, *ip4_1;
108  ip6_header_t *ip6_0, *ip6_1;
109  u32 ip4_tun_src0, ip4_tun_dst0;
110  u32 ip4_tun_src1, ip4_tun_dst1;
111  u64 ip6_tun_src0[2], ip6_tun_dst0[2];
112  u64 ip6_tun_src1[2], ip6_tun_dst1[2];
113 
114  /* Prefetch next iteration. */
115  {
116  vlib_buffer_t * p2, * p3;
117 
118  p2 = vlib_get_buffer (vm, from[2]);
119  p3 = vlib_get_buffer (vm, from[3]);
120 
121  vlib_prefetch_buffer_header (p2, LOAD);
122  vlib_prefetch_buffer_header (p3, LOAD);
123 
124  CLIB_PREFETCH (p2->data, sizeof (h0[0]), LOAD);
125  CLIB_PREFETCH (p3->data, sizeof (h1[0]), LOAD);
126  }
127 
128  bi0 = from[0];
129  bi1 = from[1];
130  to_next[0] = bi0;
131  to_next[1] = bi1;
132  from += 2;
133  to_next += 2;
134  n_left_to_next -= 2;
135  n_left_from -= 2;
136 
137  b0 = vlib_get_buffer (vm, bi0);
138  b1 = vlib_get_buffer (vm, bi1);
139 
140  if (!is_ipv6)
141  {
142  /* ip4_local hands us the ip header, not the gre header */
143  ip4_0 = vlib_buffer_get_current (b0);
144  ip4_1 = vlib_buffer_get_current (b1);
145  /* Save src + dst ip4 address, e.g. for mpls-o-gre */
146  ip4_tun_src0 = ip4_0->src_address.as_u32;
147  ip4_tun_dst0 = ip4_0->dst_address.as_u32;
148  ip4_tun_src1 = ip4_1->src_address.as_u32;
149  ip4_tun_dst1 = ip4_1->dst_address.as_u32;
150 
151  vlib_buffer_advance (b0, sizeof (*ip4_0));
152  vlib_buffer_advance (b1, sizeof (*ip4_1));
153  }
154  else
155  {
156  /* ip6_local hands us the ip header, not the gre header */
157  ip6_0 = vlib_buffer_get_current (b0);
158  ip6_1 = vlib_buffer_get_current (b1);
159  /* Save src + dst ip6 address, e.g. for mpls-o-gre */
160  ip6_tun_src0[0] = ip6_0->src_address.as_u64[0];
161  ip6_tun_src0[1] = ip6_0->src_address.as_u64[1];
162  ip6_tun_dst0[0] = ip6_0->dst_address.as_u64[0];
163  ip6_tun_dst0[1] = ip6_0->dst_address.as_u64[1];
164  ip6_tun_src1[0] = ip6_1->src_address.as_u64[0];
165  ip6_tun_src1[1] = ip6_1->src_address.as_u64[1];
166  ip6_tun_dst1[0] = ip6_1->dst_address.as_u64[0];
167  ip6_tun_dst1[1] = ip6_1->dst_address.as_u64[1];
168 
169  vlib_buffer_advance (b0, sizeof (*ip6_0));
170  vlib_buffer_advance (b1, sizeof (*ip6_1));
171  }
172 
173  h0 = vlib_buffer_get_current (b0);
174  h1 = vlib_buffer_get_current (b1);
175 
176  /* Index sparse array with network byte order. */
177  protocol0 = h0->protocol;
178  protocol1 = h1->protocol;
179  sparse_vec_index2 (gm->next_by_protocol, protocol0, protocol1,
180  &i0, &i1);
181  next0 = vec_elt(gm->next_by_protocol, i0);
182  next1 = vec_elt(gm->next_by_protocol, i1);
183 
184  b0->error = node->errors[i0 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
185  b1->error = node->errors[i1 == SPARSE_VEC_INVALID_INDEX ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
186 
187  version0 = clib_net_to_host_u16 (h0->flags_and_version);
188  verr0 = version0 & GRE_VERSION_MASK;
189  version1 = clib_net_to_host_u16 (h1->flags_and_version);
190  verr1 = version1 & GRE_VERSION_MASK;
191 
192  b0->error = verr0 ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION]
193  : b0->error;
194  next0 = verr0 ? GRE_INPUT_NEXT_DROP : next0;
195  b1->error = verr1 ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION]
196  : b1->error;
197  next1 = verr1 ? GRE_INPUT_NEXT_DROP : next1;
198 
199 
200  /* RPF check for ip4/ip6 input */
201  if (PREDICT_TRUE(next0 == GRE_INPUT_NEXT_IP4_INPUT
202  || next0 == GRE_INPUT_NEXT_IP6_INPUT
203  || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT
204  || next0 == GRE_INPUT_NEXT_MPLS_INPUT))
205  {
206 
207  u64 key4, key6[4];
208  if (!is_ipv6)
209  {
210  key4 = ((u64)(ip4_tun_dst0) << 32) | (u64)(ip4_tun_src0);
211  }
212  else
213  {
214  key6[0] = ip6_tun_dst0[0];
215  key6[1] = ip6_tun_dst0[1];
216  key6[2] = ip6_tun_src0[0];
217  key6[3] = ip6_tun_src0[1];
218  }
219 
220  if ((!is_ipv6 && cached_tunnel_key4 != key4) ||
221  (is_ipv6 && cached_tunnel_key6[0] != key6[0] &&
222  cached_tunnel_key6[1] != key6[1] &&
223  cached_tunnel_key6[2] != key6[2] &&
224  cached_tunnel_key6[3] != key6[3]))
225  {
227  gre_tunnel_t * t;
228  uword * p;
229 
230  if (!is_ipv6)
231  p = hash_get (gm->tunnel_by_key4, key4);
232  else
233  p = hash_get_mem (gm->tunnel_by_key6, key6);
234  if (!p)
235  {
236  next0 = GRE_INPUT_NEXT_DROP;
237  b0->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
238  goto drop0;
239  }
240  t = pool_elt_at_index (gm->tunnels, p[0]);
242  t->hw_if_index);
243  tunnel_sw_if_index = hi->sw_if_index;
244 
245  cached_tunnel_sw_if_index = tunnel_sw_if_index;
246  }
247  else
248  {
249  tunnel_sw_if_index = cached_tunnel_sw_if_index;
250  }
251  }
252  else
253  {
254  next0 = GRE_INPUT_NEXT_DROP;
255  goto drop0;
256  }
257  len = vlib_buffer_length_in_chain (vm, b0);
260  thread_index,
261  tunnel_sw_if_index,
262  1 /* packets */,
263  len /* bytes */);
264 
265  vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
266 
267 drop0:
268  if (PREDICT_TRUE(next1 == GRE_INPUT_NEXT_IP4_INPUT
269  || next1 == GRE_INPUT_NEXT_IP6_INPUT
270  || next1 == GRE_INPUT_NEXT_ETHERNET_INPUT
271  || next1 == GRE_INPUT_NEXT_MPLS_INPUT))
272  {
273  u64 key4, key6[4];
274  if (!is_ipv6)
275  {
276  key4 = ((u64)(ip4_tun_dst1) << 32) | (u64)(ip4_tun_src1);
277  }
278  else
279  {
280  key6[0] = ip6_tun_dst1[0];
281  key6[1] = ip6_tun_dst1[1];
282  key6[2] = ip6_tun_src1[0];
283  key6[3] = ip6_tun_src1[1];
284  }
285 
286  if ((!is_ipv6 && cached_tunnel_key4 != key4) ||
287  (is_ipv6 && cached_tunnel_key6[0] != key6[0] &&
288  cached_tunnel_key6[1] != key6[1] &&
289  cached_tunnel_key6[2] != key6[2] &&
290  cached_tunnel_key6[3] != key6[3]))
291  {
293  gre_tunnel_t * t;
294  uword * p;
295 
296  if (!is_ipv6)
297  p = hash_get (gm->tunnel_by_key4, key4);
298  else
299  p = hash_get_mem (gm->tunnel_by_key6, key6);
300 
301  if (!p)
302  {
303  next1 = GRE_INPUT_NEXT_DROP;
304  b1->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
305  goto drop1;
306  }
307  t = pool_elt_at_index (gm->tunnels, p[0]);
309  t->hw_if_index);
310  tunnel_sw_if_index = hi->sw_if_index;
311 
312  cached_tunnel_sw_if_index = tunnel_sw_if_index;
313  }
314  else
315  {
316  tunnel_sw_if_index = cached_tunnel_sw_if_index;
317  }
318  }
319  else
320  {
321  next1 = GRE_INPUT_NEXT_DROP;
322  goto drop1;
323  }
324  len = vlib_buffer_length_in_chain (vm, b1);
327  thread_index,
328  tunnel_sw_if_index,
329  1 /* packets */,
330  len /* bytes */);
331 
332  vnet_buffer(b1)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
333 
334 drop1:
336  {
337  gre_rx_trace_t *tr = vlib_add_trace (vm, node,
338  b0, sizeof (*tr));
339  tr->tunnel_id = tunnel_sw_if_index;
340  if (!is_ipv6)
341  {
342  tr->length = ip4_0->length;
343  tr->src.ip4.as_u32 = ip4_0->src_address.as_u32;
344  tr->dst.ip4.as_u32 = ip4_0->dst_address.as_u32;
345  }
346  else
347  {
348  tr->length = ip6_0->payload_length;
349  tr->src.ip6.as_u64[0] = ip6_0->src_address.as_u64[0];
350  tr->src.ip6.as_u64[1] = ip6_0->src_address.as_u64[1];
351  tr->dst.ip6.as_u64[0] = ip6_0->dst_address.as_u64[0];
352  tr->dst.ip6.as_u64[1] = ip6_0->dst_address.as_u64[1];
353  }
354  }
355 
357  {
358  gre_rx_trace_t *tr = vlib_add_trace (vm, node,
359  b1, sizeof (*tr));
360  tr->tunnel_id = tunnel_sw_if_index;
361  if (!is_ipv6)
362  {
363  tr->length = ip4_1->length;
364  tr->src.ip4.as_u32 = ip4_1->src_address.as_u32;
365  tr->dst.ip4.as_u32 = ip4_1->dst_address.as_u32;
366  }
367  else
368  {
369  tr->length = ip6_1->payload_length;
370  tr->src.ip6.as_u64[0] = ip6_1->src_address.as_u64[0];
371  tr->src.ip6.as_u64[1] = ip6_1->src_address.as_u64[1];
372  tr->dst.ip6.as_u64[0] = ip6_1->dst_address.as_u64[0];
373  tr->dst.ip6.as_u64[1] = ip6_1->dst_address.as_u64[1];
374  }
375  }
376 
377  vlib_buffer_advance (b0, sizeof (*h0));
378  vlib_buffer_advance (b1, sizeof (*h1));
379 
380  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
381  to_next, n_left_to_next,
382  bi0, bi1, next0, next1);
383  }
384 
385  while (n_left_from > 0 && n_left_to_next > 0)
386  {
387  u32 bi0;
388  vlib_buffer_t * b0;
389  gre_header_t * h0;
390  ip4_header_t * ip4_0;
391  ip6_header_t * ip6_0;
392  u16 version0;
393  int verr0;
394  u32 i0, next0;
395  u32 ip4_tun_src0, ip4_tun_dst0;
396  u32 ip6_tun_src0[4], ip6_tun_dst0[4];
397 
398  bi0 = from[0];
399  to_next[0] = bi0;
400  from += 1;
401  to_next += 1;
402  n_left_from -= 1;
403  n_left_to_next -= 1;
404 
405  b0 = vlib_get_buffer (vm, bi0);
406  ip4_0 = vlib_buffer_get_current (b0);
407  ip6_0 = (void *)ip4_0;
408 
409  if (!is_ipv6)
410  {
411  ip4_tun_src0 = ip4_0->src_address.as_u32;
412  ip4_tun_dst0 = ip4_0->dst_address.as_u32;
413 
414  vlib_buffer_advance (b0, sizeof (*ip4_0));
415  }
416  else
417  {
418  ip6_tun_src0[0] = ip6_0->src_address.as_u64[0];
419  ip6_tun_src0[1] = ip6_0->src_address.as_u64[1];
420  ip6_tun_dst0[0] = ip6_0->dst_address.as_u64[0];
421  ip6_tun_dst0[1] = ip6_0->dst_address.as_u64[1];
422 
423  vlib_buffer_advance (b0, sizeof (*ip6_0));
424  }
425 
426  h0 = vlib_buffer_get_current (b0);
427 
429  next0 = vec_elt(gm->next_by_protocol, i0);
430 
431  b0->error =
432  node->errors[i0 == SPARSE_VEC_INVALID_INDEX
433  ? GRE_ERROR_UNKNOWN_PROTOCOL : GRE_ERROR_NONE];
434 
435  version0 = clib_net_to_host_u16 (h0->flags_and_version);
436  verr0 = version0 & GRE_VERSION_MASK;
437  b0->error = verr0 ? node->errors[GRE_ERROR_UNSUPPORTED_VERSION]
438  : b0->error;
439  next0 = verr0 ? GRE_INPUT_NEXT_DROP : next0;
440 
441 
442  /* For IP payload we need to find source interface
443  so we can increase counters and help forward node to
444  pick right FIB */
445  /* RPF check for ip4/ip6 input */
446  if (PREDICT_TRUE(next0 == GRE_INPUT_NEXT_IP4_INPUT
447  || next0 == GRE_INPUT_NEXT_IP6_INPUT
448  || next0 == GRE_INPUT_NEXT_ETHERNET_INPUT
449  || next0 == GRE_INPUT_NEXT_MPLS_INPUT))
450  {
451  u64 key4, key6[4];
452  if (!is_ipv6)
453  {
454  key4 = ((u64)(ip4_tun_dst0) << 32) | (u64)(ip4_tun_src0);
455  }
456  else
457  {
458  key6[0] = ip6_tun_dst0[0];
459  key6[1] = ip6_tun_dst0[1];
460  key6[2] = ip6_tun_src0[0];
461  key6[3] = ip6_tun_src0[1];
462  }
463 
464  if ((!is_ipv6 && cached_tunnel_key4 != key4) ||
465  (is_ipv6 && cached_tunnel_key6[0] != key6[0] &&
466  cached_tunnel_key6[1] != key6[1] &&
467  cached_tunnel_key6[2] != key6[2] &&
468  cached_tunnel_key6[3] != key6[3]))
469  {
471  gre_tunnel_t * t;
472  uword * p;
473 
474  if (!is_ipv6)
475  p = hash_get (gm->tunnel_by_key4, key4);
476  else
477  p = hash_get_mem (gm->tunnel_by_key6, key6);
478 
479  if (!p)
480  {
481  next0 = GRE_INPUT_NEXT_DROP;
482  b0->error = node->errors[GRE_ERROR_NO_SUCH_TUNNEL];
483  goto drop;
484  }
485  t = pool_elt_at_index (gm->tunnels, p[0]);
487  t->hw_if_index);
488  tunnel_sw_if_index = hi->sw_if_index;
489 
490  cached_tunnel_sw_if_index = tunnel_sw_if_index;
491  }
492  else
493  {
494  tunnel_sw_if_index = cached_tunnel_sw_if_index;
495  }
496  }
497  else
498  {
499  next0 = GRE_INPUT_NEXT_DROP;
500  goto drop;
501  }
502  len = vlib_buffer_length_in_chain (vm, b0);
505  thread_index,
506  tunnel_sw_if_index,
507  1 /* packets */,
508  len /* bytes */);
509 
510  vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
511 
512 drop:
514  {
515  gre_rx_trace_t *tr = vlib_add_trace (vm, node,
516  b0, sizeof (*tr));
517  tr->tunnel_id = tunnel_sw_if_index;
518  if (!is_ipv6)
519  {
520  tr->length = ip4_0->length;
521  tr->src.ip4.as_u32 = ip4_0->src_address.as_u32;
522  tr->dst.ip4.as_u32 = ip4_0->dst_address.as_u32;
523  }
524  else
525  {
526  tr->length = ip6_0->payload_length;
527  tr->src.ip6.as_u64[0] = ip6_0->src_address.as_u64[0];
528  tr->src.ip6.as_u64[1] = ip6_0->src_address.as_u64[1];
529  tr->dst.ip6.as_u64[0] = ip6_0->dst_address.as_u64[0];
530  tr->dst.ip6.as_u64[1] = ip6_0->dst_address.as_u64[1];
531  }
532  }
533 
534  vlib_buffer_advance (b0, sizeof (*h0));
535 
536  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
537  to_next, n_left_to_next,
538  bi0, next0);
539  }
540 
541  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
542  }
543  vlib_node_increment_counter (vm, !is_ipv6 ? gre4_input_node.index : gre6_input_node.index,
544  GRE_ERROR_PKTS_DECAP, from_frame->n_vectors);
545  return from_frame->n_vectors;
546 }
547 
548 static uword
550  vlib_node_runtime_t * node,
551  vlib_frame_t * from_frame)
552 {
553  return gre_input(vm, node, from_frame, /* is_ip6 */ 0);
554 }
555 
556 static uword
558  vlib_node_runtime_t * node,
559  vlib_frame_t * from_frame)
560 {
561  return gre_input(vm, node, from_frame, /* is_ip6 */ 1);
562 }
563 
564 static char * gre_error_strings[] = {
565 #define gre_error(n,s) s,
566 #include "error.def"
567 #undef gre_error
568 };
569 
571  .function = gre4_input,
572  .name = "gre4-input",
573  /* Takes a vector of packets. */
574  .vector_size = sizeof (u32),
575 
576  .n_errors = GRE_N_ERROR,
577  .error_strings = gre_error_strings,
578 
579  .n_next_nodes = GRE_INPUT_N_NEXT,
580  .next_nodes = {
581 #define _(s,n) [GRE_INPUT_NEXT_##s] = n,
583 #undef _
584  },
585 
586  .format_buffer = format_gre_header_with_length,
587  .format_trace = format_gre_rx_trace,
588  .unformat_buffer = unformat_gre_header,
589 };
590 
592  .function = gre6_input,
593  .name = "gre6-input",
594  /* Takes a vector of packets. */
595  .vector_size = sizeof (u32),
596 
597  .runtime_data_bytes = sizeof (gre_input_runtime_t),
598 
599  .n_errors = GRE_N_ERROR,
600  .error_strings = gre_error_strings,
601 
602  .n_next_nodes = GRE_INPUT_N_NEXT,
603  .next_nodes = {
604 #define _(s,n) [GRE_INPUT_NEXT_##s] = n,
606 #undef _
607  },
608 
609  .format_buffer = format_gre_header_with_length,
610  .format_trace = format_gre_rx_trace,
611  .unformat_buffer = unformat_gre_header,
612 };
613 
616 
617 void
619  gre_protocol_t protocol,
620  u32 node_index)
621 {
622  gre_main_t * em = &gre_main;
623  gre_protocol_info_t * pi;
624  u16 * n;
625  u32 i;
626 
627  {
629  if (error)
630  clib_error_report (error);
631  }
632 
633  pi = gre_get_protocol_info (em, protocol);
634  pi->node_index = node_index;
635  pi->next_index = vlib_node_add_next (vm, gre4_input_node.index, node_index);
636  i = vlib_node_add_next (vm, gre6_input_node.index, node_index);
637  ASSERT(i == pi->next_index);
638 
639  /* Setup gre protocol -> next index sparse vector mapping. */
641  clib_host_to_net_u16 (protocol));
642  n[0] = pi->next_index;
643 }
644 
645 static void
646 gre_setup_node (vlib_main_t * vm, u32 node_index)
647 {
648  vlib_node_t * n = vlib_get_node (vm, node_index);
649  pg_node_t * pn = pg_get_node (node_index);
650 
654 }
655 
657 {
658  gre_main_t * gm = &gre_main;
659  vlib_node_t *ethernet_input, *ip4_input, *ip6_input, *mpls_unicast_input;
660 
661  {
662  clib_error_t * error;
663  error = vlib_call_init_function (vm, gre_init);
664  if (error)
665  clib_error_report (error);
666  }
667 
668  gre_setup_node (vm, gre4_input_node.index);
669  gre_setup_node (vm, gre6_input_node.index);
670 
672  (/* elt bytes */ sizeof (gm->next_by_protocol[0]),
673  /* bits in index */ BITS (((gre_header_t *) 0)->protocol));
674 
675  /* These could be moved to the supported protocol input node defn's */
676  ethernet_input = vlib_get_node_by_name (vm, (u8 *)"ethernet-input");
677  ASSERT(ethernet_input);
678  ip4_input = vlib_get_node_by_name (vm, (u8 *)"ip4-input");
679  ASSERT(ip4_input);
680  ip6_input = vlib_get_node_by_name (vm, (u8 *)"ip6-input");
681  ASSERT(ip6_input);
682  mpls_unicast_input = vlib_get_node_by_name (vm, (u8 *)"mpls-input");
683  ASSERT(mpls_unicast_input);
684 
685  gre_register_input_protocol (vm, GRE_PROTOCOL_teb,
686  ethernet_input->index);
687 
688  gre_register_input_protocol (vm, GRE_PROTOCOL_ip4,
689  ip4_input->index);
690 
691  gre_register_input_protocol (vm, GRE_PROTOCOL_ip6,
692  ip6_input->index);
693 
694  gre_register_input_protocol (vm, GRE_PROTOCOL_mpls_unicast,
695  mpls_unicast_input->index);
696 
697  ip4_register_protocol (IP_PROTOCOL_GRE, gre4_input_node.index);
698  ip6_register_protocol (IP_PROTOCOL_GRE, gre6_input_node.index);
699 
700  return 0;
701 }
702 
vnet_main_t * vnet_main
Definition: gre.h:172
vmrglw vmrglh hi
uword * tunnel_by_key6
Hash mapping ipv6 src/dst addr pair to tunnel.
Definition: gre.h:152
GRE related global data.
Definition: gre.h:128
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
format_function_t format_gre_header_with_length
Definition: gre.h:217
#define CLIB_UNUSED(x)
Definition: clib.h:79
u32 hw_if_index
Definition: gre.h:97
static uword gre4_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: node.c:549
static uword ip4_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
IPv4 input node.
Definition: ip4_input.c:397
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:211
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1589
ip4_address_t src_address
Definition: ip4_packet.h:164
vnet_interface_main_t interface_main
Definition: vnet.h:56
#define PREDICT_TRUE(x)
Definition: clib.h:98
u64 as_u64[2]
Definition: ip6_packet.h:51
u32 index
Definition: node.h:238
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:459
A GRE payload protocol registration.
Definition: gre.h:40
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
format_function_t format_ip46_address
Definition: format.h:61
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
u16 * next_by_protocol
Definition: node.c:63
u32 tunnel_id
Definition: node.c:40
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1959
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:419
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:100
ip6_address_t src_address
Definition: ip6_packet.h:341
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1081
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:350
vlib_node_registration_t gre6_input_node
(constructor) VLIB_REGISTER_NODE (gre6_input_node)
Definition: node.c:591
static void gre_setup_node(vlib_main_t *vm, u32 node_index)
Definition: node.c:646
u8 is_ipv6
Definition: node.c:44
#define foreach_gre_input_next
Definition: node.c:24
static char * gre_error_strings[]
Definition: node.c:564
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define always_inline
Definition: clib.h:84
ip4_address_t dst_address
Definition: ip4_packet.h:164
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:653
#define sparse_vec_validate(v, i)
Definition: sparse_vec.h:214
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:164
#define GRE_VERSION_MASK
Definition: packet.h:49
unsigned long u64
Definition: types.h:89
static uword gre_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, u8 is_ipv6)
Definition: node.c:67
gre_input_next_t
Definition: node.c:32
ip46_address_t dst
Definition: node.c:43
static void sparse_vec_index2(void *v, u32 si0, u32 si1, u32 *i0_return, u32 *i1_return)
Definition: sparse_vec.h:160
unformat_function_t unformat_gre_header
Definition: gre.h:230
#define vlib_call_init_function(vm, x)
Definition: init.h:162
u8 * format_gre_rx_trace(u8 *s, va_list *args)
Definition: node.c:47
#define hash_get(h, key)
Definition: hash.h:248
uword * tunnel_by_key4
Hash mapping ipv4 src/dst addr pair to tunnel.
Definition: gre.h:147
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
A representation of a GRE tunnel.
Definition: gre.h:79
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:188
u32 node_index
Node which handles this type.
Definition: gre.h:48
#define PREDICT_FALSE(x)
Definition: clib.h:97
u32 length
Definition: node.c:41
format_function_t * format_buffer
Definition: node.h:312
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:216
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:366
u16 flags_and_version
Definition: packet.h:37
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:113
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1131
static clib_error_t * gre_input_init(vlib_main_t *vm)
Definition: node.c:656
static clib_error_t * gre_init(vlib_main_t *vm)
Definition: gre.c:478
u16 n_vectors
Definition: node.h:345
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:185
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
u16 protocol
Definition: packet.h:52
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:85
gre_protocol_t
Definition: packet.h:29
unformat_function_t * unformat_buffer
Definition: node.h:313
unformat_function_t * unformat_edit
Definition: pg.h:307
ip46_address_t src
Definition: node.c:42
vlib_node_registration_t gre4_input_node
(constructor) VLIB_REGISTER_NODE (gre4_input_node)
Definition: node.c:570
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
static uword sparse_vec_index(void *v, uword sparse_index)
Definition: sparse_vec.h:152
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:460
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u16 * next_by_protocol
Definition: gre.h:168
u32 next_index
Next index for this type.
Definition: gre.h:51
gre_tunnel_t * tunnels
pool of tunnel instances
Definition: gre.h:132
#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:201
u64 uword
Definition: types.h:112
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.
void gre_register_input_protocol(vlib_main_t *vm, gre_protocol_t protocol, u32 node_index)
Definition: node.c:618
unsigned short u16
Definition: types.h:57
u16 payload_length
Definition: ip6_packet.h:332
unsigned char u8
Definition: types.h:56
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:269
unformat_function_t unformat_pg_gre_header
Definition: gre.h:231
static uword ethernet_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: node.c:753
#define hash_get_mem(h, key)
Definition: hash.h:268
#define vnet_buffer(b)
Definition: buffer.h:304
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:144
u8 data[0]
Packet data.
Definition: buffer.h:152
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:58
static uword gre6_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: node.c:557
static gre_protocol_info_t * gre_get_protocol_info(gre_main_t *em, gre_protocol_t protocol)
Definition: gre.h:192
static uword ip6_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: ip6_input.c:75
static void * sparse_vec_new(uword elt_bytes, uword sparse_index_bits)
Definition: sparse_vec.h:71
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:74
#define BITS(x)
Definition: clib.h:58
gre_main_t gre_main
Definition: gre.c:22
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
Definition: pg.h:304
VLIB_NODE_FUNCTION_MULTIARCH(ethernet_input_not_l2_node, ethernet_input_not_l2)
Definition: node.c:1175
Definition: defs.h:46
ip6_address_t dst_address
Definition: ip6_packet.h:341
#define SPARSE_VEC_INVALID_INDEX
Definition: sparse_vec.h:68