FD.io VPP  v21.06-3-gbb25fbf28
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 
18 #include <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;
83  u32 stats_sw_if_index, stats_n_packets, stats_n_bytes;
85 
86  if (is_ip4)
87  last_key4.as_u64 = ~0;
88  else
89  clib_memset (&last_key6, 0xff, sizeof (last_key6));
90 
92  n_left_from = from_frame->n_vectors;
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 
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  }
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? */
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 
797 {
798  return geneve_input (vm, node, from_frame, /* is_ip4 */ 1);
799 }
800 
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,
810 #include <geneve/geneve_error.def>
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 */
873 
875  n_left_from = frame->n_vectors;
876  next_index = node->cached_next_index;
877 
879 
880  if (node->flags & VLIB_NODE_FLAG_TRACE)
882 
883  if (is_ip4)
884  vtep4_key_init (&last_vtep4);
885  else
886  vtep6_key_init (&last_vtep6);
887 
888  while (n_left_from > 0)
889  {
890  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
891 
892  while (n_left_from >= 4 && n_left_to_next >= 2)
893  {
894  vlib_buffer_t *b0, *b1;
895  ip4_header_t *ip40, *ip41;
896  ip6_header_t *ip60, *ip61;
897  udp_header_t *udp0, *udp1;
898  u32 bi0, ip_len0, udp_len0, flags0, next0;
899  u32 bi1, ip_len1, udp_len1, flags1, next1;
900  i32 len_diff0, len_diff1;
901  u8 error0, good_udp0, proto0;
902  u8 error1, good_udp1, proto1;
903 
904  /* Prefetch next iteration. */
905  {
906  vlib_prefetch_buffer_header (b[2], LOAD);
907  vlib_prefetch_buffer_header (b[3], LOAD);
908 
909  CLIB_PREFETCH (b[2]->data, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
910  CLIB_PREFETCH (b[3]->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 = b[0];
921  b1 = b[1];
922  b += 2;
923  if (is_ip4)
924  {
925  ip40 = vlib_buffer_get_current (b0);
926  ip41 = vlib_buffer_get_current (b1);
927  }
928  else
929  {
930  ip60 = vlib_buffer_get_current (b0);
931  ip61 = vlib_buffer_get_current (b1);
932  }
933 
934  /* Setup packet for next IP feature */
935  vnet_feature_next (&next0, b0);
936  vnet_feature_next (&next1, b1);
937 
938  if (is_ip4)
939  {
940  /* Treat IP frag packets as "experimental" protocol for now
941  until support of IP frag reassembly is implemented */
942  proto0 = ip4_is_fragment (ip40) ? 0xfe : ip40->protocol;
943  proto1 = ip4_is_fragment (ip41) ? 0xfe : ip41->protocol;
944  }
945  else
946  {
947  proto0 = ip60->protocol;
948  proto1 = ip61->protocol;
949  }
950 
951  /* Process packet 0 */
952  if (proto0 != IP_PROTOCOL_UDP)
953  goto exit0; /* not UDP packet */
954 
955  if (is_ip4)
956  udp0 = ip4_next_header (ip40);
957  else
958  udp0 = ip6_next_header (ip60);
959 
960  if (udp0->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
961  goto exit0; /* not GENEVE packet */
962 
963  /* Validate DIP against VTEPs */
964  if (is_ip4)
965  {
966 #ifdef CLIB_HAVE_VEC512
967  if (!vtep4_check_vector (&vxm->vtep_table, b0, ip40, &last_vtep4,
968  &vxm->vtep4_u512))
969 #else
970  if (!vtep4_check (&vxm->vtep_table, b0, ip40, &last_vtep4))
971 #endif
972  goto exit0; /* no local VTEP for GENEVE packet */
973  }
974  else
975  {
976  if (!vtep6_check (&vxm->vtep_table, b0, ip60, &last_vtep6))
977  goto exit0; /* no local VTEP for GENEVE packet */
978  }
979 
980  flags0 = b0->flags;
981  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
982 
983  /* Don't verify UDP checksum for packets with explicit zero checksum. */
984  good_udp0 |= udp0->checksum == 0;
985 
986  /* Verify UDP length */
987  if (is_ip4)
988  ip_len0 = clib_net_to_host_u16 (ip40->length);
989  else
990  ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
991  udp_len0 = clib_net_to_host_u16 (udp0->length);
992  len_diff0 = ip_len0 - udp_len0;
993 
994  /* Verify UDP checksum */
995  if (PREDICT_FALSE (!good_udp0))
996  {
997  if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
998  {
999  if (is_ip4)
1000  flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
1001  else
1002  flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
1003  good_udp0 =
1004  (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1005  }
1006  }
1007 
1008  if (is_ip4)
1009  {
1010  error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1011  error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
1012  }
1013  else
1014  {
1015  error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1016  error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
1017  }
1018 
1019  next0 = error0 ?
1021  b0->error = error0 ? error_node->errors[error0] : 0;
1022 
1023  /* geneve-input node expect current at GENEVE header */
1024  if (is_ip4)
1025  vlib_buffer_advance (b0,
1026  sizeof (ip4_header_t) +
1027  sizeof (udp_header_t));
1028  else
1029  vlib_buffer_advance (b0,
1030  sizeof (ip6_header_t) +
1031  sizeof (udp_header_t));
1032 
1033  exit0:
1034  /* Process packet 1 */
1035  if (proto1 != IP_PROTOCOL_UDP)
1036  goto exit1; /* not UDP packet */
1037 
1038  if (is_ip4)
1039  udp1 = ip4_next_header (ip41);
1040  else
1041  udp1 = ip6_next_header (ip61);
1042 
1043  if (udp1->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
1044  goto exit1; /* not GENEVE packet */
1045 
1046  /* Validate DIP against VTEPs */
1047  if (is_ip4)
1048  {
1049 #ifdef CLIB_HAVE_VEC512
1050  if (!vtep4_check_vector (&vxm->vtep_table, b1, ip41, &last_vtep4,
1051  &vxm->vtep4_u512))
1052 #else
1053  if (!vtep4_check (&vxm->vtep_table, b1, ip41, &last_vtep4))
1054 #endif
1055  goto exit1; /* no local VTEP for GENEVE packet */
1056  }
1057  else
1058  {
1059  if (!vtep6_check (&vxm->vtep_table, b1, ip61, &last_vtep6))
1060  goto exit1; /* no local VTEP for GENEVE packet */
1061  }
1062 
1063  flags1 = b1->flags;
1064  good_udp1 = (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1065 
1066  /* Don't verify UDP checksum for packets with explicit zero checksum. */
1067  good_udp1 |= udp1->checksum == 0;
1068 
1069  /* Verify UDP length */
1070  if (is_ip4)
1071  ip_len1 = clib_net_to_host_u16 (ip41->length);
1072  else
1073  ip_len1 = clib_net_to_host_u16 (ip61->payload_length);
1074  udp_len1 = clib_net_to_host_u16 (udp1->length);
1075  len_diff1 = ip_len1 - udp_len1;
1076 
1077  /* Verify UDP checksum */
1078  if (PREDICT_FALSE (!good_udp1))
1079  {
1080  if ((flags1 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1081  {
1082  if (is_ip4)
1083  flags1 = ip4_tcp_udp_validate_checksum (vm, b1);
1084  else
1085  flags1 = ip6_tcp_udp_icmp_validate_checksum (vm, b1);
1086  good_udp1 =
1087  (flags1 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1088  }
1089  }
1090 
1091  if (is_ip4)
1092  {
1093  error1 = good_udp1 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1094  error1 = (len_diff1 >= 0) ? error1 : IP4_ERROR_UDP_LENGTH;
1095  }
1096  else
1097  {
1098  error1 = good_udp1 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1099  error1 = (len_diff1 >= 0) ? error1 : IP6_ERROR_UDP_LENGTH;
1100  }
1101 
1102  next1 = error1 ?
1104  b1->error = error1 ? error_node->errors[error1] : 0;
1105 
1106  /* geneve-input node expect current at GENEVE header */
1107  if (is_ip4)
1108  vlib_buffer_advance (b1,
1109  sizeof (ip4_header_t) +
1110  sizeof (udp_header_t));
1111  else
1112  vlib_buffer_advance (b1,
1113  sizeof (ip6_header_t) +
1114  sizeof (udp_header_t));
1115 
1116  exit1:
1118  to_next, n_left_to_next,
1119  bi0, bi1, next0, next1);
1120  }
1121 
1122  while (n_left_from > 0 && n_left_to_next > 0)
1123  {
1124  vlib_buffer_t *b0;
1125  ip4_header_t *ip40;
1126  ip6_header_t *ip60;
1127  udp_header_t *udp0;
1128  u32 bi0, ip_len0, udp_len0, flags0, next0;
1129  i32 len_diff0;
1130  u8 error0, good_udp0, proto0;
1131 
1132  bi0 = to_next[0] = from[0];
1133  from += 1;
1134  n_left_from -= 1;
1135  to_next += 1;
1136  n_left_to_next -= 1;
1137 
1138  b0 = b[0];
1139  b++;
1140  if (is_ip4)
1141  ip40 = vlib_buffer_get_current (b0);
1142  else
1143  ip60 = vlib_buffer_get_current (b0);
1144 
1145  /* Setup packet for next IP feature */
1146  vnet_feature_next (&next0, b0);
1147 
1148  if (is_ip4)
1149  /* Treat IP4 frag packets as "experimental" protocol for now
1150  until support of IP frag reassembly is implemented */
1151  proto0 = ip4_is_fragment (ip40) ? 0xfe : ip40->protocol;
1152  else
1153  proto0 = ip60->protocol;
1154 
1155  if (proto0 != IP_PROTOCOL_UDP)
1156  goto exit; /* not UDP packet */
1157 
1158  if (is_ip4)
1159  udp0 = ip4_next_header (ip40);
1160  else
1161  udp0 = ip6_next_header (ip60);
1162 
1163  if (udp0->dst_port != clib_host_to_net_u16 (UDP_DST_PORT_geneve))
1164  goto exit; /* not GENEVE packet */
1165 
1166  /* Validate DIP against VTEPs */
1167  if (is_ip4)
1168  {
1169 #ifdef CLIB_HAVE_VEC512
1170  if (!vtep4_check_vector (&vxm->vtep_table, b0, ip40, &last_vtep4,
1171  &vxm->vtep4_u512))
1172 #else
1173  if (!vtep4_check (&vxm->vtep_table, b0, ip40, &last_vtep4))
1174 #endif
1175  goto exit; /* no local VTEP for GENEVE packet */
1176  }
1177  else
1178  {
1179  if (!vtep6_check (&vxm->vtep_table, b0, ip60, &last_vtep6))
1180  goto exit; /* no local VTEP for GENEVE packet */
1181  }
1182 
1183  flags0 = b0->flags;
1184  good_udp0 = (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1185 
1186  /* Don't verify UDP checksum for packets with explicit zero checksum. */
1187  good_udp0 |= udp0->checksum == 0;
1188 
1189  /* Verify UDP length */
1190  if (is_ip4)
1191  ip_len0 = clib_net_to_host_u16 (ip40->length);
1192  else
1193  ip_len0 = clib_net_to_host_u16 (ip60->payload_length);
1194  udp_len0 = clib_net_to_host_u16 (udp0->length);
1195  len_diff0 = ip_len0 - udp_len0;
1196 
1197  /* Verify UDP checksum */
1198  if (PREDICT_FALSE (!good_udp0))
1199  {
1200  if ((flags0 & VNET_BUFFER_F_L4_CHECKSUM_COMPUTED) == 0)
1201  {
1202  if (is_ip4)
1203  flags0 = ip4_tcp_udp_validate_checksum (vm, b0);
1204  else
1205  flags0 = ip6_tcp_udp_icmp_validate_checksum (vm, b0);
1206  good_udp0 =
1207  (flags0 & VNET_BUFFER_F_L4_CHECKSUM_CORRECT) != 0;
1208  }
1209  }
1210 
1211  if (is_ip4)
1212  {
1213  error0 = good_udp0 ? 0 : IP4_ERROR_UDP_CHECKSUM;
1214  error0 = (len_diff0 >= 0) ? error0 : IP4_ERROR_UDP_LENGTH;
1215  }
1216  else
1217  {
1218  error0 = good_udp0 ? 0 : IP6_ERROR_UDP_CHECKSUM;
1219  error0 = (len_diff0 >= 0) ? error0 : IP6_ERROR_UDP_LENGTH;
1220  }
1221 
1222  next0 = error0 ?
1224  b0->error = error0 ? error_node->errors[error0] : 0;
1225 
1226  /* geneve-input node expect current at GENEVE header */
1227  if (is_ip4)
1228  vlib_buffer_advance (b0,
1229  sizeof (ip4_header_t) +
1230  sizeof (udp_header_t));
1231  else
1232  vlib_buffer_advance (b0,
1233  sizeof (ip6_header_t) +
1234  sizeof (udp_header_t));
1235 
1236  exit:
1238  to_next, n_left_to_next,
1239  bi0, next0);
1240  }
1241 
1242  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1243  }
1244 
1245  return frame->n_vectors;
1246 }
1247 
1250  vlib_frame_t * frame)
1251 {
1252  return ip_geneve_bypass_inline (vm, node, frame, /* is_ip4 */ 1);
1253 }
1254 
1255 /* *INDENT-OFF* */
1257 {
1258  .name = "ip4-geneve-bypass",
1259  .vector_size = sizeof (u32),
1260  .n_next_nodes = IP_GENEVE_BYPASS_N_NEXT,.next_nodes =
1261  {
1262  [IP_GENEVE_BYPASS_NEXT_DROP] = "error-drop",
1263  [IP_GENEVE_BYPASS_NEXT_GENEVE] = "geneve4-input",
1264  },
1265  .format_buffer = format_ip4_header,
1266  .format_trace = format_ip4_forward_next_trace,
1267 };
1268 /* *INDENT-ON* */
1269 
1272  vlib_frame_t * frame)
1273 {
1274  return ip_geneve_bypass_inline (vm, node, frame, /* is_ip4 */ 0);
1275 }
1276 
1277 /* *INDENT-OFF* */
1279 {
1280  .name = "ip6-geneve-bypass",
1281  .vector_size = sizeof (u32),
1282  .n_next_nodes = IP_GENEVE_BYPASS_N_NEXT,
1283  .next_nodes =
1284  {
1285  [IP_GENEVE_BYPASS_NEXT_DROP] = "error-drop",
1286  [IP_GENEVE_BYPASS_NEXT_GENEVE] = "geneve6-input",
1287  },
1288  .format_buffer = format_ip6_header,
1289  .format_trace = format_ip6_forward_next_trace,
1290 };
1291 /* *INDENT-ON* */
1292 
1293 /*
1294  * fd.io coding-style-patch-verification: ON
1295  *
1296  * Local Variables:
1297  * eval: (c-set-style "gnu")
1298  * End:
1299  */
vlib.h
geneve_main_t::vnet_main
vnet_main_t * vnet_main
Definition: geneve.h:186
ip6_address_is_equal
static uword ip6_address_is_equal(const ip6_address_t *a, const ip6_address_t *b)
Definition: ip6_packet.h:167
im
vnet_interface_main_t * im
Definition: interface_output.c:395
geneve_main_t::geneve4_tunnel_by_key
uword * geneve4_tunnel_by_key
Definition: geneve.h:171
udp_header_t::length
u16 length
Definition: udp_packet.h:51
geneve6_input_node
vlib_node_registration_t geneve6_input_node
(constructor) VLIB_REGISTER_NODE (geneve6_input_node)
Definition: decap.c:834
ip6_tcp_udp_icmp_validate_checksum
u32 ip6_tcp_udp_icmp_validate_checksum(vlib_main_t *vm, vlib_buffer_t *p0)
Definition: ip6_forward.c:1163
thread_index
u32 thread_index
Definition: nat44_ei_hairpinning.c:492
bufs
vlib_buffer_t * bufs[VLIB_FRAME_SIZE]
Definition: nat44_ei_out2in.c:717
geneve_tunnel_t::local
ip46_address_t local
Definition: geneve.h:106
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
vlib_prefetch_buffer_header
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:231
geneve.h
ip4_forward_next_trace
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:1240
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
ip4_main
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1105
format_ip6_header
format_function_t format_ip6_header
Definition: format.h:95
vtep4_key_init
static void vtep4_key_init(vtep4_key_t *k4)
Definition: vtep.h:80
geneve_rx_trace_t::vni_rsvd
u32 vni_rsvd
Definition: decap.c:25
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
ip_vxan_bypass_next_t
ip_vxan_bypass_next_t
Definition: decap.c:852
ip6_header_t::protocol
u8 protocol
Definition: ip6_packet.h:304
vlib_get_buffers
vlib_get_buffers(vm, from, b, n_left_from)
geneve_tunnel_t::sw_if_index
u32 sw_if_index
Definition: geneve.h:119
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
geneve_input
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
ip4_address_t::as_u32
u32 as_u32
Definition: ip4_packet.h:57
vnet_interface_main_t
Definition: interface.h:989
vnet_get_geneve_version
static u8 vnet_get_geneve_version(geneve_header_t *h)
Definition: geneve_packet.h:159
geneve4_input_node
vlib_node_registration_t geneve4_input_node
(constructor) VLIB_REGISTER_NODE (geneve4_input_node)
Definition: decap.c:816
GENEVE_N_ERROR
@ GENEVE_N_ERROR
Definition: geneve.h:162
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vnet_get_geneve_vni_network_order
static u32 vnet_get_geneve_vni_network_order(geneve_header_t *h)
Definition: geneve_packet.h:145
geneve_main
geneve_main_t geneve_main
Definition: geneve.c:39
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
from_frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * from_frame
Definition: esp_encrypt.c:1328
GENEVE_VERSION
#define GENEVE_VERSION
Definition: geneve_packet.h:98
ip6_next_header
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:407
vlib_frame_t
Definition: node.h:372
vlib_buffer_length_in_chain
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:433
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
udp_header_t
Definition: udp_packet.h:45
ip4_header_t
Definition: ip4_packet.h:87
format_ip4_forward_next_trace
u8 * format_ip4_forward_next_trace(u8 *s, va_list *args)
Definition: ip4_forward.c:1190
ip4_header_t::length
u16 length
Definition: ip4_packet.h:99
geneve_main_t
Definition: geneve.h:165
i32
signed int i32
Definition: types.h:77
vec_elt
#define vec_elt(v, i)
Get vector value at index i.
Definition: vec_bootstrap.h:210
CLIB_PREFETCH
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
ip4_main_t::fib_index_by_sw_if_index
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:123
vlib_node_runtime_t::errors
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:460
vlib_buffer_advance
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:276
ip4_address_is_multicast
static uword ip4_address_is_multicast(const ip4_address_t *a)
Definition: ip4_packet.h:446
ip6_address_is_multicast
static uword ip6_address_is_multicast(const ip6_address_t *a)
Definition: ip6_packet.h:121
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
geneve_error_strings
static char * geneve_error_strings[]
Definition: decap.c:808
VLIB_NODE_FN
#define VLIB_NODE_FN(node)
Definition: node.h:202
ip4_is_fragment
static int ip4_is_fragment(const ip4_header_t *i)
Definition: ip4_packet.h:168
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
format_geneve_rx_trace
static u8 * format_geneve_rx_trace(u8 *s, va_list *args)
Definition: decap.c:29
PREDICT_FALSE
#define PREDICT_FALSE(x)
Definition: clib.h:124
vnet_feature_next
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:322
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
foreach_geneve_input_next
#define foreach_geneve_input_next
Definition: geneve.h:145
GENEVE_INPUT_N_NEXT
@ GENEVE_INPUT_N_NEXT
Definition: geneve.h:154
uword
u64 uword
Definition: types.h:112
if
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
hash_get
#define hash_get(h, key)
Definition: hash.h:249
vlib_main_t::thread_index
u32 thread_index
Definition: main.h:213
vlib_node_increment_counter
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1244
ip6_header_t::dst_address
ip6_address_t dst_address
Definition: ip6_packet.h:310
vnet_get_geneve_critical_bit
static u8 vnet_get_geneve_critical_bit(geneve_header_t *h)
Definition: geneve_packet.h:199
ip6_main_t::fib_index_by_sw_if_index
u32 * fib_index_by_sw_if_index
Definition: ip6.h:127
geneve_error.def
VNET_INTERFACE_COUNTER_RX
@ VNET_INTERFACE_COUNTER_RX
Definition: interface.h:914
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vnet_interface_main_t::combined_sw_if_counters
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:1023
geneve_main_t::vtep_table
vtep_table_t vtep_table
Definition: geneve.h:176
ip4_header_t::dst_address
ip4_address_t dst_address
Definition: ip4_packet.h:125
ip4_tcp_udp_validate_checksum
u32 ip4_tcp_udp_validate_checksum(vlib_main_t *vm, vlib_buffer_t *p0)
Definition: pnat_test_stubs.h:84
geneve_main_t::geneve6_tunnel_by_key
uword * geneve6_tunnel_by_key
Definition: geneve.h:172
udp_header_t::checksum
u16 checksum
Definition: udp_packet.h:55
IP_GENEVE_BYPASS_N_NEXT
@ IP_GENEVE_BYPASS_N_NEXT
Definition: decap.c:856
geneve_rx_trace_t::next_index
u32 next_index
Definition: decap.c:22
ip6_main
ip6_main_t ip6_main
Definition: ip6_forward.c:2787
data
u8 data[128]
Definition: ipsec_types.api:92
vnet_main_t
Definition: vnet.h:76
vlib_validate_buffer_enqueue_x1
#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
index
u32 index
Definition: flow_types.api:221
geneve_main_t::tunnels
geneve_tunnel_t * tunnels
Definition: geneve.h:168
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
vnet_update_l2_len
static u16 vnet_update_l2_len(vlib_buffer_t *b)
Definition: l2_input.h:298
ip4_header_t::src_address
ip4_address_t src_address
Definition: ip4_packet.h:125
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
vtep6_check
static u8 vtep6_check(vtep_table_t *t, vlib_buffer_t *b0, ip6_header_t *ip60, vtep6_key_t *last_k6)
Definition: vtep.h:155
format
description fragment has unexpected format
Definition: map.api:433
IP_GENEVE_BYPASS_NEXT_DROP
@ IP_GENEVE_BYPASS_NEXT_DROP
Definition: decap.c:854
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
u32
unsigned int u32
Definition: types.h:88
udp_header_t::dst_port
u16 dst_port
Definition: udp_packet.h:48
IP_GENEVE_BYPASS_NEXT_GENEVE
@ IP_GENEVE_BYPASS_NEXT_GENEVE
Definition: decap.c:855
vlib_node_get_runtime
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:116
geneve_tunnel_t
Definition: geneve.h:86
ip6_header_t
Definition: ip6_packet.h:294
format_ip4_header
format_function_t format_ip4_header
Definition: format.h:81
GENEVE_BASE_HEADER_LENGTH
#define GENEVE_BASE_HEADER_LENGTH
Definition: geneve_packet.h:95
ip6_header_t::src_address
ip6_address_t src_address
Definition: ip6_packet.h:310
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
vlib_add_trace
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace.c:628
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
geneve_header_t
Definition: geneve_packet.h:101
u8
unsigned char u8
Definition: types.h:56
validate_geneve_fib
static u32 validate_geneve_fib(vlib_buffer_t *b, geneve_tunnel_t *t, u32 is_ip4)
Definition: decap.c:51
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
vnet_get_geneve_vni
static u32 vnet_get_geneve_vni(geneve_header_t *h)
Definition: geneve_packet.h:138
ip4_input_node
vlib_node_registration_t ip4_input_node
Global ip4 input node.
Definition: ip4_input.c:385
vtep4_check
static u8 vtep4_check(vtep_table_t *t, vlib_buffer_t *b0, ip4_header_t *ip40, vtep4_key_t *last_k4)
Definition: vtep.h:100
word
i64 word
Definition: types.h:111
vlib_validate_buffer_enqueue_x2
#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
geneve_rx_trace_t::error
u32 error
Definition: decap.c:24
geneve_tunnel_t::decap_next_index
u32 decap_next_index
Definition: geneve.h:113
ip6_header_t::payload_length
u16 payload_length
Definition: ip6_packet.h:301
vlib_node_runtime_t
Definition: node.h:454
ip_geneve_bypass_inline
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
vnet_geneve_hdr_1word_ntoh
static void vnet_geneve_hdr_1word_ntoh(geneve_header_t *h)
Definition: geneve_packet.h:226
vnet_get_geneve_options_len
static u8 vnet_get_geneve_options_len(geneve_header_t *h)
Definition: geneve_packet.h:172
geneve_tunnel_t::encap_fib_index
u32 encap_fib_index
Definition: geneve.h:116
from
from
Definition: nat44_ei_hairpinning.c:415
PREDICT_TRUE
#define PREDICT_TRUE(x)
Definition: clib.h:125
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
vlib_get_next_frame
#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:395
geneve_rx_trace_t
Definition: decap.c:20
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
ip6_geneve_bypass_node
vlib_node_registration_t ip6_geneve_bypass_node
(constructor) VLIB_REGISTER_NODE (ip6_geneve_bypass_node)
Definition: decap.c:1278
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
format_ip6_forward_next_trace
u8 * format_ip6_forward_next_trace(u8 *s, va_list *args)
Definition: ip6_forward.c:951
geneve_rx_trace_t::tunnel_index
u32 tunnel_index
Definition: decap.c:23
ip4_header_t::protocol
u8 protocol
Definition: ip4_packet.h:115
vnet_main_t::interface_main
vnet_interface_main_t interface_main
Definition: vnet.h:81
vlib_increment_combined_counter
vlib_increment_combined_counter(ccm, ti, sw_if_index, n_buffers, n_bytes)
vtep6_key_init
static void vtep6_key_init(vtep6_key_t *k6)
Definition: vtep.h:86
ip4_next_header
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:196
ip4_geneve_bypass_node
vlib_node_registration_t ip4_geneve_bypass_node
(constructor) VLIB_REGISTER_NODE (ip4_geneve_bypass_node)
Definition: decap.c:1256
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169