FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
decap.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 SUSE LLC.
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 #include <vlib/vlib.h>
17 #include <vnet/pg/pg.h>
18 #include <vnet/geneve/geneve.h>
19 
20 typedef struct
21 {
27 
28 static u8 *
29 format_geneve_rx_trace (u8 * s, va_list * args)
30 {
31  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
32  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
33  geneve_rx_trace_t *t = va_arg (*args, geneve_rx_trace_t *);
34 
35  if (t->tunnel_index != ~0)
36  {
37  s =
38  format (s,
39  "GENEVE decap from geneve_tunnel%d vni %d next %d error %d",
40  t->tunnel_index, t->vni_rsvd, t->next_index, t->error);
41  }
42  else
43  {
44  s = format (s, "GENEVE decap error - tunnel for vni %d does not exist",
45  t->vni_rsvd);
46  }
47  return s;
48 }
49 
52 {
53  u32 fib_index, sw_if_index;
54 
55  sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
56 
57  if (is_ip4)
58  fib_index = (vnet_buffer (b)->sw_if_index[VLIB_TX] == (u32) ~ 0) ?
60  vnet_buffer (b)->sw_if_index[VLIB_TX];
61  else
62  fib_index = (vnet_buffer (b)->sw_if_index[VLIB_TX] == (u32) ~ 0) ?
64  vnet_buffer (b)->sw_if_index[VLIB_TX];
65 
66  return (fib_index == t->encap_fib_index);
67 }
68 
72  vlib_frame_t * from_frame, u32 is_ip4)
73 {
74  u32 n_left_from, next_index, *from, *to_next;
75  geneve_main_t *vxm = &geneve_main;
76  vnet_main_t *vnm = vxm->vnet_main;
78  u32 last_tunnel_index = ~0;
79  geneve4_tunnel_key_t last_key4;
80  geneve6_tunnel_key_t last_key6;
81  u32 pkts_decapsulated = 0;
82  u32 thread_index = vm->thread_index;
83  u32 stats_sw_if_index, stats_n_packets, stats_n_bytes;
84  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
85 
86  if (is_ip4)
87  last_key4.as_u64 = ~0;
88  else
89  clib_memset (&last_key6, 0xff, sizeof (last_key6));
90 
91  from = vlib_frame_vector_args (from_frame);
92  n_left_from = from_frame->n_vectors;
93  vlib_get_buffers (vm, from, bufs, n_left_from);
94 
95  next_index = node->cached_next_index;
96  stats_sw_if_index = node->runtime_data[0];
97  stats_n_packets = stats_n_bytes = 0;
98 
99  while (n_left_from > 0)
100  {
101  u32 n_left_to_next;
102 
103  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
104  while (n_left_from >= 4 && n_left_to_next >= 2)
105  {
106  u32 bi0, bi1;
107  vlib_buffer_t *b0, *b1;
108  u32 next0, next1;
109  ip4_header_t *ip4_0, *ip4_1;
110  ip6_header_t *ip6_0, *ip6_1;
111  geneve_header_t *geneve0, *geneve1;
112  uword *p0, *p1;
113  u32 tunnel_index0, tunnel_index1;
114  geneve_tunnel_t *t0, *t1, *mt0 = NULL, *mt1 = NULL;
115  geneve4_tunnel_key_t key4_0, key4_1;
116  geneve6_tunnel_key_t key6_0, key6_1;
117  u32 error0, error1;
118  u32 sw_if_index0, sw_if_index1, len0, len1;
119 
120  /* Prefetch next iteration. */
121  {
122  vlib_prefetch_buffer_header (b[2], LOAD);
123  vlib_prefetch_buffer_header (b[3], LOAD);
124 
125  CLIB_PREFETCH (b[2]->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
126  CLIB_PREFETCH (b[3]->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
127  }
128 
129  bi0 = from[0];
130  bi1 = from[1];
131  to_next[0] = bi0;
132  to_next[1] = bi1;
133  from += 2;
134  to_next += 2;
135  n_left_to_next -= 2;
136  n_left_from -= 2;
137 
138  b0 = b[0];
139  b1 = b[1];
140  b += 2;
141 
142  /* udp leaves current_data pointing at the geneve header */
143  geneve0 = vlib_buffer_get_current (b0);
144  geneve1 = vlib_buffer_get_current (b1);
145 
146  vnet_geneve_hdr_1word_ntoh (geneve0);
147  vnet_geneve_hdr_1word_ntoh (geneve1);
148 
149  if (is_ip4)
150  {
152  (b0, -(word) (sizeof (udp_header_t) + sizeof (ip4_header_t)));
154  (b1, -(word) (sizeof (udp_header_t) + sizeof (ip4_header_t)));
155  ip4_0 = vlib_buffer_get_current (b0);
156  ip4_1 = vlib_buffer_get_current (b1);
157  }
158  else
159  {
161  (b0, -(word) (sizeof (udp_header_t) + sizeof (ip6_header_t)));
163  (b1, -(word) (sizeof (udp_header_t) + sizeof (ip6_header_t)));
164  ip6_0 = vlib_buffer_get_current (b0);
165  ip6_1 = vlib_buffer_get_current (b1);
166  }
167 
168  /* pop (ip, udp, geneve) */
169  if (is_ip4)
170  {
172  sizeof (*ip4_0) + sizeof (udp_header_t) +
174  vnet_get_geneve_options_len (geneve0));
176  sizeof (*ip4_1) + sizeof (udp_header_t) +
178  vnet_get_geneve_options_len (geneve1));
179  }
180  else
181  {
183  sizeof (*ip6_0) + sizeof (udp_header_t) +
185  vnet_get_geneve_options_len (geneve0));
187  sizeof (*ip6_1) + sizeof (udp_header_t) +
189  vnet_get_geneve_options_len (geneve1));
190  }
191 
192  tunnel_index0 = ~0;
193  error0 = 0;
194 
195  tunnel_index1 = ~0;
196  error1 = 0;
197 
198  if (PREDICT_FALSE
200  {
201  error0 = GENEVE_ERROR_BAD_FLAGS;
202  next0 = GENEVE_INPUT_NEXT_DROP;
203  goto trace0;
204  }
205 #if SUPPORT_OPTIONS_HEADER==1
206  if (PREDICT_FALSE (vnet_get_geneve_critical_bit (geneve0) == 1))
207  {
208  error0 = GENEVE_ERROR_BAD_FLAGS;
209  next0 = GENEVE_INPUT_NEXT_DROP;
210  goto trace0;
211  }
212 #endif
213  if (is_ip4)
214  {
215  key4_0.remote = ip4_0->src_address.as_u32;
216  key4_0.vni = vnet_get_geneve_vni_network_order (geneve0);
217 
218  /* Make sure GENEVE tunnel exist according to packet SIP and VNI */
219  if (PREDICT_FALSE (key4_0.as_u64 != last_key4.as_u64))
220  {
221  p0 = hash_get (vxm->geneve4_tunnel_by_key, key4_0.as_u64);
222  if (PREDICT_FALSE (p0 == NULL))
223  {
224  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
225  next0 = GENEVE_INPUT_NEXT_DROP;
226  goto trace0;
227  }
228  last_key4.as_u64 = key4_0.as_u64;
229  tunnel_index0 = last_tunnel_index = p0[0];
230  }
231  else
232  tunnel_index0 = last_tunnel_index;
233  t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0);
234 
235  /* Validate GENEVE tunnel encap-fib index against packet */
236  if (PREDICT_FALSE (validate_geneve_fib (b0, t0, is_ip4) == 0))
237  {
238  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
239  next0 = GENEVE_INPUT_NEXT_DROP;
240  goto trace0;
241  }
242 
243  /* Validate GENEVE tunnel SIP against packet DIP */
244  if (PREDICT_TRUE
245  (ip4_0->dst_address.as_u32 == t0->local.ip4.as_u32))
246  goto next0; /* valid packet */
247  if (PREDICT_FALSE
249  {
250  key4_0.remote = ip4_0->dst_address.as_u32;
251  key4_0.vni = vnet_get_geneve_vni_network_order (geneve0);
252  /* Make sure mcast GENEVE tunnel exist by packet DIP and VNI */
253  p0 = hash_get (vxm->geneve4_tunnel_by_key, key4_0.as_u64);
254  if (PREDICT_TRUE (p0 != NULL))
255  {
256  mt0 = pool_elt_at_index (vxm->tunnels, p0[0]);
257  goto next0; /* valid packet */
258  }
259  }
260  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
261  next0 = GENEVE_INPUT_NEXT_DROP;
262  goto trace0;
263 
264  }
265  else /* !is_ip4 */
266  {
267  key6_0.remote.as_u64[0] = ip6_0->src_address.as_u64[0];
268  key6_0.remote.as_u64[1] = ip6_0->src_address.as_u64[1];
269  key6_0.vni = vnet_get_geneve_vni_network_order (geneve0);
270 
271  /* Make sure GENEVE tunnel exist according to packet SIP and VNI */
272  if (PREDICT_FALSE
273  (memcmp (&key6_0, &last_key6, sizeof (last_key6)) != 0))
274  {
275  p0 = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6_0);
276  if (PREDICT_FALSE (p0 == NULL))
277  {
278  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
279  next0 = GENEVE_INPUT_NEXT_DROP;
280  goto trace0;
281  }
282  clib_memcpy_fast (&last_key6, &key6_0, sizeof (key6_0));
283  tunnel_index0 = last_tunnel_index = p0[0];
284  }
285  else
286  tunnel_index0 = last_tunnel_index;
287  t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0);
288 
289  /* Validate GENEVE tunnel encap-fib index against packet */
290  if (PREDICT_FALSE (validate_geneve_fib (b0, t0, is_ip4) == 0))
291  {
292  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
293  next0 = GENEVE_INPUT_NEXT_DROP;
294  goto trace0;
295  }
296 
297  /* Validate GENEVE tunnel SIP against packet DIP */
299  &t0->local.ip6)))
300  goto next0; /* valid packet */
301  if (PREDICT_FALSE
303  {
304  key6_0.remote.as_u64[0] = ip6_0->dst_address.as_u64[0];
305  key6_0.remote.as_u64[1] = ip6_0->dst_address.as_u64[1];
306  key6_0.vni = vnet_get_geneve_vni_network_order (geneve0);
307  p0 = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6_0);
308  if (PREDICT_TRUE (p0 != NULL))
309  {
310  mt0 = pool_elt_at_index (vxm->tunnels, p0[0]);
311  goto next0; /* valid packet */
312  }
313  }
314  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
315  next0 = GENEVE_INPUT_NEXT_DROP;
316  goto trace0;
317  }
318 
319  next0:
320  next0 = t0->decap_next_index;
321  sw_if_index0 = t0->sw_if_index;
322  len0 = vlib_buffer_length_in_chain (vm, b0);
323 
324  /* Required to make the l2 tag push / pop code work on l2 subifs */
325  if (PREDICT_TRUE (next0 == GENEVE_INPUT_NEXT_L2_INPUT))
326  vnet_update_l2_len (b0);
327 
328  /* Set packet input sw_if_index to unicast GENEVE tunnel for learning */
329  vnet_buffer (b0)->sw_if_index[VLIB_RX] = sw_if_index0;
330  sw_if_index0 = (mt0) ? mt0->sw_if_index : sw_if_index0;
331 
332  pkts_decapsulated++;
333  stats_n_packets += 1;
334  stats_n_bytes += len0;
335 
336  /* Batch stats increment on the same geneve tunnel so counter
337  is not incremented per packet */
338  if (PREDICT_FALSE (sw_if_index0 != stats_sw_if_index))
339  {
340  stats_n_packets -= 1;
341  stats_n_bytes -= len0;
342  if (stats_n_packets)
345  thread_index, stats_sw_if_index,
346  stats_n_packets, stats_n_bytes);
347  stats_n_packets = 1;
348  stats_n_bytes = len0;
349  stats_sw_if_index = sw_if_index0;
350  }
351 
352  trace0:
353  b0->error = error0 ? node->errors[error0] : 0;
354 
355  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
356  {
358  = vlib_add_trace (vm, node, b0, sizeof (*tr));
359  tr->next_index = next0;
360  tr->error = error0;
361  tr->tunnel_index = tunnel_index0;
362  tr->vni_rsvd = vnet_get_geneve_vni (geneve0);
363  }
364 
365  if (PREDICT_FALSE
367  {
368  error1 = GENEVE_ERROR_BAD_FLAGS;
369  next1 = GENEVE_INPUT_NEXT_DROP;
370  goto trace1;
371  }
372 #if SUPPORT_OPTIONS_HEADER==1
373  if (PREDICT_FALSE (vnet_get_geneve_critical_bit (geneve1) == 1))
374  {
375  error1 = GENEVE_ERROR_BAD_FLAGS;
376  next1 = GENEVE_INPUT_NEXT_DROP;
377  goto trace1;
378  }
379 #endif
380  if (is_ip4)
381  {
382  key4_1.remote = ip4_1->src_address.as_u32;
383  key4_1.vni = vnet_get_geneve_vni_network_order (geneve1);
384 
385  /* Make sure unicast GENEVE tunnel exist by packet SIP and VNI */
386  if (PREDICT_FALSE (key4_1.as_u64 != last_key4.as_u64))
387  {
388  p1 = hash_get (vxm->geneve4_tunnel_by_key, key4_1.as_u64);
389  if (PREDICT_FALSE (p1 == NULL))
390  {
391  error1 = GENEVE_ERROR_NO_SUCH_TUNNEL;
392  next1 = GENEVE_INPUT_NEXT_DROP;
393  goto trace1;
394  }
395  last_key4.as_u64 = key4_1.as_u64;
396  tunnel_index1 = last_tunnel_index = p1[0];
397  }
398  else
399  tunnel_index1 = last_tunnel_index;
400  t1 = pool_elt_at_index (vxm->tunnels, tunnel_index1);
401 
402  /* Validate GENEVE tunnel encap-fib index against packet */
403  if (PREDICT_FALSE (validate_geneve_fib (b1, t1, is_ip4) == 0))
404  {
405  error1 = GENEVE_ERROR_NO_SUCH_TUNNEL;
406  next1 = GENEVE_INPUT_NEXT_DROP;
407  goto trace1;
408  }
409 
410  /* Validate GENEVE tunnel SIP against packet DIP */
411  if (PREDICT_TRUE
412  (ip4_1->dst_address.as_u32 == t1->local.ip4.as_u32))
413  goto next1; /* valid packet */
414  if (PREDICT_FALSE
416  {
417  key4_1.remote = ip4_1->dst_address.as_u32;
418  key4_1.vni = vnet_get_geneve_vni_network_order (geneve1);
419  /* Make sure mcast GENEVE tunnel exist by packet DIP and VNI */
420  p1 = hash_get (vxm->geneve4_tunnel_by_key, key4_1.as_u64);
421  if (PREDICT_TRUE (p1 != NULL))
422  {
423  mt1 = pool_elt_at_index (vxm->tunnels, p1[0]);
424  goto next1; /* valid packet */
425  }
426  }
427  error1 = GENEVE_ERROR_NO_SUCH_TUNNEL;
428  next1 = GENEVE_INPUT_NEXT_DROP;
429  goto trace1;
430 
431  }
432  else /* !is_ip4 */
433  {
434  key6_1.remote.as_u64[0] = ip6_1->src_address.as_u64[0];
435  key6_1.remote.as_u64[1] = ip6_1->src_address.as_u64[1];
436  key6_1.vni = vnet_get_geneve_vni_network_order (geneve1);
437 
438  /* Make sure GENEVE tunnel exist according to packet SIP and VNI */
439  if (PREDICT_FALSE
440  (memcmp (&key6_1, &last_key6, sizeof (last_key6)) != 0))
441  {
442  p1 = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6_1);
443 
444  if (PREDICT_FALSE (p1 == NULL))
445  {
446  error1 = GENEVE_ERROR_NO_SUCH_TUNNEL;
447  next1 = GENEVE_INPUT_NEXT_DROP;
448  goto trace1;
449  }
450 
451  clib_memcpy_fast (&last_key6, &key6_1, sizeof (key6_1));
452  tunnel_index1 = last_tunnel_index = p1[0];
453  }
454  else
455  tunnel_index1 = last_tunnel_index;
456  t1 = pool_elt_at_index (vxm->tunnels, tunnel_index1);
457 
458  /* Validate GENEVE tunnel encap-fib index against packet */
459  if (PREDICT_FALSE (validate_geneve_fib (b1, t1, is_ip4) == 0))
460  {
461  error1 = GENEVE_ERROR_NO_SUCH_TUNNEL;
462  next1 = GENEVE_INPUT_NEXT_DROP;
463  goto trace1;
464  }
465 
466  /* Validate GENEVE tunnel SIP against packet DIP */
468  &t1->local.ip6)))
469  goto next1; /* valid packet */
470  if (PREDICT_FALSE
472  {
473  key6_1.remote.as_u64[0] = ip6_1->dst_address.as_u64[0];
474  key6_1.remote.as_u64[1] = ip6_1->dst_address.as_u64[1];
475  key6_1.vni = vnet_get_geneve_vni_network_order (geneve1);
476  p1 = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6_1);
477  if (PREDICT_TRUE (p1 != NULL))
478  {
479  mt1 = pool_elt_at_index (vxm->tunnels, p1[0]);
480  goto next1; /* valid packet */
481  }
482  }
483  error1 = GENEVE_ERROR_NO_SUCH_TUNNEL;
484  next1 = GENEVE_INPUT_NEXT_DROP;
485  goto trace1;
486  }
487 
488  next1:
489  next1 = t1->decap_next_index;
490  sw_if_index1 = t1->sw_if_index;
491  len1 = vlib_buffer_length_in_chain (vm, b1);
492 
493  /* Required to make the l2 tag push / pop code work on l2 subifs */
494  if (PREDICT_TRUE (next1 == GENEVE_INPUT_NEXT_L2_INPUT))
495  vnet_update_l2_len (b1);
496 
497  /* Set packet input sw_if_index to unicast GENEVE tunnel for learning */
498  vnet_buffer (b1)->sw_if_index[VLIB_RX] = sw_if_index1;
499  sw_if_index1 = (mt1) ? mt1->sw_if_index : sw_if_index1;
500 
501  pkts_decapsulated++;
502  stats_n_packets += 1;
503  stats_n_bytes += len1;
504 
505  /* Batch stats increment on the same geneve tunnel so counter
506  is not incremented per packet */
507  if (PREDICT_FALSE (sw_if_index1 != stats_sw_if_index))
508  {
509  stats_n_packets -= 1;
510  stats_n_bytes -= len1;
511  if (stats_n_packets)
514  thread_index, stats_sw_if_index,
515  stats_n_packets, stats_n_bytes);
516  stats_n_packets = 1;
517  stats_n_bytes = len1;
518  stats_sw_if_index = sw_if_index1;
519  }
520 
521  trace1:
522  b1->error = error1 ? node->errors[error1] : 0;
523 
524  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
525  {
527  = vlib_add_trace (vm, node, b1, sizeof (*tr));
528  tr->next_index = next1;
529  tr->error = error1;
530  tr->tunnel_index = tunnel_index1;
531  tr->vni_rsvd = vnet_get_geneve_vni (geneve1);
532  }
533 
534  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
535  to_next, n_left_to_next,
536  bi0, bi1, next0, next1);
537  }
538 
539  while (n_left_from > 0 && n_left_to_next > 0)
540  {
541  u32 bi0;
542  vlib_buffer_t *b0;
543  u32 next0;
544  ip4_header_t *ip4_0;
545  ip6_header_t *ip6_0;
546  geneve_header_t *geneve0;
547  uword *p0;
548  u32 tunnel_index0;
549  geneve_tunnel_t *t0, *mt0 = NULL;
550  geneve4_tunnel_key_t key4_0;
551  geneve6_tunnel_key_t key6_0;
552  u32 error0;
553  u32 sw_if_index0, len0;
554 
555  bi0 = from[0];
556  to_next[0] = bi0;
557  from += 1;
558  to_next += 1;
559  n_left_from -= 1;
560  n_left_to_next -= 1;
561 
562  b0 = b[0];
563  b += 1;
564 
565  /* udp leaves current_data pointing at the geneve header */
566  geneve0 = vlib_buffer_get_current (b0);
567  vnet_geneve_hdr_1word_ntoh (geneve0);
568 
569  if (is_ip4)
570  {
572  (b0, -(word) (sizeof (udp_header_t) + sizeof (ip4_header_t)));
573  ip4_0 = vlib_buffer_get_current (b0);
574  }
575  else
576  {
578  (b0, -(word) (sizeof (udp_header_t) + sizeof (ip6_header_t)));
579  ip6_0 = vlib_buffer_get_current (b0);
580  }
581 
582  /* pop (ip, udp, geneve) */
583  if (is_ip4)
584  {
586  (b0,
587  sizeof (*ip4_0) + sizeof (udp_header_t) +
589  vnet_get_geneve_options_len (geneve0));
590  }
591  else
592  {
594  (b0,
595  sizeof (*ip6_0) + sizeof (udp_header_t) +
597  vnet_get_geneve_options_len (geneve0));
598  }
599 
600  tunnel_index0 = ~0;
601  error0 = 0;
602 
603  if (PREDICT_FALSE
605  {
606  error0 = GENEVE_ERROR_BAD_FLAGS;
607  next0 = GENEVE_INPUT_NEXT_DROP;
608  goto trace00;
609  }
610 #if SUPPORT_OPTIONS_HEADER==1
611  if (PREDICT_FALSE (vnet_get_geneve_critical_bit (geneve0) == 1))
612  {
613  error0 = GENEVE_ERROR_BAD_FLAGS;
614  next0 = GENEVE_INPUT_NEXT_DROP;
615  goto trace00;
616  }
617 #endif
618  if (is_ip4)
619  {
620  key4_0.remote = ip4_0->src_address.as_u32;
621  key4_0.vni = vnet_get_geneve_vni_network_order (geneve0);
622 
623  /* Make sure unicast GENEVE tunnel exist by packet SIP and VNI */
624  if (PREDICT_FALSE (key4_0.as_u64 != last_key4.as_u64))
625  {
626  p0 = hash_get (vxm->geneve4_tunnel_by_key, key4_0.as_u64);
627  if (PREDICT_FALSE (p0 == NULL))
628  {
629  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
630  next0 = GENEVE_INPUT_NEXT_DROP;
631  goto trace00;
632  }
633  last_key4.as_u64 = key4_0.as_u64;
634  tunnel_index0 = last_tunnel_index = p0[0];
635  }
636  else
637  tunnel_index0 = last_tunnel_index;
638  t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0);
639 
640  /* Validate GENEVE tunnel encap-fib index agaist packet */
641  if (PREDICT_FALSE (validate_geneve_fib (b0, t0, is_ip4) == 0))
642  {
643  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
644  next0 = GENEVE_INPUT_NEXT_DROP;
645  goto trace00;
646  }
647 
648  /* Validate GENEVE tunnel SIP against packet DIP */
649  if (PREDICT_TRUE
650  (ip4_0->dst_address.as_u32 == t0->local.ip4.as_u32))
651  goto next00; /* valid packet */
652  if (PREDICT_FALSE
654  {
655  key4_0.remote = ip4_0->dst_address.as_u32;
656  key4_0.vni = vnet_get_geneve_vni_network_order (geneve0);
657  /* Make sure mcast GENEVE tunnel exist by packet DIP and VNI */
658  p0 = hash_get (vxm->geneve4_tunnel_by_key, key4_0.as_u64);
659  if (PREDICT_TRUE (p0 != NULL))
660  {
661  mt0 = pool_elt_at_index (vxm->tunnels, p0[0]);
662  goto next00; /* valid packet */
663  }
664  }
665  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
666  next0 = GENEVE_INPUT_NEXT_DROP;
667  goto trace00;
668 
669  }
670  else /* !is_ip4 */
671  {
672  key6_0.remote.as_u64[0] = ip6_0->src_address.as_u64[0];
673  key6_0.remote.as_u64[1] = ip6_0->src_address.as_u64[1];
674  key6_0.vni = vnet_get_geneve_vni_network_order (geneve0);
675 
676  /* Make sure GENEVE tunnel exist according to packet SIP and VNI */
677  if (PREDICT_FALSE
678  (memcmp (&key6_0, &last_key6, sizeof (last_key6)) != 0))
679  {
680  p0 = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6_0);
681  if (PREDICT_FALSE (p0 == NULL))
682  {
683  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
684  next0 = GENEVE_INPUT_NEXT_DROP;
685  goto trace00;
686  }
687  clib_memcpy_fast (&last_key6, &key6_0, sizeof (key6_0));
688  tunnel_index0 = last_tunnel_index = p0[0];
689  }
690  else
691  tunnel_index0 = last_tunnel_index;
692  t0 = pool_elt_at_index (vxm->tunnels, tunnel_index0);
693 
694  /* Validate GENEVE tunnel encap-fib index agaist packet */
695  if (PREDICT_FALSE (validate_geneve_fib (b0, t0, is_ip4) == 0))
696  {
697  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
698  next0 = GENEVE_INPUT_NEXT_DROP;
699  goto trace00;
700  }
701 
702  /* Validate GENEVE tunnel SIP against packet DIP */
704  &t0->local.ip6)))
705  goto next00; /* valid packet */
706  if (PREDICT_FALSE
708  {
709  key6_0.remote.as_u64[0] = ip6_0->dst_address.as_u64[0];
710  key6_0.remote.as_u64[1] = ip6_0->dst_address.as_u64[1];
711  key6_0.vni = vnet_get_geneve_vni_network_order (geneve0);
712  p0 = hash_get_mem (vxm->geneve6_tunnel_by_key, &key6_0);
713  if (PREDICT_TRUE (p0 != NULL))
714  {
715  mt0 = pool_elt_at_index (vxm->tunnels, p0[0]);
716  goto next00; /* valid packet */
717  }
718  }
719  error0 = GENEVE_ERROR_NO_SUCH_TUNNEL;
720  next0 = GENEVE_INPUT_NEXT_DROP;
721  goto trace00;
722  }
723 
724  next00:
725  next0 = t0->decap_next_index;
726  sw_if_index0 = t0->sw_if_index;
727  len0 = vlib_buffer_length_in_chain (vm, b0);
728 
729  /* Required to make the l2 tag push / pop code work on l2 subifs */
730  if (PREDICT_TRUE (next0 == GENEVE_INPUT_NEXT_L2_INPUT))
731  vnet_update_l2_len (b0);
732 
733  /* Set packet input sw_if_index to unicast GENEVE tunnel for learning */
734  vnet_buffer (b0)->sw_if_index[VLIB_RX] = sw_if_index0;
735  sw_if_index0 = (mt0) ? mt0->sw_if_index : sw_if_index0;
736 
737  pkts_decapsulated++;
738  stats_n_packets += 1;
739  stats_n_bytes += len0;
740 
741  /* Batch stats increment on the same geneve tunnel so counter
742  is not incremented per packet */
743  if (PREDICT_FALSE (sw_if_index0 != stats_sw_if_index))
744  {
745  stats_n_packets -= 1;
746  stats_n_bytes -= len0;
747  if (stats_n_packets)
750  thread_index, stats_sw_if_index,
751  stats_n_packets, stats_n_bytes);
752  stats_n_packets = 1;
753  stats_n_bytes = len0;
754  stats_sw_if_index = sw_if_index0;
755  }
756 
757  trace00:
758  b0->error = error0 ? node->errors[error0] : 0;
759 
760  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
761  {
763  = vlib_add_trace (vm, node, b0, sizeof (*tr));
764  tr->next_index = next0;
765  tr->error = error0;
766  tr->tunnel_index = tunnel_index0;
767  tr->vni_rsvd = vnet_get_geneve_vni (geneve0);
768  }
769  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
770  to_next, n_left_to_next,
771  bi0, next0);
772  }
773 
774  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
775  }
776  /* Do we still need this now that tunnel tx stats is kept? */
777  vlib_node_increment_counter (vm, is_ip4 ?
779  index : geneve6_input_node.index,
780  GENEVE_ERROR_DECAPSULATED, pkts_decapsulated);
781 
782  /* Increment any remaining batch stats */
783  if (stats_n_packets)
784  {
787  thread_index, stats_sw_if_index, stats_n_packets, stats_n_bytes);
788  node->runtime_data[0] = stats_sw_if_index;
789  }
790 
791  return from_frame->n_vectors;
792 }
793 
796  vlib_frame_t * from_frame)
797 {
798  return geneve_input (vm, node, from_frame, /* is_ip4 */ 1);
799 }
800 
803  vlib_frame_t * from_frame)
804 {
805  return geneve_input (vm, node, from_frame, /* is_ip4 */ 0);
806 }
807 
808 static char *geneve_error_strings[] = {
809 #define geneve_error(n,s) s,
811 #undef geneve_error
812 #undef _
813 };
814 
815 /* *INDENT-OFF* */
817  .name = "geneve4-input",
818  /* Takes a vector of packets. */
819  .vector_size = sizeof (u32),
820  .n_errors = GENEVE_N_ERROR,
821  .error_strings = geneve_error_strings,
822  .n_next_nodes = GENEVE_INPUT_N_NEXT,
823  .next_nodes = {
824 #define _(s,n) [GENEVE_INPUT_NEXT_##s] = n,
826 #undef _
827  },
828 
829 //temp .format_buffer = format_geneve_header,
830  .format_trace = format_geneve_rx_trace,
831  // $$$$ .unformat_buffer = unformat_geneve_header,
832 };
833 
835  .name = "geneve6-input",
836  /* Takes a vector of packets. */
837  .vector_size = sizeof (u32),
838  .n_errors = GENEVE_N_ERROR,
839  .error_strings = geneve_error_strings,
840  .n_next_nodes = GENEVE_INPUT_N_NEXT,
841  .next_nodes = {
842 #define _(s,n) [GENEVE_INPUT_NEXT_##s] = n,
844 #undef _
845  },
846 //temp .format_buffer = format_geneve_header,
847  .format_trace = format_geneve_rx_trace,
848  // $$$$ .unformat_buffer = unformat_geneve_header,
849 };
850 /* *INDENT-ON* */
851 
852 typedef enum
853 {
858 
862  vlib_frame_t * frame, u32 is_ip4)
863 {
864  geneve_main_t *vxm = &geneve_main;
865  u32 *from, *to_next, n_left_from, n_left_to_next, next_index;
866  vlib_node_runtime_t *error_node =
868  vtep4_key_t last_vtep4; /* last IPv4 address / fib index
869  matching a local VTEP address */
870  vtep6_key_t last_vtep6; /* last IPv6 address / fib index
871  matching a local VTEP address */
872  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
873 #ifdef CLIB_HAVE_VEC512
874  vtep4_cache_t vtep4_u512;
875  clib_memset (&vtep4_u512, 0, sizeof (vtep4_u512));
876 #endif
877 
878  from = vlib_frame_vector_args (frame);
879  n_left_from = frame->n_vectors;
880  next_index = node->cached_next_index;
881 
882  vlib_get_buffers (vm, from, bufs, n_left_from);
883 
884  if (node->flags & VLIB_NODE_FLAG_TRACE)
885  ip4_forward_next_trace (vm, node, frame, VLIB_TX);
886 
887  if (is_ip4)
888  vtep4_key_init (&last_vtep4);
889  else
890  vtep6_key_init (&last_vtep6);
891 
892  while (n_left_from > 0)
893  {
894  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
895 
896  while (n_left_from >= 4 && n_left_to_next >= 2)
897  {
898  vlib_buffer_t *b0, *b1;
899  ip4_header_t *ip40, *ip41;
900  ip6_header_t *ip60, *ip61;
901  udp_header_t *udp0, *udp1;
902  u32 bi0, ip_len0, udp_len0, flags0, next0;
903  u32 bi1, ip_len1, udp_len1, flags1, next1;
904  i32 len_diff0, len_diff1;
905  u8 error0, good_udp0, proto0;
906  u8 error1, good_udp1, proto1;
907 
908  /* Prefetch next iteration. */
909  {
910  vlib_prefetch_buffer_header (b[2], LOAD);
911  vlib_prefetch_buffer_header (b[3], LOAD);
912 
913  CLIB_PREFETCH (b[2]->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
914  CLIB_PREFETCH (b[3]->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
915  }
916 
917  bi0 = to_next[0] = from[0];
918  bi1 = to_next[1] = from[1];
919  from += 2;
920  n_left_from -= 2;
921  to_next += 2;
922  n_left_to_next -= 2;
923 
924  b0 = b[0];
925  b1 = b[1];
926  b += 2;
927  if (is_ip4)
928  {
929  ip40 = vlib_buffer_get_current (b0);
930  ip41 = vlib_buffer_get_current (b1);
931  }
932  else
933  {
934  ip60 = vlib_buffer_get_current (b0);
935  ip61 = vlib_buffer_get_current (b1);
936  }
937 
938  /* Setup packet for next IP feature */
939  vnet_feature_next (&next0, b0);
940  vnet_feature_next (&next1, b1);
941 
942  if (is_ip4)
943  {
944  /* Treat IP frag packets as "experimental" protocol for now
945  until support of IP frag reassembly is implemented */
946  proto0 = ip4_is_fragment (ip40) ? 0xfe : ip40->protocol;
947  proto1 = ip4_is_fragment (ip41) ? 0xfe : ip41->protocol;
948  }
949  else
950  {
951  proto0 = ip60->protocol;
952  proto1 = ip61->protocol;
953  }
954 
955  /* Process packet 0 */
956  if (proto0 != IP_PROTOCOL_UDP)
957  goto exit0; /* not UDP packet */
958 
959  if (is_ip4)
960  udp0 = ip4_next_header (ip40);
961  else
962  udp0 = ip6_next_header (ip60);
963 
964  if (udp0->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
965  goto exit0; /* not GENEVE packet */
966 
967  /* Validate DIP against VTEPs */
968  if (is_ip4)
969  {
970 #ifdef CLIB_HAVE_VEC512
971  if (!vtep4_check_vector
972  (&vxm->vtep_table, b0, ip40, &last_vtep4, &vtep4_u512))
973 #else
974  if (!vtep4_check (&vxm->vtep_table, b0, ip40, &last_vtep4))
975 #endif
976  goto exit0; /* no local VTEP for GENEVE packet */
977  }
978  else
979  {
980  if (!vtep6_check (&vxm->vtep_table, b0, ip60, &last_vtep6))
981  goto exit0; /* no local VTEP for GENEVE packet */
982  }
983 
984  flags0 = b0->flags;
985  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
986 
987  /* Don't verify UDP checksum for packets with explicit zero checksum. */
988  good_udp0 |= udp0->checksum == 0;
989 
990  /* Verify UDP length */
991  if (is_ip4)
992  ip_len0 = clib_net_to_host_u16 (ip40->length);
993  else
994  ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
995  udp_len0 = clib_net_to_host_u16 (udp0->length);
996  len_diff0 = ip_len0 - udp_len0;
997 
998  /* Verify UDP checksum */
999  if (PREDICT_FALSE (!good_udp0))
1000  {
1001  if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1002  {
1003  if (is_ip4)
1004  flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
1005  else
1006  flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
1007  good_udp0 =
1008  (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1009  }
1010  }
1011 
1012  if (is_ip4)
1013  {
1014  error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1015  error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
1016  }
1017  else
1018  {
1019  error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1020  error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
1021  }
1022 
1023  next0 = error0 ?
1025  b0->error = error0 ? error_node->errors[error0] : 0;
1026 
1027  /* geneve-input node expect current at GENEVE header */
1028  if (is_ip4)
1029  vlib_buffer_advance (b0,
1030  sizeof (ip4_header_t) +
1031  sizeof (udp_header_t));
1032  else
1033  vlib_buffer_advance (b0,
1034  sizeof (ip6_header_t) +
1035  sizeof (udp_header_t));
1036 
1037  exit0:
1038  /* Process packet 1 */
1039  if (proto1 != IP_PROTOCOL_UDP)
1040  goto exit1; /* not UDP packet */
1041 
1042  if (is_ip4)
1043  udp1 = ip4_next_header (ip41);
1044  else
1045  udp1 = ip6_next_header (ip61);
1046 
1047  if (udp1->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
1048  goto exit1; /* not GENEVE packet */
1049 
1050  /* Validate DIP against VTEPs */
1051  if (is_ip4)
1052  {
1053 #ifdef CLIB_HAVE_VEC512
1054  if (!vtep4_check_vector
1055  (&vxm->vtep_table, b1, ip41, &last_vtep4, &vtep4_u512))
1056 #else
1057  if (!vtep4_check (&vxm->vtep_table, b1, ip41, &last_vtep4))
1058 #endif
1059  goto exit1; /* no local VTEP for GENEVE packet */
1060  }
1061  else
1062  {
1063  if (!vtep6_check (&vxm->vtep_table, b1, ip61, &last_vtep6))
1064  goto exit1; /* no local VTEP for GENEVE packet */
1065  }
1066 
1067  flags1 = b1->flags;
1068  good_udp1 = (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1069 
1070  /* Don't verify UDP checksum for packets with explicit zero checksum. */
1071  good_udp1 |= udp1->checksum == 0;
1072 
1073  /* Verify UDP length */
1074  if (is_ip4)
1075  ip_len1 = clib_net_to_host_u16 (ip41->length);
1076  else
1077  ip_len1 = clib_net_to_host_u16 (ip61->payload_length);
1078  udp_len1 = clib_net_to_host_u16 (udp1->length);
1079  len_diff1 = ip_len1 - udp_len1;
1080 
1081  /* Verify UDP checksum */
1082  if (PREDICT_FALSE (!good_udp1))
1083  {
1084  if ((flags1 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1085  {
1086  if (is_ip4)
1087  flags1 = ip4_tcp_udp_validate_checksum (vm, b1);
1088  else
1089  flags1 = ip6_tcp_udp_icmp_validate_checksum (vm, b1);
1090  good_udp1 =
1091  (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1092  }
1093  }
1094 
1095  if (is_ip4)
1096  {
1097  error1 = good_udp1 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1098  error1 = (len_diff1 >= 0) ? error1 : IP4_ERROR_UDP_LENGTH;
1099  }
1100  else
1101  {
1102  error1 = good_udp1 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1103  error1 = (len_diff1 >= 0) ? error1 : IP6_ERROR_UDP_LENGTH;
1104  }
1105 
1106  next1 = error1 ?
1108  b1->error = error1 ? error_node->errors[error1] : 0;
1109 
1110  /* geneve-input node expect current at GENEVE header */
1111  if (is_ip4)
1112  vlib_buffer_advance (b1,
1113  sizeof (ip4_header_t) +
1114  sizeof (udp_header_t));
1115  else
1116  vlib_buffer_advance (b1,
1117  sizeof (ip6_header_t) +
1118  sizeof (udp_header_t));
1119 
1120  exit1:
1121  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
1122  to_next, n_left_to_next,
1123  bi0, bi1, next0, next1);
1124  }
1125 
1126  while (n_left_from > 0 && n_left_to_next > 0)
1127  {
1128  vlib_buffer_t *b0;
1129  ip4_header_t *ip40;
1130  ip6_header_t *ip60;
1131  udp_header_t *udp0;
1132  u32 bi0, ip_len0, udp_len0, flags0, next0;
1133  i32 len_diff0;
1134  u8 error0, good_udp0, proto0;
1135 
1136  bi0 = to_next[0] = from[0];
1137  from += 1;
1138  n_left_from -= 1;
1139  to_next += 1;
1140  n_left_to_next -= 1;
1141 
1142  b0 = b[0];
1143  b++;
1144  if (is_ip4)
1145  ip40 = vlib_buffer_get_current (b0);
1146  else
1147  ip60 = vlib_buffer_get_current (b0);
1148 
1149  /* Setup packet for next IP feature */
1150  vnet_feature_next (&next0, b0);
1151 
1152  if (is_ip4)
1153  /* Treat IP4 frag packets as "experimental" protocol for now
1154  until support of IP frag reassembly is implemented */
1155  proto0 = ip4_is_fragment (ip40) ? 0xfe : ip40->protocol;
1156  else
1157  proto0 = ip60->protocol;
1158 
1159  if (proto0 != IP_PROTOCOL_UDP)
1160  goto exit; /* not UDP packet */
1161 
1162  if (is_ip4)
1163  udp0 = ip4_next_header (ip40);
1164  else
1165  udp0 = ip6_next_header (ip60);
1166 
1167  if (udp0->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
1168  goto exit; /* not GENEVE packet */
1169 
1170  /* Validate DIP against VTEPs */
1171  if (is_ip4)
1172  {
1173 #ifdef CLIB_HAVE_VEC512
1174  if (!vtep4_check_vector
1175  (&vxm->vtep_table, b0, ip40, &last_vtep4, &vtep4_u512))
1176 #else
1177  if (!vtep4_check (&vxm->vtep_table, b0, ip40, &last_vtep4))
1178 #endif
1179  goto exit; /* no local VTEP for GENEVE packet */
1180  }
1181  else
1182  {
1183  if (!vtep6_check (&vxm->vtep_table, b0, ip60, &last_vtep6))
1184  goto exit; /* no local VTEP for GENEVE packet */
1185  }
1186 
1187  flags0 = b0->flags;
1188  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1189 
1190  /* Don't verify UDP checksum for packets with explicit zero checksum. */
1191  good_udp0 |= udp0->checksum == 0;
1192 
1193  /* Verify UDP length */
1194  if (is_ip4)
1195  ip_len0 = clib_net_to_host_u16 (ip40->length);
1196  else
1197  ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
1198  udp_len0 = clib_net_to_host_u16 (udp0->length);
1199  len_diff0 = ip_len0 - udp_len0;
1200 
1201  /* Verify UDP checksum */
1202  if (PREDICT_FALSE (!good_udp0))
1203  {
1204  if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1205  {
1206  if (is_ip4)
1207  flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
1208  else
1209  flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
1210  good_udp0 =
1211  (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1212  }
1213  }
1214 
1215  if (is_ip4)
1216  {
1217  error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1218  error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
1219  }
1220  else
1221  {
1222  error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1223  error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
1224  }
1225 
1226  next0 = error0 ?
1228  b0->error = error0 ? error_node->errors[error0] : 0;
1229 
1230  /* geneve-input node expect current at GENEVE header */
1231  if (is_ip4)
1232  vlib_buffer_advance (b0,
1233  sizeof (ip4_header_t) +
1234  sizeof (udp_header_t));
1235  else
1236  vlib_buffer_advance (b0,
1237  sizeof (ip6_header_t) +
1238  sizeof (udp_header_t));
1239 
1240  exit:
1241  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
1242  to_next, n_left_to_next,
1243  bi0, next0);
1244  }
1245 
1246  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1247  }
1248 
1249  return frame->n_vectors;
1250 }
1251 
1254  vlib_frame_t * frame)
1255 {
1256  return ip_geneve_bypass_inline (vm, node, frame, /* is_ip4 */ 1);
1257 }
1258 
1259 /* *INDENT-OFF* */
1261 {
1262  .name = "ip4-geneve-bypass",
1263  .vector_size = sizeof (u32),
1264  .n_next_nodes = IP_GENEVE_BYPASS_N_NEXT,.next_nodes =
1265  {
1266  [IP_GENEVE_BYPASS_NEXT_DROP] = "error-drop",
1267  [IP_GENEVE_BYPASS_NEXT_GENEVE] = "geneve4-input",
1268  },
1269  .format_buffer = format_ip4_header,
1270  .format_trace = format_ip4_forward_next_trace,
1271 };
1272 /* *INDENT-ON* */
1273 
1276  vlib_frame_t * frame)
1277 {
1278  return ip_geneve_bypass_inline (vm, node, frame, /* is_ip4 */ 0);
1279 }
1280 
1281 /* *INDENT-OFF* */
1283 {
1284  .name = "ip6-geneve-bypass",
1285  .vector_size = sizeof (u32),
1286  .n_next_nodes = IP_GENEVE_BYPASS_N_NEXT,
1287  .next_nodes =
1288  {
1289  [IP_GENEVE_BYPASS_NEXT_DROP] = "error-drop",
1290  [IP_GENEVE_BYPASS_NEXT_GENEVE] = "geneve6-input",
1291  },
1292  .format_buffer = format_ip6_header,
1293  .format_trace = format_ip6_forward_next_trace,
1294 };
1295 /* *INDENT-ON* */
1296 
1297 /*
1298  * fd.io coding-style-patch-verification: ON
1299  *
1300  * Local Variables:
1301  * eval: (c-set-style "gnu")
1302  * End:
1303  */
static u8 vnet_get_geneve_critical_bit(geneve_header_t *h)
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
static u32 vnet_get_geneve_vni(geneve_header_t *h)
#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:220
u8 runtime_data[0]
Function dependent node-runtime data.
Definition: node.h:518
ip4_address_t src_address
Definition: ip4_packet.h:125
vnet_interface_main_t interface_main
Definition: vnet.h:59
format_function_t format_ip4_header
Definition: format.h:81
u32 tunnel_index
Definition: decap.c:23
#define PREDICT_TRUE(x)
Definition: clib.h:121
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 decap_next_index
Definition: geneve.h:110
u32 thread_index
Definition: main.h:249
vlib_main_t * vm
Definition: in2out_ed.c:1582
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:122
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define VLIB_NODE_FN(node)
Definition: node.h:202
static uword ip4_address_is_multicast(const ip4_address_t *a)
Definition: ip4_packet.h:434
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:469
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
unsigned char u8
Definition: types.h:56
static char * geneve_error_strings[]
Definition: decap.c:808
#define GENEVE_BASE_HEADER_LENGTH
Definition: geneve_packet.h:95
u8 data[128]
Definition: ipsec_types.api:89
vlib_node_registration_t ip4_geneve_bypass_node
(constructor) VLIB_REGISTER_NODE (ip4_geneve_bypass_node)
Definition: decap.c:1260
geneve_tunnel_t * tunnels
Definition: geneve.h:165
static int ip4_is_fragment(const ip4_header_t *i)
Definition: ip4_packet.h:168
static u8 vnet_get_geneve_options_len(geneve_header_t *h)
i64 word
Definition: types.h:111
ip4_address_t dst_address
Definition: ip4_packet.h:125
#define foreach_geneve_input_next
Definition: geneve.h:142
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:881
static uword ip_geneve_bypass_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u32 is_ip4)
Definition: decap.c:860
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
vtep_table_t vtep_table
Definition: geneve.h:173
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:196
unsigned int u32
Definition: types.h:88
static void vtep4_key_init(vtep4_key_t *k4)
Definition: vtep.h:81
#define VLIB_FRAME_SIZE
Definition: node.h:377
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
static void vnet_geneve_hdr_1word_ntoh(geneve_header_t *h)
vlib_node_registration_t ip4_input_node
Global ip4 input node.
Definition: ip4_input.c:385
u32 encap_fib_index
Definition: geneve.h:113
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:120
#define always_inline
Definition: ipsec.h:28
ip6_main_t ip6_main
Definition: ip6_forward.c:2781
static u32 validate_geneve_fib(vlib_buffer_t *b, geneve_tunnel_t *t, u32 is_ip4)
Definition: decap.c:51
u32 ip4_tcp_udp_validate_checksum(vlib_main_t *vm, vlib_buffer_t *p0)
Definition: ip4_forward.c:1400
vlib_node_registration_t ip6_geneve_bypass_node
(constructor) VLIB_REGISTER_NODE (ip6_geneve_bypass_node)
Definition: decap.c:1282
#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 u8 vtep6_check(vtep_table_t *t, vlib_buffer_t *b0, ip6_header_t *ip60, vtep6_key_t *last_k6)
Definition: vtep.h:158
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1231
static u8 vtep4_check(vtep_table_t *t, vlib_buffer_t *b0, ip4_header_t *ip40, vtep4_key_t *last_k4)
Definition: vtep.h:101
vlib_node_registration_t geneve4_input_node
(constructor) VLIB_REGISTER_NODE (geneve4_input_node)
Definition: decap.c:816
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u16 n_vectors
Definition: node.h:396
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:322
ip46_address_t local
Definition: geneve.h:103
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:115
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
uword * geneve4_tunnel_by_key
Definition: geneve.h:168
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:371
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
ip_vxan_bypass_next_t
Definition: decap.c:852
signed int i32
Definition: types.h:77
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:510
u32 sw_if_index
Definition: geneve.h:116
static u8 * format_geneve_rx_trace(u8 *s, va_list *args)
Definition: decap.c:29
static void vtep6_key_init(vtep6_key_t *k6)
Definition: vtep.h:87
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:248
static u8 vnet_get_geneve_version(geneve_header_t *h)
format_function_t format_ip6_header
Definition: format.h:95
u32 next_index
Definition: decap.c:22
static uword ip6_address_is_equal(const ip6_address_t *a, const ip6_address_t *b)
Definition: ip6_packet.h:167
static uword ip6_address_is_multicast(const ip6_address_t *a)
Definition: ip6_packet.h:121
static u32 vnet_get_geneve_vni_network_order(geneve_header_t *h)
vnet_main_t * vnet_main
Definition: geneve.h:183
#define vec_elt(v, i)
Get vector value at index i.
Definition: defs.h:47
u16 payload_length
Definition: ip6_packet.h:301
u32 ip6_tcp_udp_icmp_validate_checksum(vlib_main_t *vm, vlib_buffer_t *p0)
Definition: ip6_forward.c:1160
static void vnet_update_l2_len(vlib_buffer_t *b)
Definition: l2_input.h:236
void ip4_forward_next_trace(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, vlib_rx_or_tx_t which_adj_index)
Definition: ip4_forward.c:1279
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1583
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
uword * geneve6_tunnel_by_key
Definition: geneve.h:169
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:297
u8 * format_ip4_forward_next_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1229
#define GENEVE_VERSION
Definition: geneve_packet.h:98
u32 index
Definition: flow_types.api:221
#define hash_get_mem(h, key)
Definition: hash.h:269
vlib_node_registration_t geneve6_input_node
(constructor) VLIB_REGISTER_NODE (geneve6_input_node)
Definition: decap.c:834
#define vnet_buffer(b)
Definition: buffer.h:417
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1144
geneve_main_t geneve_main
Definition: geneve.c:39
u16 flags
Copy of main node flags.
Definition: node.h:500
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:577
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
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:301
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u32 * fib_index_by_sw_if_index
Definition: ip6.h:196
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
Definition: defs.h:46
ip6_address_t dst_address
Definition: ip6_packet.h:310
static u8 vtep4_check_vector(vtep_table_t *t, vlib_buffer_t *b0, ip4_header_t *ip40, vtep4_key_t *last_k4, vtep4_cache_t *vtep4_u512)
Definition: vtep.h:122
static uword geneve_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, u32 is_ip4)
Definition: decap.c:70
u8 * format_ip6_forward_next_trace(u8 *s, va_list *args)
Definition: ip6_forward.c:951