FD.io VPP  v17.01.1-3-gc6833f8
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/fib/ip6_fib.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  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 =
269  ip_get_adjacency (&(ip4_main.lookup_main), adj_index0);
270  sw_if_index0 = adj0->rewrite_header.sw_if_index;
271 
272  if (~0 == sw_if_index0)
273  {
274  continue;
275  }
276 
277 
278  if (is_add)
279  {
280  vnet_feature_enable_disable ("ip4-output",
281  "vxlan-gpe-transit-ioam",
282  sw_if_index0, is_add, 0
283  /* void *feature_config */
284  , 0 /* u32 n_feature_config_bytes */
285  );
286 
288  sw_if_index0, ~0);
289  hm->bool_ref_by_sw_if_index[sw_if_index0] = 1;
290  }
291  else
292  {
293  hm->bool_ref_by_sw_if_index[sw_if_index0] = ~0;
294  }
295  }
296  }
297  }
298  }
299 
300  if (is_ipv4)
301  {
302 
303  uword *t = NULL;
305  fib_prefix_t key4, *key4_copy;
306  hash_pair_t *hp;
307  memset (&key4, 0, sizeof (key4));
308  key4.fp_proto = FIB_PROTOCOL_IP4;
309  key4.fp_addr.ip4.as_u32 = fib_prefix.fp_addr.ip4.as_u32;
310  t = hash_get_mem (hm->dst_by_ip4, &key4);
311  if (is_add)
312  {
313  if (t)
314  {
315  return 0;
316  }
318  memset (t1, 0, sizeof (*t1));
320  t1->dst_addr.ip4.as_u32 = fib_prefix.fp_addr.ip4.as_u32;
321  key4_copy = clib_mem_alloc (sizeof (*key4_copy));
322  clib_memcpy (key4_copy, &key4, sizeof (*key4_copy));
323  hash_set_mem (hm->dst_by_ip4, key4_copy, t1 - hm->dst_tunnels);
324  /*
325  * Attach to the FIB entry for the VxLAN-GPE destination
326  * and become its child. The dest route will invoke a callback
327  * when the fib entry changes, it can be used to
328  * re-program the output feature on the egress interface.
329  */
330 
331  const fib_prefix_t tun_dst_pfx = {
332  .fp_len = 32,
333  .fp_proto = FIB_PROTOCOL_IP4,
334  .fp_addr = {.ip4 = t1->dst_addr.ip4,}
335  };
336 
337  t1->fib_entry_index =
338  fib_table_entry_special_add (outer_fib_index,
339  &tun_dst_pfx,
343  t1->sibling_index =
345  hm->fib_entry_type, t1 - hm->dst_tunnels);
346  t1->outer_fib_index = outer_fib_index;
347 
348  }
349  else
350  {
351  if (!t)
352  {
353  return 0;
354  }
355  t1 = pool_elt_at_index (hm->dst_tunnels, t[0]);
356  hp = hash_get_pair (hm->dst_by_ip4, &key4);
357  key4_copy = (void *) (hp->key);
358  hash_unset_mem (hm->dst_by_ip4, &key4);
359  clib_mem_free (key4_copy);
360  pool_put (hm->dst_tunnels, t1);
361  }
362  }
363  else
364  {
365  // TBD for IPv6
366  }
367 
368  return 0;
369 }
370 
371 void
373 {
376  u32 i;
377  if (pool_elts (hm->dst_tunnels) == 0)
378  return;
383  pool_foreach (t, hm->dst_tunnels, (
384  {
385  vxlan_gpe_enable_disable_ioam_for_dest
386  (hm->vlib_main,
387  t->dst_addr,
388  t->outer_fib_index,
389  (t->fp_proto == FIB_PROTOCOL_IP4), 1
390  /* is_add */
391  );
392  }
393  ));
394  return;
395 }
396 
397 void
399 {
401  u32 sw_if_index0 = 0;
402  for (sw_if_index0 = 0;
403  sw_if_index0 < vec_len (hm->bool_ref_by_sw_if_index); sw_if_index0++)
404  {
405  if (hm->bool_ref_by_sw_if_index[sw_if_index0] == 0xFF)
406  {
408  (hm->vlib_main, sw_if_index0, 0);
409  }
410  }
411 
412  return;
413 }
414 
415 static clib_error_t *
417  vm,
419  * input, vlib_cli_command_t * cmd)
420 {
422  ip46_address_t local, remote;
423  u8 local_set = 0;
424  u8 remote_set = 0;
425  u8 ipv4_set = 0;
426  u8 ipv6_set = 0;
427  u32 vni;
428  u8 vni_set = 0;
429  u8 disable = 0;
430  clib_error_t *rv = 0;
431  vxlan4_gpe_tunnel_key_t key4;
432  vxlan6_gpe_tunnel_key_t key6;
433  uword *p;
435  vxlan_gpe_tunnel_t *t = 0;
437  {
438  if (unformat (input, "local %U", unformat_ip4_address, &local.ip4))
439  {
440  local_set = 1;
441  ipv4_set = 1;
442  }
443  else
444  if (unformat (input, "remote %U", unformat_ip4_address, &remote.ip4))
445  {
446  remote_set = 1;
447  ipv4_set = 1;
448  }
449  else if (unformat (input, "local %U", unformat_ip6_address, &local.ip6))
450  {
451  local_set = 1;
452  ipv6_set = 1;
453  }
454  else
455  if (unformat (input, "remote %U", unformat_ip6_address, &remote.ip6))
456  {
457  remote_set = 1;
458  ipv6_set = 1;
459  }
460  else if (unformat (input, "vni %d", &vni))
461  vni_set = 1;
462  else if (unformat (input, "disable"))
463  disable = 1;
464  else
465  break;
466  }
467 
468  if (local_set == 0)
469  return clib_error_return (0, "tunnel local address not specified");
470  if (remote_set == 0)
471  return clib_error_return (0, "tunnel remote address not specified");
472  if (ipv4_set && ipv6_set)
473  return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
474  if ((ipv4_set
475  && memcmp (&local.ip4, &remote.ip4,
476  sizeof (local.ip4)) == 0) || (ipv6_set
477  &&
478  memcmp
479  (&local.ip6,
480  &remote.ip6,
481  sizeof (local.ip6)) == 0))
482  return clib_error_return (0, "src and dst addresses are identical");
483  if (vni_set == 0)
484  return clib_error_return (0, "vni not specified");
485  if (!ipv6_set)
486  {
487  key4.local = local.ip4.as_u32;
488  key4.remote = remote.ip4.as_u32;
489  key4.vni = clib_host_to_net_u32 (vni << 8);
490  key4.pad = 0;
491  p = hash_get_mem (gm->vxlan4_gpe_tunnel_by_key, &key4);
492  }
493  else
494  {
495  key6.local.as_u64[0] = local.ip6.as_u64[0];
496  key6.local.as_u64[1] = local.ip6.as_u64[1];
497  key6.remote.as_u64[0] = remote.ip6.as_u64[0];
498  key6.remote.as_u64[1] = remote.ip6.as_u64[1];
499  key6.vni = clib_host_to_net_u32 (vni << 8);
500  p = hash_get_mem (gm->vxlan6_gpe_tunnel_by_key, &key6);
501  }
502 
503  if (!p)
504  return clib_error_return (0, "VxLAN Tunnel not found");
505  t = pool_elt_at_index (gm->tunnels, p[0]);
506  if (!disable)
507  {
508  rv =
510  hm->has_pot_option, hm->has_ppc_option, ipv6_set);
511  }
512  else
513  {
514  rv = vxlan_gpe_ioam_clear (t, 0, 0, 0, 0);
515  }
516  return rv;
517 }
518 
519 
520 /* *INDENT-OFF* */
521 VLIB_CLI_COMMAND (vxlan_gpe_set_ioam_rewrite_cmd, static) = {
522  .path = "set vxlan-gpe-ioam",
523  .short_help = "set vxlan-gpe-ioam vxlan <src-ip> <dst_ip> <vnid> [disable]",
525 };
526 /* *INDENT-ON* */
527 
528 
529 
530 clib_error_t *
531 vxlan_gpe_ioam_enable (int has_trace_option,
532  int has_pot_option, int has_ppc_option)
533 {
535  hm->has_trace_option = has_trace_option;
536  hm->has_pot_option = has_pot_option;
537  hm->has_ppc_option = has_ppc_option;
538  if (hm->has_trace_option)
539  {
541  }
542 
543  return 0;
544 }
545 
546 clib_error_t *
548  has_trace_option,
549  int has_pot_option, int has_ppc_option)
550 {
552  hm->has_trace_option = has_trace_option;
553  hm->has_pot_option = has_pot_option;
554  hm->has_ppc_option = has_ppc_option;
555  if (!hm->has_trace_option)
556  {
558  }
559 
560  return 0;
561 }
562 
563 void
565 {
567  hm->decap_v4_next_override = next;
568  return;
569 }
570 
571 static clib_error_t *
574  * input, vlib_cli_command_t * cmd)
575 {
576  int has_trace_option = 0;
577  int has_pot_option = 0;
578  int has_ppc_option = 0;
579  clib_error_t *rv = 0;
581  {
582  if (unformat (input, "trace"))
583  has_trace_option = 1;
584  else if (unformat (input, "pot"))
585  has_pot_option = 1;
586  else if (unformat (input, "ppc encap"))
587  has_ppc_option = PPC_ENCAP;
588  else if (unformat (input, "ppc decap"))
589  has_ppc_option = PPC_DECAP;
590  else if (unformat (input, "ppc none"))
591  has_ppc_option = PPC_NONE;
592  else
593  break;
594  }
595 
596 
597  rv =
598  vxlan_gpe_ioam_enable (has_trace_option, has_pot_option, has_ppc_option);
599  return rv;
600 }
601 
602 /* *INDENT-OFF* */
603 VLIB_CLI_COMMAND (vxlan_gpe_set_ioam_flags_cmd, static) =
604 {
605 .path = "set vxlan-gpe-ioam rewrite",
606 .short_help = "set vxlan-gpe-ioam [trace] [pot] [ppc <encap|decap>]",
608 /* *INDENT-ON* */
609 
610 
612  (vlib_main_t * vm, ip46_address_t dst_addr, u32 outer_fib_index,
613  u8 ipv4_set)
614 {
617 
619  dst_addr, outer_fib_index, ipv4_set,
620  0);
621  if (pool_elts (hm->dst_tunnels) == 0)
622  {
624  return 0;
625  }
626 
627  pool_foreach (t, hm->dst_tunnels, (
628  {
629  vxlan_gpe_enable_disable_ioam_for_dest
630  (hm->vlib_main,
631  t->dst_addr,
632  t->outer_fib_index,
633  (t->fp_proto ==
634  FIB_PROTOCOL_IP4), 1 /* is_add */ );
635  }
636  ));
638  return (0);
639 
640 }
641 
644 {
646  ip46_address_t dst_addr;
647  u8 dst_addr_set = 0;
648  u8 ipv4_set = 0;
649  u8 ipv6_set = 0;
650  u8 disable = 0;
651  clib_error_t *rv = 0;
652  u32 outer_fib_index = 0;
654  {
655  if (unformat (input, "dst-ip %U", unformat_ip4_address, &dst_addr.ip4))
656  {
657  dst_addr_set = 1;
658  ipv4_set = 1;
659  }
660  else
661  if (unformat
662  (input, "dst-ip %U", unformat_ip6_address, &dst_addr.ip6))
663  {
664  dst_addr_set = 1;
665  ipv6_set = 1;
666  }
667  else if (unformat (input, "outer-fib-index %d", &outer_fib_index))
668  {
669  }
670 
671  else if (unformat (input, "disable"))
672  disable = 1;
673  else
674  break;
675  }
676 
677  if (dst_addr_set == 0)
678  return clib_error_return (0, "tunnel destination address not specified");
679  if (ipv4_set && ipv6_set)
680  return clib_error_return (0, "both IPv4 and IPv6 addresses specified");
681  if (!disable)
682  {
684  dst_addr, outer_fib_index,
685  ipv4_set, 1);
686  }
687  else
688  {
690  (vm, dst_addr, outer_fib_index, ipv4_set);
691  }
692  return rv;
693 }
694 
695  /* *INDENT-OFF* */
696 VLIB_CLI_COMMAND (vxlan_gpe_set_ioam_transit_rewrite_cmd, static) = {
697  .path = "set vxlan-gpe-ioam-transit",
698  .short_help = "set vxlan-gpe-ioam-transit dst-ip <dst_ip> [outer-fib-index <outer_fib_index>] [disable]",
700 };
701 /* *INDENT-ON* */
702 
705 {
706  return (vxlan_gpe_ioam_disable (0, 0, 0));
707 }
708 
709 /* *INDENT-OFF* */
710 VLIB_CLI_COMMAND (vxlan_gpe_clear_ioam_flags_cmd, static) =
711 {
712 .path = "clear vxlan-gpe-ioam rewrite",
713 .short_help = "clear vxlan-gpe-ioam rewrite",
715 };
716 /* *INDENT-ON* */
717 
718 
719 /**
720  * Function definition to backwalk a FIB node
721  */
724 {
727 }
728 
729 /**
730  * Function definition to get a FIB node from its index
731  */
732 static fib_node_t *
734 {
736  return (&hm->node);
737 }
738 
739 /**
740  * Function definition to inform the FIB node that its last lock has gone.
741  */
742 static void
744 {
745  ASSERT (0);
746 }
747 
748 
749 /*
750  * Virtual function table registered by MPLS GRE tunnels
751  * for participation in the FIB object graph.
752  */
753 const static fib_node_vft_t vxlan_gpe_ioam_vft = {
755  .fnv_last_lock = vxlan_gpe_ioam_last_lock_gone,
756  .fnv_back_walk = vxlan_gpe_ioam_back_walk,
757 };
758 
759 void
761 {
763  hm->fib_entry_type = fib_node_register_new_type (&vxlan_gpe_ioam_vft);
764  return;
765 }
766 
767 /*
768  * fd.io coding-style-patch-verification: ON
769  *
770  * Local Variables:
771  * eval: (c-set-style "gnu")
772  * End:
773  */
u16 lb_n_buckets
number of buckets in the load-balance.
Definition: load_balance.h:87
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:154
static clib_error_t * vxlan_gpe_set_ioam_rewrite_command_fn(vlib_main_t *vm, unformat_input_t()*input, vlib_cli_command_t *cmd)
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:159
Recursive resolution source.
Definition: fib_entry.h:105
#define clib_error_return_code(e, code, flags, args...)
Definition: error.h:105
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
An entry in a FIB table.
Definition: fib_entry.h:361
void vxlan_gpe_set_next_override(uword next)
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
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:57
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:472
static int dpo_id_is_valid(const dpo_id_t *dpoi)
Return true if the DPO object is valid, i.e.
Definition: dpo.h:177
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#define NULL
Definition: clib.h:55
IP unicast adjacency.
Definition: lookup.h:188
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:233
#define hash_set_mem(h, key, value)
Definition: hash.h:274
fib_node_index_t fib_entry_index
ip_lookup_main_t lookup_main
Definition: ip4.h:97
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)
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:78
u8 protocol
see vxlan_gpe_protocol_t
clib_error_t * clear_vxlan_gpe_ioam_rewrite_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
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:145
#define hash_get_pair(h, key)
Definition: hash.h:251
u16 fp_len
The mask length.
Definition: fib_types.h:149
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:92
VXLAN GPE packet header structure.
Definition: fib_entry.h:216
static void vxlan_gpe_set_clear_output_feature_on_intf(vlib_main_t *vm, u32 sw_if_index0, u8 is_add)
unformat_function_t unformat_ip4_address
Definition: format.h:76
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:138
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:176
#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:369
#define hash_unset_mem(h, key)
Definition: hash.h:280
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, adj_index_t adj_index)
Add a &#39;special&#39; entry to the FIB that links to the adj passed A special entry is an entry that the FI...
Definition: fib_table.c:369
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:168
Struct for VXLAN GPE tunnel.
Definition: vxlan_gpe.h:90
dpo_type_t dpoi_type
the type
Definition: dpo.h:142
static const dpo_id_t * load_balance_get_bucket_i(const load_balance_t *lb, u32 bucket)
Definition: load_balance.h:194
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:214
vxlan_gpe_main_t vxlan_gpe_main
Definition: vxlan_gpe.c:24
The FIB DPO provieds;.
Definition: load_balance.h:83
static clib_error_t * vxlan_gpe_set_ioam_flags_command_fn(vlib_main_t *vm, unformat_input_t()*input, vlib_cli_command_t *cmd)
u8 protocol
encapsulated protocol
Definition: vxlan_gpe.h:95
int vxlan_gpe_trace_profile_setup(void)
An node in the FIB graph.
Definition: fib_node.h:273
unformat_function_t unformat_ip6_address
Definition: format.h:94
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:169
#define VXLAN_GPE_OPTION_TYPE_IOAM_TRACE
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)
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:300
fib_node_get_t fnv_get
Definition: fib_node.h:261
#define clib_memcpy(a, b, c)
Definition: string.h:69
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:44
Context passed between object during a back walk.
Definition: fib_node.h:186
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
fib_node_t node
Linkage into the FIB object graph.
int(* add_options[256])(u8 *rewrite_string, u8 *rewrite_size)
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
void vxlan_gpe_refresh_output_feature_on_all_dest(void)
u8 rewrite_size
rewrite size for dynamic plugins like iOAM
Definition: vxlan_gpe.h:119
Struct for VXLAN GPE node state.
Definition: vxlan_gpe.h:152
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:185
u64 size
Definition: vhost-user.h:74
static void clib_mem_free(void *p)
Definition: mem.h:176
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:109
fib_forward_chain_type_t fib_entry_get_default_chain_type(const fib_entry_t *fib_entry)
Definition: fib_entry.c:68
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:154
dpo_id_t fe_lb
The load-balance used for forwarding.
Definition: fib_entry.h:387
u64 uword
Definition: types.h:112
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:157
fib_node_type_t fib_entry_type
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:154
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
VXLAN GPE Extension (iOAM) Header definition.
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:606
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:268
void vxlan_gpe_clear_output_feature_on_select_intfs(void)
A FIB graph nodes virtual function table.
Definition: fib_node.h:260
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.
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
ip46_address_t dst_addr
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1099
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 clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
#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:445
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
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:161
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:238
static ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
Definition: lookup.h:415
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109