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