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