FD.io VPP  v19.08.3-2-gbabecb413
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 
71  vlib_node_runtime_t * node,
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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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_bigendian (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 
795  vlib_node_runtime_t * node,
796  vlib_frame_t * from_frame)
797 {
798  return geneve_input (vm, node, from_frame, /* is_ip4 */ 1);
799 }
800 
802  vlib_node_runtime_t * node,
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 
861  vlib_node_runtime_t * node,
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  ip4_address_t addr4; /* last IPv4 address matching a local VTEP address */
869  ip6_address_t addr6; /* last IPv6 address matching a local VTEP address */
870 
871  from = vlib_frame_vector_args (frame);
872  n_left_from = frame->n_vectors;
873  next_index = node->cached_next_index;
874 
875  if (node->flags & VLIB_NODE_FLAG_TRACE)
876  ip4_forward_next_trace (vm, node, frame, VLIB_TX);
877 
878  if (is_ip4)
879  addr4.data_u32 = ~0;
880  else
881  ip6_address_set_zero (&addr6);
882 
883  while (n_left_from > 0)
884  {
885  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
886 
887  while (n_left_from >= 4 && n_left_to_next >= 2)
888  {
889  vlib_buffer_t *b0, *b1;
890  ip4_header_t *ip40, *ip41;
891  ip6_header_t *ip60, *ip61;
892  udp_header_t *udp0, *udp1;
893  u32 bi0, ip_len0, udp_len0, flags0, next0;
894  u32 bi1, ip_len1, udp_len1, flags1, next1;
895  i32 len_diff0, len_diff1;
896  u8 error0, good_udp0, proto0;
897  u8 error1, good_udp1, proto1;
898 
899  /* Prefetch next iteration. */
900  {
901  vlib_buffer_t *p2, *p3;
902 
903  p2 = vlib_get_buffer (vm, from[2]);
904  p3 = vlib_get_buffer (vm, from[3]);
905 
906  vlib_prefetch_buffer_header (p2, LOAD);
907  vlib_prefetch_buffer_header (p3, LOAD);
908 
909  CLIB_PREFETCH (p2->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
910  CLIB_PREFETCH (p3->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
911  }
912 
913  bi0 = to_next[0] = from[0];
914  bi1 = to_next[1] = from[1];
915  from += 2;
916  n_left_from -= 2;
917  to_next += 2;
918  n_left_to_next -= 2;
919 
920  b0 = vlib_get_buffer (vm, bi0);
921  b1 = vlib_get_buffer (vm, bi1);
922  if (is_ip4)
923  {
924  ip40 = vlib_buffer_get_current (b0);
925  ip41 = vlib_buffer_get_current (b1);
926  }
927  else
928  {
929  ip60 = vlib_buffer_get_current (b0);
930  ip61 = vlib_buffer_get_current (b1);
931  }
932 
933  /* Setup packet for next IP feature */
934  vnet_feature_next (&next0, b0);
935  vnet_feature_next (&next1, b1);
936 
937  if (is_ip4)
938  {
939  /* Treat IP frag packets as "experimental" protocol for now
940  until support of IP frag reassembly is implemented */
941  proto0 = ip4_is_fragment (ip40) ? 0xfe : ip40->protocol;
942  proto1 = ip4_is_fragment (ip41) ? 0xfe : ip41->protocol;
943  }
944  else
945  {
946  proto0 = ip60->protocol;
947  proto1 = ip61->protocol;
948  }
949 
950  /* Process packet 0 */
951  if (proto0 != IP_PROTOCOL_UDP)
952  goto exit0; /* not UDP packet */
953 
954  if (is_ip4)
955  udp0 = ip4_next_header (ip40);
956  else
957  udp0 = ip6_next_header (ip60);
958 
959  if (udp0->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
960  goto exit0; /* not GENEVE packet */
961 
962  /* Validate DIP against VTEPs */
963  if (is_ip4)
964  {
965  if (addr4.as_u32 != ip40->dst_address.as_u32)
966  {
967  if (!hash_get (vxm->vtep4, ip40->dst_address.as_u32))
968  goto exit0; /* no local VTEP for GENEVE packet */
969  addr4 = ip40->dst_address;
970  }
971  }
972  else
973  {
974  if (!ip6_address_is_equal (&addr6, &ip60->dst_address))
975  {
976  if (!hash_get_mem (vxm->vtep6, &ip60->dst_address))
977  goto exit0; /* no local VTEP for GENEVE packet */
978  addr6 = ip60->dst_address;
979  }
980  }
981 
982  flags0 = b0->flags;
983  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
984 
985  /* Don't verify UDP checksum for packets with explicit zero checksum. */
986  good_udp0 |= udp0->checksum == 0;
987 
988  /* Verify UDP length */
989  if (is_ip4)
990  ip_len0 = clib_net_to_host_u16 (ip40->length);
991  else
992  ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
993  udp_len0 = clib_net_to_host_u16 (udp0->length);
994  len_diff0 = ip_len0 - udp_len0;
995 
996  /* Verify UDP checksum */
997  if (PREDICT_FALSE (!good_udp0))
998  {
999  if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1000  {
1001  if (is_ip4)
1002  flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
1003  else
1004  flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
1005  good_udp0 =
1006  (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1007  }
1008  }
1009 
1010  if (is_ip4)
1011  {
1012  error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1013  error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
1014  }
1015  else
1016  {
1017  error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1018  error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
1019  }
1020 
1021  next0 = error0 ?
1023  b0->error = error0 ? error_node->errors[error0] : 0;
1024 
1025  /* geneve-input node expect current at GENEVE header */
1026  if (is_ip4)
1027  vlib_buffer_advance (b0,
1028  sizeof (ip4_header_t) +
1029  sizeof (udp_header_t));
1030  else
1031  vlib_buffer_advance (b0,
1032  sizeof (ip6_header_t) +
1033  sizeof (udp_header_t));
1034 
1035  exit0:
1036  /* Process packet 1 */
1037  if (proto1 != IP_PROTOCOL_UDP)
1038  goto exit1; /* not UDP packet */
1039 
1040  if (is_ip4)
1041  udp1 = ip4_next_header (ip41);
1042  else
1043  udp1 = ip6_next_header (ip61);
1044 
1045  if (udp1->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
1046  goto exit1; /* not GENEVE packet */
1047 
1048  /* Validate DIP against VTEPs */
1049  if (is_ip4)
1050  {
1051  if (addr4.as_u32 != ip41->dst_address.as_u32)
1052  {
1053  if (!hash_get (vxm->vtep4, ip41->dst_address.as_u32))
1054  goto exit1; /* no local VTEP for GENEVE packet */
1055  addr4 = ip41->dst_address;
1056  }
1057  }
1058  else
1059  {
1060  if (!ip6_address_is_equal (&addr6, &ip61->dst_address))
1061  {
1062  if (!hash_get_mem (vxm->vtep6, &ip61->dst_address))
1063  goto exit1; /* no local VTEP for GENEVE packet */
1064  addr6 = ip61->dst_address;
1065  }
1066  }
1067 
1068  flags1 = b1->flags;
1069  good_udp1 = (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1070 
1071  /* Don't verify UDP checksum for packets with explicit zero checksum. */
1072  good_udp1 |= udp1->checksum == 0;
1073 
1074  /* Verify UDP length */
1075  if (is_ip4)
1076  ip_len1 = clib_net_to_host_u16 (ip41->length);
1077  else
1078  ip_len1 = clib_net_to_host_u16 (ip61->payload_length);
1079  udp_len1 = clib_net_to_host_u16 (udp1->length);
1080  len_diff1 = ip_len1 - udp_len1;
1081 
1082  /* Verify UDP checksum */
1083  if (PREDICT_FALSE (!good_udp1))
1084  {
1085  if ((flags1 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1086  {
1087  if (is_ip4)
1088  flags1 = ip4_tcp_udp_validate_checksum (vm, b1);
1089  else
1090  flags1 = ip6_tcp_udp_icmp_validate_checksum (vm, b1);
1091  good_udp1 =
1092  (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1093  }
1094  }
1095 
1096  if (is_ip4)
1097  {
1098  error1 = good_udp1 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1099  error1 = (len_diff1 >= 0) ? error1 : IP4_ERROR_UDP_LENGTH;
1100  }
1101  else
1102  {
1103  error1 = good_udp1 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1104  error1 = (len_diff1 >= 0) ? error1 : IP6_ERROR_UDP_LENGTH;
1105  }
1106 
1107  next1 = error1 ?
1109  b1->error = error1 ? error_node->errors[error1] : 0;
1110 
1111  /* geneve-input node expect current at GENEVE header */
1112  if (is_ip4)
1113  vlib_buffer_advance (b1,
1114  sizeof (ip4_header_t) +
1115  sizeof (udp_header_t));
1116  else
1117  vlib_buffer_advance (b1,
1118  sizeof (ip6_header_t) +
1119  sizeof (udp_header_t));
1120 
1121  exit1:
1122  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
1123  to_next, n_left_to_next,
1124  bi0, bi1, next0, next1);
1125  }
1126 
1127  while (n_left_from > 0 && n_left_to_next > 0)
1128  {
1129  vlib_buffer_t *b0;
1130  ip4_header_t *ip40;
1131  ip6_header_t *ip60;
1132  udp_header_t *udp0;
1133  u32 bi0, ip_len0, udp_len0, flags0, next0;
1134  i32 len_diff0;
1135  u8 error0, good_udp0, proto0;
1136 
1137  bi0 = to_next[0] = from[0];
1138  from += 1;
1139  n_left_from -= 1;
1140  to_next += 1;
1141  n_left_to_next -= 1;
1142 
1143  b0 = vlib_get_buffer (vm, bi0);
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  if (addr4.as_u32 != ip40->dst_address.as_u32)
1174  {
1175  if (!hash_get (vxm->vtep4, ip40->dst_address.as_u32))
1176  goto exit; /* no local VTEP for GENEVE packet */
1177  addr4 = ip40->dst_address;
1178  }
1179  }
1180  else
1181  {
1182  if (!ip6_address_is_equal (&addr6, &ip60->dst_address))
1183  {
1184  if (!hash_get_mem (vxm->vtep6, &ip60->dst_address))
1185  goto exit; /* no local VTEP for GENEVE packet */
1186  addr6 = ip60->dst_address;
1187  }
1188  }
1189 
1190  flags0 = b0->flags;
1191  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1192 
1193  /* Don't verify UDP checksum for packets with explicit zero checksum. */
1194  good_udp0 |= udp0->checksum == 0;
1195 
1196  /* Verify UDP length */
1197  if (is_ip4)
1198  ip_len0 = clib_net_to_host_u16 (ip40->length);
1199  else
1200  ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
1201  udp_len0 = clib_net_to_host_u16 (udp0->length);
1202  len_diff0 = ip_len0 - udp_len0;
1203 
1204  /* Verify UDP checksum */
1205  if (PREDICT_FALSE (!good_udp0))
1206  {
1207  if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1208  {
1209  if (is_ip4)
1210  flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
1211  else
1212  flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
1213  good_udp0 =
1214  (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1215  }
1216  }
1217 
1218  if (is_ip4)
1219  {
1220  error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1221  error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
1222  }
1223  else
1224  {
1225  error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1226  error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
1227  }
1228 
1229  next0 = error0 ?
1231  b0->error = error0 ? error_node->errors[error0] : 0;
1232 
1233  /* geneve-input node expect current at GENEVE header */
1234  if (is_ip4)
1235  vlib_buffer_advance (b0,
1236  sizeof (ip4_header_t) +
1237  sizeof (udp_header_t));
1238  else
1239  vlib_buffer_advance (b0,
1240  sizeof (ip6_header_t) +
1241  sizeof (udp_header_t));
1242 
1243  exit:
1244  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
1245  to_next, n_left_to_next,
1246  bi0, next0);
1247  }
1248 
1249  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1250  }
1251 
1252  return frame->n_vectors;
1253 }
1254 
1256  vlib_node_runtime_t * node,
1257  vlib_frame_t * frame)
1258 {
1259  return ip_geneve_bypass_inline (vm, node, frame, /* is_ip4 */ 1);
1260 }
1261 
1262 /* *INDENT-OFF* */
1264 {
1265  .name = "ip4-geneve-bypass",.vector_size =
1266  sizeof (u32),.n_next_nodes = IP_GENEVE_BYPASS_N_NEXT,.next_nodes =
1267  {
1268  [IP_GENEVE_BYPASS_NEXT_DROP] = "error-drop",
1269  [IP_GENEVE_BYPASS_NEXT_GENEVE] = "geneve4-input",}
1270 ,.format_buffer = format_ip4_header,.format_trace =
1272 
1273 #ifndef CLIB_MARCH_VARIANT
1274 /* Dummy init function to get us linked in. */
1276 {
1277  return 0;
1278 }
1279 
1281 /* *INDENT-ON* */
1282 #endif /* CLIB_MARCH_VARIANT */
1283 
1285  vlib_node_runtime_t * node,
1286  vlib_frame_t * frame)
1287 {
1288  return ip_geneve_bypass_inline (vm, node, frame, /* is_ip4 */ 0);
1289 }
1290 
1291 /* *INDENT-OFF* */
1293 {
1294  .name = "ip6-geneve-bypass",.vector_size =
1295  sizeof (u32),.n_next_nodes = IP_GENEVE_BYPASS_N_NEXT,.next_nodes =
1296  {
1297  [IP_GENEVE_BYPASS_NEXT_DROP] = "error-drop",
1298  [IP_GENEVE_BYPASS_NEXT_GENEVE] = "geneve6-input",}
1299 ,.format_buffer = format_ip6_header,.format_trace =
1301 /* *INDENT-ON* */
1302 
1303 #ifndef CLIB_MARCH_VARIANT
1304 /* Dummy init function to get us linked in. */
1305 clib_error_t *
1307 {
1308  return 0;
1309 }
1310 
1312 #endif /* CLIB_MARCH_VARIANT */
1313 
1314 /*
1315  * fd.io coding-style-patch-verification: ON
1316  *
1317  * Local Variables:
1318  * eval: (c-set-style "gnu")
1319  * End:
1320  */
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:83
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:523
ip4_address_t src_address
Definition: ip4_packet.h:170
vnet_interface_main_t interface_main
Definition: vnet.h:56
format_function_t format_ip4_header
Definition: format.h:83
u32 tunnel_index
Definition: decap.c:23
#define PREDICT_TRUE(x)
Definition: clib.h:113
u64 as_u64[2]
Definition: ip6_packet.h:51
#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:109
u32 thread_index
Definition: main.h:218
uword * vtep6
Definition: geneve.h:171
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:121
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u8 data[128]
Definition: ipsec.api:251
#define VLIB_NODE_FN(node)
Definition: node.h:202
static uword ip4_address_is_multicast(const ip4_address_t *a)
Definition: ip4_packet.h:318
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:470
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:366
ip6_address_t src_address
Definition: ip6_packet.h:383
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
vlib_node_registration_t ip4_geneve_bypass_node
(constructor) VLIB_REGISTER_NODE (ip4_geneve_bypass_node)
Definition: decap.c:1263
geneve_tunnel_t * tunnels
Definition: geneve.h:162
static int ip4_is_fragment(const ip4_header_t *i)
Definition: ip4_packet.h:213
static u8 vnet_get_geneve_options_len(geneve_header_t *h)
i64 word
Definition: types.h:111
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
#define always_inline
Definition: clib.h:99
ip4_address_t dst_address
Definition: ip4_packet.h:170
#define foreach_geneve_input_next
Definition: geneve.h:139
static u32 vnet_get_geneve_vni_bigendian(geneve_header_t *h)
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:846
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
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:241
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:378
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
clib_error_t * ip6_geneve_bypass_init(vlib_main_t *vm)
Definition: decap.c:1306
#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:514
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:317
u32 encap_fib_index
Definition: geneve.h:112
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:112
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:1332
vlib_node_registration_t ip6_geneve_bypass_node
(constructor) VLIB_REGISTER_NODE (ip6_geneve_bypass_node)
Definition: decap.c:1292
#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:218
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:338
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1150
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
uword * vtep4
Definition: geneve.h:170
u16 n_vectors
Definition: node.h:397
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
vlib_main_t * vm
Definition: buffer.c:323
static void ip6_address_set_zero(ip6_address_t *a)
Definition: ip6_packet.h:276
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
ip46_address_t local
Definition: geneve.h:102
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:89
u8 data[]
Packet data.
Definition: buffer.h:181
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:456
uword * geneve4_tunnel_by_key
Definition: geneve.h:165
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:410
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:515
u32 sw_if_index
Definition: geneve.h:115
static u8 * format_geneve_rx_trace(u8 *s, va_list *args)
Definition: decap.c:29
ip6_main_t ip6_main
Definition: ip6_forward.c:2805
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:97
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:240
static uword ip6_address_is_multicast(const ip6_address_t *a)
Definition: ip6_packet.h:187
vnet_main_t * vnet_main
Definition: geneve.h:184
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.
Definition: defs.h:47
u16 payload_length
Definition: ip6_packet.h:374
u32 ip6_tcp_udp_icmp_validate_checksum(vlib_main_t *vm, vlib_buffer_t *p0)
Definition: ip6_forward.c:1075
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:1211
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
uword * geneve6_tunnel_by_key
Definition: geneve.h:166
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
u8 * format_ip4_forward_next_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1161
#define GENEVE_VERSION
Definition: geneve_packet.h:98
#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:365
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1076
geneve_main_t geneve_main
Definition: geneve.c:39
u16 flags
Copy of main node flags.
Definition: node.h:509
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:244
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:302
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
clib_error_t * ip4_geneve_bypass_init(vlib_main_t *vm)
Definition: decap.c:1275
u32 * fib_index_by_sw_if_index
Definition: ip6.h:194
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
Definition: defs.h:46
ip6_address_t dst_address
Definition: ip6_packet.h:383
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:866