FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
vxlan_gpe_ioam.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
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  */
17 #include <vnet/ip/format.h>
19 #include <vnet/dpo/load_balance.h>
20 #include <vnet/fib/ip4_fib.h>
21 #include <vnet/fib/fib_entry.h>
22 
24 
25 int
27  int has_pot_option, int has_ppc_option,
28  u8 ipv6_set)
29 {
31  u32 size;
32  vxlan_gpe_ioam_hdr_t *vxlan_gpe_ioam_hdr;
33  u8 *current;
34  u8 trace_data_size = 0;
35  u8 pot_data_size = 0;
36 
37  if (has_trace_option == 0 && has_pot_option == 0)
38  return -1;
39 
40  /* Work out how much space we need */
41  size = sizeof (vxlan_gpe_ioam_hdr_t);
42 
43  if (has_trace_option
45  {
46  size += sizeof (vxlan_gpe_ioam_option_t);
48  }
49  if (has_pot_option
51  {
52  size += sizeof (vxlan_gpe_ioam_option_t);
54  }
55 
56  t->rewrite_size = size;
57 
58  if (!ipv6_set)
59  {
60  vxlan4_gpe_rewrite (t, size, VXLAN_GPE_PROTOCOL_IOAM,
61  hm->encap_v4_next_node);
62  vxlan_gpe_ioam_hdr =
64  sizeof (ip4_vxlan_gpe_header_t));
65  }
66  else
67  {
68  vxlan6_gpe_rewrite (t, size, VXLAN_GPE_PROTOCOL_IOAM,
70  vxlan_gpe_ioam_hdr =
72  sizeof (ip6_vxlan_gpe_header_t));
73  }
74 
75 
76  vxlan_gpe_ioam_hdr->type = VXLAN_GPE_PROTOCOL_IOAM;
77  /* Length of the header in octets */
78  vxlan_gpe_ioam_hdr->length = size;
79  vxlan_gpe_ioam_hdr->protocol = t->protocol;
80  current = (u8 *) vxlan_gpe_ioam_hdr + sizeof (vxlan_gpe_ioam_hdr_t);
81 
82  if (has_trace_option
84  {
85  if (0 != hm->add_options[VXLAN_GPE_OPTION_TYPE_IOAM_TRACE] (current,
86  &trace_data_size))
87  return -1;
88  current += trace_data_size;
89  }
90  if (has_pot_option
92  {
93  pot_data_size =
95  if (0 ==
97  (current, &pot_data_size))
98  current += pot_data_size;
99  }
100 
101  return 0;
102 }
103 
104 int
106  int has_pot_option, int has_ppc_option,
107  u8 ipv6_set)
108 {
109 
110  t->rewrite_size = 0;
111 
112  if (!ipv6_set)
113  {
115  }
116  else
117  {
119  }
120 
121 
122  return 0;
123 }
124 
125 clib_error_t *
127  int has_trace_option, int has_pot_option,
128  int has_ppc_option, u8 ipv6_set)
129 {
130  int rv;
131  rv = vxlan_gpe_ioam_clear_rewrite (t, 0, 0, 0, 0);
132 
133  if (rv == 0)
134  {
135  return (0);
136  }
137  else
138  {
139  return clib_error_return_code (0, rv, 0,
140  "vxlan_gpe_ioam_clear_rewrite returned %d",
141  rv);
142  }
143 
144 }
145 
146 
147 clib_error_t *
149  int has_trace_option, int has_pot_option,
150  int has_ppc_option, u8 ipv6_set)
151 {
152  int rv;
153  rv = vxlan_gpe_ioam_set_rewrite (t, has_trace_option,
154  has_pot_option, has_ppc_option, ipv6_set);
155 
156  if (rv == 0)
157  {
158  return (0);
159  }
160  else
161  {
162  return clib_error_return_code (0, rv, 0,
163  "vxlan_gpe_ioam_set_rewrite returned %d",
164  rv);
165  }
166 
167 }
168 
169 static void
171  u32 sw_if_index0, u8 is_add)
172 {
173 
174 
175 
176  vnet_feature_enable_disable ("ip4-output", "vxlan-gpe-transit-ioam",
177  sw_if_index0, is_add,
178  0 /* void *feature_config */ ,
179  0 /* u32 n_feature_config_bytes */ );
180  return;
181 }
182 
183 void
185 {
186  vnet_sw_interface_t *si = 0;
187  vnet_main_t *vnm = vnet_get_main ();
189 
190  pool_foreach (si, im->sw_interfaces, (
191  {
192  vxlan_gpe_set_clear_output_feature_on_intf
193  (vm, si->sw_if_index, 0);
194  }));
195  return;
196 }
197 
198 
201 
202 int
204  ip46_address_t dst_addr,
205  u32 outer_fib_index,
206  u8 is_ipv4, u8 is_add)
207 {
209  u32 fib_index0 = 0;
210  u32 sw_if_index0 = ~0;
211 
212  fib_node_index_t fei = ~0;
213  fib_entry_t *fib_entry;
214  u32 adj_index0;
215  ip_adjacency_t *adj0;
216  fib_prefix_t fib_prefix;
217  //fib_forward_chain_type_t fct;
218  load_balance_t *lb_m, *lb_b;
219  const dpo_id_t *dpo0, *dpo1;
220  u32 i, j;
221  //vnet_hw_interface_t *hw;
222 
223  if (is_ipv4)
224  {
225  clib_memset (&fib_prefix, 0, sizeof (fib_prefix_t));
226  fib_prefix.fp_len = 32;
227  fib_prefix.fp_proto = FIB_PROTOCOL_IP4;
228  fib_prefix.fp_addr = dst_addr;
229  }
230  else
231  {
232  return 0;
233  }
234 
235  fei = fib_table_lookup (fib_index0, &fib_prefix);
236  fib_entry = fib_entry_get (fei);
237 
238  //fct = fib_entry_get_default_chain_type (fib_entry);
239 
240  if (!dpo_id_is_valid (&fib_entry->fe_lb /*[fct] */ ))
241  {
242  return (-1);
243  }
244 
245  lb_m = load_balance_get (fib_entry->fe_lb /*[fct] */ .dpoi_index);
246 
247  for (i = 0; i < lb_m->lb_n_buckets; i++)
248  {
249  dpo0 = load_balance_get_bucket_i (lb_m, i);
250 
251  if (dpo0->dpoi_type == DPO_LOAD_BALANCE)
252  {
253  lb_b = load_balance_get (dpo0->dpoi_index);
254 
255  for (j = 0; j < lb_b->lb_n_buckets; j++)
256  {
257  dpo1 = load_balance_get_bucket_i (lb_b, j);
258 
259  if (dpo1->dpoi_type == DPO_ADJACENCY)
260  {
261  adj_index0 = dpo1->dpoi_index;
262 
263  if (ADJ_INDEX_INVALID == adj_index0)
264  {
265  continue;
266  }
267 
268  adj0 = adj_get (adj_index0);
269  sw_if_index0 = adj0->rewrite_header.sw_if_index;
270 
271  if (~0 == sw_if_index0)
272  {
273  continue;
274  }
275 
276 
277  if (is_add)
278  {
279  vnet_feature_enable_disable ("ip4-output",
280  "vxlan-gpe-transit-ioam",
281  sw_if_index0, is_add, 0
282  /* void *feature_config */
283  , 0 /* u32 n_feature_config_bytes */
284  );
285 
287  sw_if_index0, ~0);
288  hm->bool_ref_by_sw_if_index[sw_if_index0] = 1;
289  }
290  else
291  {
292  hm->bool_ref_by_sw_if_index[sw_if_index0] = ~0;
293  }
294  }
295  }
296  }
297  }
298 
299  if (is_ipv4)
300  {
301 
302  uword *t = NULL;
304  fib_prefix_t key4, *key4_copy;
305  hash_pair_t *hp;
306  clib_memset (&key4, 0, sizeof (key4));
307  key4.fp_proto = FIB_PROTOCOL_IP4;
308  key4.fp_addr.ip4.as_u32 = fib_prefix.fp_addr.ip4.as_u32;
309  t = hash_get_mem (hm->dst_by_ip4, &key4);
310  if (is_add)
311  {
312  if (t)
313  {
314  return 0;
315  }
317  clib_memset (t1, 0, sizeof (*t1));
319  t1->dst_addr.ip4.as_u32 = fib_prefix.fp_addr.ip4.as_u32;
320  key4_copy = clib_mem_alloc (sizeof (*key4_copy));
321  clib_memcpy (key4_copy, &key4, sizeof (*key4_copy));
322  hash_set_mem (hm->dst_by_ip4, key4_copy, t1 - hm->dst_tunnels);
323  /*
324  * Attach to the FIB entry for the VxLAN-GPE destination
325  * and become its child. The dest route will invoke a callback
326  * when the fib entry changes, it can be used to
327  * re-program the output feature on the egress interface.
328  */
329 
330  const fib_prefix_t tun_dst_pfx = {
331  .fp_len = 32,
332  .fp_proto = FIB_PROTOCOL_IP4,
333  .fp_addr = {.ip4 = t1->dst_addr.ip4,}
334  };
335 
336  t1->fib_entry_index =
337  fib_table_entry_special_add (outer_fib_index,
338  &tun_dst_pfx,
340  t1->sibling_index =
342  hm->fib_entry_type, t1 - hm->dst_tunnels);
343  t1->outer_fib_index = outer_fib_index;
344 
345  }
346  else
347  {
348  if (!t)
349  {
350  return 0;
351  }
352  t1 = pool_elt_at_index (hm->dst_tunnels, t[0]);
353  hp = hash_get_pair (hm->dst_by_ip4, &key4);
354  key4_copy = (void *) (hp->key);
355  hash_unset_mem (hm->dst_by_ip4, &key4);
356  clib_mem_free (key4_copy);
357  pool_put (hm->dst_tunnels, t1);
358  }
359  }
360  else
361  {
362  // TBD for IPv6
363  }
364 
365  return 0;
366 }
367 
368 void
370 {
373  u32 i;
374  if (pool_elts (hm->dst_tunnels) == 0)
375  return;
380  pool_foreach (t, hm->dst_tunnels, (
381  {
382  vxlan_gpe_enable_disable_ioam_for_dest
383  (hm->vlib_main,
384  t->dst_addr,
385  t->outer_fib_index,
386  (t->fp_proto == FIB_PROTOCOL_IP4), 1
387  /* is_add */
388  );
389  }
390  ));
391  return;
392 }
393 
394 void
396 {
398  u32 sw_if_index0 = 0;
399  for (sw_if_index0 = 0;
400  sw_if_index0 < vec_len (hm->bool_ref_by_sw_if_index); sw_if_index0++)
401  {
402  if (hm->bool_ref_by_sw_if_index[sw_if_index0] == 0xFF)
403  {
405  (hm->vlib_main, sw_if_index0, 0);
406  }
407  }
408 
409  return;
410 }
411 
412 static clib_error_t *
414  vm,
416  * input, vlib_cli_command_t * cmd)
417 {
419  ip46_address_t local, remote;
420  u8 local_set = 0;
421  u8 remote_set = 0;
422  u8 ipv4_set = 0;
423  u8 ipv6_set = 0;
424  u32 vni;
425  u8 vni_set = 0;
426  u8 disable = 0;
427  clib_error_t *rv = 0;
428  vxlan4_gpe_tunnel_key_t key4;
429  vxlan6_gpe_tunnel_key_t key6;
430  uword *p;
432  vxlan_gpe_tunnel_t *t = 0;
434  {
435  if (unformat (input, "local %U", unformat_ip4_address, &local.ip4))
436  {
437  local_set = 1;
438  ipv4_set = 1;
439  }
440  else
441  if (unformat (input, "remote %U", unformat_ip4_address, &remote.ip4))
442  {
443  remote_set = 1;
444  ipv4_set = 1;
445  }
446  else if (unformat (input, "local %U", unformat_ip6_address, &local.ip6))
447  {
448  local_set = 1;
449  ipv6_set = 1;
450  }
451  else
452  if (unformat (input, "remote %U", unformat_ip6_address, &remote.ip6))
453  {
454  remote_set = 1;
455  ipv6_set = 1;
456  }
457  else if (unformat (input, "vni %d", &vni))
458  vni_set = 1;
459  else if (unformat (input, "disable"))
460  disable = 1;
461  else
462  break;
463  }
464 
465  if (local_set == 0)
466  return clib_error_return (0, "tunnel local address not specified");
467  if (remote_set == 0)
468  return clib_error_return (0, "tunnel remote address not specified");
469  if (ipv4_set && ipv6_set)
470  return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
471  if ((ipv4_set
472  && memcmp (&local.ip4, &remote.ip4,
473  sizeof (local.ip4)) == 0) || (ipv6_set
474  &&
475  memcmp
476  (&local.ip6,
477  &remote.ip6,
478  sizeof (local.ip6)) == 0))
479  return clib_error_return (0, "src and dst addresses are identical");
480  if (vni_set == 0)
481  return clib_error_return (0, "vni not specified");
482  if (!ipv6_set)
483  {
484  key4.local = local.ip4.as_u32;
485  key4.remote = remote.ip4.as_u32;
486  key4.vni = clib_host_to_net_u32 (vni << 8);
487  key4.pad = 0;
488  p = hash_get_mem (gm->vxlan4_gpe_tunnel_by_key, &key4);
489  }
490  else
491  {
492  key6.local.as_u64[0] = local.ip6.as_u64[0];
493  key6.local.as_u64[1] = local.ip6.as_u64[1];
494  key6.remote.as_u64[0] = remote.ip6.as_u64[0];
495  key6.remote.as_u64[1] = remote.ip6.as_u64[1];
496  key6.vni = clib_host_to_net_u32 (vni << 8);
497  p = hash_get_mem (gm->vxlan6_gpe_tunnel_by_key, &key6);
498  }
499 
500  if (!p)
501  return clib_error_return (0, "VxLAN Tunnel not found");
502  t = pool_elt_at_index (gm->tunnels, p[0]);
503  if (!disable)
504  {
505  rv =
507  hm->has_pot_option, hm->has_ppc_option, ipv6_set);
508  }
509  else
510  {
511  rv = vxlan_gpe_ioam_clear (t, 0, 0, 0, 0);
512  }
513  return rv;
514 }
515 
516 
517 /* *INDENT-OFF* */
518 VLIB_CLI_COMMAND (vxlan_gpe_set_ioam_rewrite_cmd, static) = {
519  .path = "set vxlan-gpe-ioam",
520  .short_help = "set vxlan-gpe-ioam vxlan <src-ip> <dst_ip> <vnid> [disable]",
522 };
523 /* *INDENT-ON* */
524 
525 
526 
527 clib_error_t *
528 vxlan_gpe_ioam_enable (int has_trace_option,
529  int has_pot_option, int has_ppc_option)
530 {
532  hm->has_trace_option = has_trace_option;
533  hm->has_pot_option = has_pot_option;
534  hm->has_ppc_option = has_ppc_option;
535  if (hm->has_trace_option)
536  {
538  }
539 
540  return 0;
541 }
542 
543 clib_error_t *
545  has_trace_option,
546  int has_pot_option, int has_ppc_option)
547 {
549  hm->has_trace_option = has_trace_option;
550  hm->has_pot_option = has_pot_option;
551  hm->has_ppc_option = has_ppc_option;
552  if (!hm->has_trace_option)
553  {
555  }
556 
557  return 0;
558 }
559 
560 void
562 {
564  hm->decap_v4_next_override = next;
565  return;
566 }
567 
568 static clib_error_t *
571  * input, vlib_cli_command_t * cmd)
572 {
573  int has_trace_option = 0;
574  int has_pot_option = 0;
575  int has_ppc_option = 0;
576  clib_error_t *rv = 0;
578  {
579  if (unformat (input, "trace"))
580  has_trace_option = 1;
581  else if (unformat (input, "pot"))
582  has_pot_option = 1;
583  else if (unformat (input, "ppc encap"))
584  has_ppc_option = PPC_ENCAP;
585  else if (unformat (input, "ppc decap"))
586  has_ppc_option = PPC_DECAP;
587  else if (unformat (input, "ppc none"))
588  has_ppc_option = PPC_NONE;
589  else
590  break;
591  }
592 
593 
594  rv =
595  vxlan_gpe_ioam_enable (has_trace_option, has_pot_option, has_ppc_option);
596  return rv;
597 }
598 
599 /* *INDENT-OFF* */
600 VLIB_CLI_COMMAND (vxlan_gpe_set_ioam_flags_cmd, static) =
601 {
602 .path = "set vxlan-gpe-ioam rewrite",
603 .short_help = "set vxlan-gpe-ioam [trace] [pot] [ppc <encap|decap>]",
605 /* *INDENT-ON* */
606 
607 
609  (vlib_main_t * vm, ip46_address_t dst_addr, u32 outer_fib_index,
610  u8 ipv4_set)
611 {
614 
616  dst_addr, outer_fib_index, ipv4_set,
617  0);
618  if (pool_elts (hm->dst_tunnels) == 0)
619  {
621  return 0;
622  }
623 
624  pool_foreach (t, hm->dst_tunnels, (
625  {
626  vxlan_gpe_enable_disable_ioam_for_dest
627  (hm->vlib_main,
628  t->dst_addr,
629  t->outer_fib_index,
630  (t->fp_proto ==
631  FIB_PROTOCOL_IP4), 1 /* is_add */ );
632  }
633  ));
635  return (0);
636 
637 }
638 
641 {
643  ip46_address_t dst_addr;
644  u8 dst_addr_set = 0;
645  u8 ipv4_set = 0;
646  u8 ipv6_set = 0;
647  u8 disable = 0;
648  clib_error_t *rv = 0;
649  u32 outer_fib_index = 0;
651  {
652  if (unformat (input, "dst-ip %U", unformat_ip4_address, &dst_addr.ip4))
653  {
654  dst_addr_set = 1;
655  ipv4_set = 1;
656  }
657  else
658  if (unformat
659  (input, "dst-ip %U", unformat_ip6_address, &dst_addr.ip6))
660  {
661  dst_addr_set = 1;
662  ipv6_set = 1;
663  }
664  else if (unformat (input, "outer-fib-index %d", &outer_fib_index))
665  {
666  }
667 
668  else if (unformat (input, "disable"))
669  disable = 1;
670  else
671  break;
672  }
673 
674  if (dst_addr_set == 0)
675  return clib_error_return (0, "tunnel destination address not specified");
676  if (ipv4_set && ipv6_set)
677  return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
678  if (!disable)
679  {
681  dst_addr, outer_fib_index,
682  ipv4_set, 1);
683  }
684  else
685  {
687  (vm, dst_addr, outer_fib_index, ipv4_set);
688  }
689  return rv;
690 }
691 
692  /* *INDENT-OFF* */
693 VLIB_CLI_COMMAND (vxlan_gpe_set_ioam_transit_rewrite_cmd, static) = {
694  .path = "set vxlan-gpe-ioam-transit",
695  .short_help = "set vxlan-gpe-ioam-transit dst-ip <dst_ip> [outer-fib-index <outer_fib_index>] [disable]",
697 };
698 /* *INDENT-ON* */
699 
702 {
703  return (vxlan_gpe_ioam_disable (0, 0, 0));
704 }
705 
706 /* *INDENT-OFF* */
707 VLIB_CLI_COMMAND (vxlan_gpe_clear_ioam_flags_cmd, static) =
708 {
709 .path = "clear vxlan-gpe-ioam rewrite",
710 .short_help = "clear vxlan-gpe-ioam rewrite",
712 };
713 /* *INDENT-ON* */
714 
715 
716 /**
717  * Function definition to backwalk a FIB node
718  */
721 {
724 }
725 
726 /**
727  * Function definition to get a FIB node from its index
728  */
729 static fib_node_t *
731 {
733  return (&hm->node);
734 }
735 
736 /**
737  * Function definition to inform the FIB node that its last lock has gone.
738  */
739 static void
741 {
742  ASSERT (0);
743 }
744 
745 
746 /*
747  * Virtual function table registered by MPLS GRE tunnels
748  * for participation in the FIB object graph.
749  */
750 const static fib_node_vft_t vxlan_gpe_ioam_vft = {
752  .fnv_last_lock = vxlan_gpe_ioam_last_lock_gone,
753  .fnv_back_walk = vxlan_gpe_ioam_back_walk,
754 };
755 
756 void
758 {
760  hm->fib_entry_type = fib_node_register_new_type (&vxlan_gpe_ioam_vft);
761  return;
762 }
763 
764 /*
765  * fd.io coding-style-patch-verification: ON
766  *
767  * Local Variables:
768  * eval: (c-set-style "gnu")
769  * End:
770  */
u16 lb_n_buckets
number of buckets in the load-balance.
Definition: load_balance.h:116
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
clib_error_t * vxlan_gpe_ioam_enable(int has_trace_option, int has_pot_option, int has_ppc_option)
uword * vxlan6_gpe_tunnel_by_key
lookup IPv6 VXLAN GPE tunnel by key
Definition: vxlan_gpe.h:204
Recursive resolution source.
Definition: fib_entry.h:125
An entry in a FIB table.
Definition: fib_entry.h:462
void vxlan_gpe_set_next_override(uword next)
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
vlib_main_t * vlib_main
State convenience vlib_main_t.
#define VXLAN_GPE_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT
vnet_interface_main_t interface_main
Definition: vnet.h:56
u32 fib_entry_child_add(fib_node_index_t fib_entry_index, fib_node_type_t child_type, fib_node_index_t child_index)
Definition: fib_entry.c:565
static int dpo_id_is_valid(const dpo_id_t *dpoi)
Return true if the DPO object is valid, i.e.
Definition: dpo.h:207
#define NULL
Definition: clib.h:58
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
IP unicast adjacency.
Definition: adj.h:221
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
VXLAN GPE definitions.
#define PPC_NONE
int vxlan_gpe_enable_disable_ioam_for_dest(vlib_main_t *vm, ip46_address_t dst_addr, u32 outer_fib_index, u8 is_ipv4, u8 is_add)
int vxlan6_gpe_rewrite(vxlan_gpe_tunnel_t *t, u32 extension_size, u8 protocol_override, uword encap_next_node)
Calculate IPv6 VXLAN GPE rewrite header.
Definition: vxlan_gpe.c:336
int i
#define hash_set_mem(h, key, value)
Definition: hash.h:275
fib_node_index_t fib_entry_index
clib_error_t * vxlan_gpe_ioam_clear(vxlan_gpe_tunnel_t *t, int has_trace_option, int has_pot_option, int has_ppc_option, u8 ipv6_set)
void vxlan_gpe_ioam_interface_init(void)
unsigned char u8
Definition: types.h:56
fib_node_type_t fib_node_register_new_type(const fib_node_vft_t *vft)
Create a new FIB node type and Register the function table for it.
Definition: fib_node.c:80
u8 protocol
see vxlan_gpe_protocol_t
#define clib_memcpy(d, s, n)
Definition: string.h:180
clib_error_t * clear_vxlan_gpe_ioam_rewrite_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:433
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
unformat_function_t unformat_ip4_address
Definition: format.h:70
clib_error_t * vxlan_gpe_ioam_disable(int has_trace_option, int has_pot_option, int has_ppc_option)
int vxlan_gpe_ioam_disable_for_dest(vlib_main_t *vm, ip46_address_t dst_addr, u32 outer_fib_index, u8 ipv4_set)
vxlan_gpe_ioam_main_t vxlan_gpe_ioam_main
Aggregrate type for a prefix.
Definition: fib_types.h:203
#define clib_error_return(e, args...)
Definition: error.h:99
static clib_error_t * vxlan_gpe_set_ioam_rewrite_command_fn(vlib_main_t *vm, unformat_input_t() *input, vlib_cli_command_t *cmd)
#define hash_get_pair(h, key)
Definition: hash.h:252
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:207
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
Definition: fib_table.c:66
u8 * rewrite
Rewrite string.
Definition: vxlan_gpe.h:108
VXLAN GPE packet header structure.
Definition: fib_entry.h:275
static void vxlan_gpe_set_clear_output_feature_on_intf(vlib_main_t *vm, u32 sw_if_index0, u8 is_add)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
int vxlan4_gpe_rewrite(vxlan_gpe_tunnel_t *t, u32 extension_size, u8 protocol_override, uword encap_next_node)
Calculate IPv4 VXLAN GPE rewrite header.
Definition: vxlan_gpe.c:278
#define ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
Definition: adj_types.h:36
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
uword size
#define hash_unset_mem(h, key)
Definition: hash.h:291
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
#define gm
Definition: dlmalloc.c:1217
Struct for VXLAN GPE tunnel.
Definition: vxlan_gpe.h:102
dpo_type_t dpoi_type
the type
Definition: dpo.h:172
static const dpo_id_t * load_balance_get_bucket_i(const load_balance_t *lb, u32 bucket)
Definition: load_balance.h:228
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
load-balancing over a choice of [un]equal cost paths
Definition: dpo.h:102
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
vxlan_gpe_main_t vxlan_gpe_main
Definition: vxlan_gpe.c:45
The FIB DPO provieds;.
Definition: load_balance.h:106
u8 protocol
encapsulated protocol
Definition: vxlan_gpe.h:111
int vxlan_gpe_trace_profile_setup(void)
An node in the FIB graph.
Definition: fib_node.h:291
unformat_function_t unformat_ip6_address
Definition: format.h:91
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:230
#define VXLAN_GPE_OPTION_TYPE_IOAM_TRACE
fib_node_index_t fib_table_entry_special_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags)
Add a &#39;special&#39; entry to the FIB.
Definition: fib_table.c:388
clib_error_t * vxlan_gpe_ioam_set(vxlan_gpe_tunnel_t *t, int has_trace_option, int has_pot_option, int has_ppc_option, u8 ipv6_set)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
static fib_node_t * vxlan_gpe_ioam_fib_node_get(fib_node_index_t index)
Function definition to get a FIB node from its index.
vxlan_gpe_ioam_dest_tunnels_t * dst_tunnels
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
fib_node_get_t fnv_get
Definition: fib_node.h:279
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:50
Context passed between object during a back walk.
Definition: fib_node.h:204
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
fib_node_t node
Linkage into the FIB object graph.
int(* add_options[256])(u8 *rewrite_string, u8 *rewrite_size)
#define ASSERT(truth)
void vxlan_gpe_refresh_output_feature_on_all_dest(void)
u8 rewrite_size
rewrite size for dynamic plugins like iOAM
Definition: vxlan_gpe.h:140
Struct for VXLAN GPE node state.
Definition: vxlan_gpe.h:196
u8 is_add
Definition: ipsec_gre.api:36
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:219
static void clib_mem_free(void *p)
Definition: mem.h:205
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
int vxlan_gpe_ioam_clear_rewrite(vxlan_gpe_tunnel_t *t, int has_trace_option, int has_pot_option, int has_ppc_option, u8 ipv6_set)
#define PPC_DECAP
static void * clib_mem_alloc(uword size)
Definition: mem.h:132
fib_forward_chain_type_t fib_entry_get_default_chain_type(const fib_entry_t *fib_entry)
Definition: fib_entry.c:80
u8 * bool_ref_by_sw_if_index
per sw_if_index, to maintain bitmap
vxlan_gpe_tunnel_t * tunnels
vector of encap tunnel instances
Definition: vxlan_gpe.h:199
dpo_id_t fe_lb
The load-balance used for forwarding.
Definition: fib_entry.h:488
static fib_node_back_walk_rc_t vxlan_gpe_ioam_back_walk(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Function definition to backwalk a FIB node.
uword * vxlan4_gpe_tunnel_by_key
lookup IPv4 VXLAN GPE tunnel by key
Definition: vxlan_gpe.h:202
fib_node_type_t fib_entry_type
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u64 uword
Definition: types.h:112
VXLAN GPE Extension (iOAM) Header definition.
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:815
u32 vni
Definition: vxlan_gbp.api:42
void vxlan_gpe_clear_output_feature_on_all_intfs(vlib_main_t *vm)
#define PPC_ENCAP
#define hash_get_mem(h, key)
Definition: hash.h:269
void vxlan_gpe_clear_output_feature_on_select_intfs(void)
A FIB graph nodes virtual function table.
Definition: fib_node.h:278
static void vxlan_gpe_ioam_last_lock_gone(fib_node_t *node)
Function definition to inform the FIB node that its last lock has gone.
ip46_address_t dst_addr
#define clib_error_return_code(e, code, flags, args...)
Definition: error.h:93
static clib_error_t * vxlan_gpe_set_ioam_flags_command_fn(vlib_main_t *vm, unformat_input_t() *input, vlib_cli_command_t *cmd)
int vxlan_gpe_ioam_set_rewrite(vxlan_gpe_tunnel_t *t, int has_trace_option, int has_pot_option, int has_ppc_option, u8 ipv6_set)
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:486
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
static clib_error_t * vxlan_gpe_set_ioam_transit_rewrite_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
int vxlan_gpe_trace_profile_cleanup(void)
uword key
Definition: hash.h:162
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:274
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128