FD.io VPP  v19.04.2-12-g66b1689
Vector Packet Processing
fib_entry.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  */
15 
16 #include <vlib/vlib.h>
17 #include <vnet/ip/format.h>
18 #include <vnet/ip/lookup.h>
19 #include <vnet/adj/adj.h>
20 #include <vnet/dpo/load_balance.h>
21 #include <vnet/dpo/drop_dpo.h>
22 
23 #include <vnet/fib/fib_entry.h>
24 #include <vnet/fib/fib_walk.h>
25 #include <vnet/fib/fib_entry_src.h>
27 #include <vnet/fib/fib_table.h>
28 #include <vnet/fib/fib_internal.h>
30 #include <vnet/fib/fib_path_ext.h>
31 
32 /*
33  * Array of strings/names for the FIB sources
34  */
35 static const char *fib_source_names[] = FIB_SOURCES;
38 
39 /*
40  * Pool for all fib_entries
41  */
43 
44 /**
45  * the logger
46  */
48 
51 {
52  return (pool_elt_at_index(fib_entry_pool, index));
53 }
54 
55 static fib_node_t *
57 {
58  return ((fib_node_t*)fib_entry_get(index));
59 }
60 
62 fib_entry_get_index (const fib_entry_t * fib_entry)
63 {
64  return (fib_entry - fib_entry_pool);
65 }
66 
68 fib_entry_get_proto (const fib_entry_t * fib_entry)
69 {
70  return (fib_entry->fe_prefix.fp_proto);
71 }
72 
75 {
76  return (fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto));
77 }
78 
81 {
82  switch (fib_entry->fe_prefix.fp_proto)
83  {
84  case FIB_PROTOCOL_IP4:
86  case FIB_PROTOCOL_IP6:
88  case FIB_PROTOCOL_MPLS:
89  if (MPLS_EOS == fib_entry->fe_prefix.fp_eos)
91  else
93  }
94 
96 }
97 
98 u8 *
99 format_fib_source (u8 * s, va_list * args)
100 {
101  fib_source_t source = va_arg (*args, int);
102 
103  s = format (s, "src:%s", fib_source_names[source]);
104 
105  return (s);
106 }
107 
108 u8 *
109 format_fib_entry_flags (u8 *s, va_list *args)
110 {
112  fib_entry_flag_t flag = va_arg(*args, int);
113 
114  FOR_EACH_FIB_ATTRIBUTE(attr) {
115  if ((1<<attr) & flag) {
116  s = format (s, "%s,", fib_attribute_names[attr]);
117  }
118  }
119 
120  return (s);
121 }
122 
123 u8 *
124 format_fib_entry_src_flags (u8 *s, va_list *args)
125 {
127  fib_entry_src_flag_t flag = va_arg(*args, int);
128 
130  if ((1<<sattr) & flag) {
131  s = format (s, "%s,", fib_src_attribute_names[sattr]);
132  }
133  }
134 
135  return (s);
136 }
137 
138 u8 *
139 format_fib_entry (u8 * s, va_list * args)
140 {
142  fib_entry_t *fib_entry;
144  fib_node_index_t fei;
145  fib_source_t source;
146  int level;
147 
148  fei = va_arg (*args, fib_node_index_t);
149  level = va_arg (*args, int);
150  fib_entry = fib_entry_get(fei);
151 
152  s = format (s, "%U", format_fib_prefix, &fib_entry->fe_prefix);
153 
154  if (level >= FIB_ENTRY_FORMAT_DETAIL)
155  {
156  s = format (s, " fib:%d", fib_entry->fe_fib_index);
157  s = format (s, " index:%d", fib_entry_get_index(fib_entry));
158  s = format (s, " locks:%d", fib_entry->fe_node.fn_locks);
159 
160  FOR_EACH_SRC_ADDED(fib_entry, src, source,
161  ({
162  s = format (s, "\n %U", format_fib_source, source);
163  s = format (s, " refs:%d", src->fes_ref_count);
164  if (FIB_ENTRY_FLAG_NONE != src->fes_entry_flags) {
165  s = format(s, " entry-flags:%U",
167  }
168  if (FIB_ENTRY_SRC_FLAG_NONE != src->fes_flags) {
169  s = format(s, " src-flags:%U",
171  }
172  s = fib_entry_src_format(fib_entry, source, s);
173  s = format (s, "\n");
174  if (FIB_NODE_INDEX_INVALID != src->fes_pl)
175  {
176  s = fib_path_list_format(src->fes_pl, s);
177  }
178  s = format(s, "%U", format_fib_path_ext_list, &src->fes_path_exts);
179  }));
180 
181  s = format (s, "\n forwarding: ");
182  }
183  else
184  {
185  s = format (s, "\n");
186  }
187 
188  fct = fib_entry_get_default_chain_type(fib_entry);
189 
190  if (!dpo_id_is_valid(&fib_entry->fe_lb))
191  {
192  s = format (s, " UNRESOLVED\n");
193  return (s);
194  }
195  else
196  {
197  s = format(s, " %U-chain\n %U",
200  &fib_entry->fe_lb,
201  2);
202  s = format(s, "\n");
203 
204  if (level >= FIB_ENTRY_FORMAT_DETAIL2)
205  {
208 
209  s = format (s, " Delegates:\n");
210  FOR_EACH_DELEGATE(fib_entry, fdt, fed,
211  {
212  s = format(s, " %U\n", format_fib_entry_deletegate, fed);
213  });
214  }
215  }
216 
217  if (level >= FIB_ENTRY_FORMAT_DETAIL2)
218  {
219  s = format(s, " Children:");
220  s = fib_node_children_format(fib_entry->fe_node.fn_children, s);
221  }
222 
223  return (s);
224 }
225 
226 static fib_entry_t*
228 {
230  return ((fib_entry_t*)node);
231 }
232 
233 static void
235 {
238  fib_entry_t *fib_entry;
239 
240  fib_entry = fib_entry_from_fib_node(node);
241 
242  ASSERT(!dpo_id_is_valid(&fib_entry->fe_lb));
243 
244  FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
245  {
246  dpo_reset(&fed->fd_dpo);
247  fib_entry_delegate_remove(fib_entry, fdt);
248  });
249 
250  FIB_ENTRY_DBG(fib_entry, "last-lock");
251 
252  fib_node_deinit(&fib_entry->fe_node);
253 
254  ASSERT(0 == vec_len(fib_entry->fe_delegates));
255  vec_free(fib_entry->fe_delegates);
256  vec_free(fib_entry->fe_srcs);
257  pool_put(fib_entry_pool, fib_entry);
258 }
259 
260 static fib_entry_src_t*
262 {
263  fib_entry_src_t *bsrc;
264 
265  /*
266  * the enum of sources is deliberately arranged in priority order
267  */
268  if (0 == vec_len(fib_entry->fe_srcs))
269  {
270  bsrc = NULL;
271  }
272  else
273  {
274  bsrc = vec_elt_at_index(fib_entry->fe_srcs, 0);
275  }
276 
277  return (bsrc);
278 }
279 
280 static fib_source_t
282 {
283  if (NULL != esrc)
284  {
285  return (esrc->fes_src);
286  }
287  return (FIB_SOURCE_MAX);
288 }
289 
290 static fib_entry_flag_t
292 {
293  if (NULL != esrc)
294  {
295  return (esrc->fes_entry_flags);
296  }
297  return (FIB_ENTRY_FLAG_NONE);
298 }
299 
302 {
303  return (fib_entry_get_flags_i(fib_entry_get(fib_entry_index)));
304 }
305 
306 /*
307  * fib_entry_back_walk_notify
308  *
309  * A back walk has reach this entry.
310  */
314 {
315  fib_entry_t *fib_entry;
316 
317  fib_entry = fib_entry_from_fib_node(node);
318 
325  {
328  fib_entry_get_index(fib_entry)));
329  }
330 
331  /*
332  * all other walk types can be reclassifed to a re-evaluate to
333  * all recursive dependents.
334  * By reclassifying we ensure that should any of these walk types meet
335  * they can be merged.
336  */
338 
339  /*
340  * ... and nothing is forced sync from now on.
341  */
343 
344  FIB_ENTRY_DBG(fib_entry, "bw:%U",
346 
347  /*
348  * propagate the backwalk further if we haven't already reached the
349  * maximum depth.
350  */
352  fib_entry_get_index(fib_entry),
353  ctx);
354 
356 }
357 
358 static void
360 {
361  u32 n_srcs = 0, n_exts = 0;
362  fib_entry_src_t *esrc;
363  fib_entry_t *entry;
364 
365  fib_show_memory_usage("Entry",
366  pool_elts(fib_entry_pool),
367  pool_len(fib_entry_pool),
368  sizeof(fib_entry_t));
369 
370  pool_foreach(entry, fib_entry_pool,
371  ({
372  n_srcs += vec_len(entry->fe_srcs);
373  vec_foreach(esrc, entry->fe_srcs)
374  {
375  n_exts += fib_path_ext_list_length(&esrc->fes_path_exts);
376  }
377  }));
378 
379  fib_show_memory_usage("Entry Source",
380  n_srcs, n_srcs, sizeof(fib_entry_src_t));
381  fib_show_memory_usage("Entry Path-Extensions",
382  n_exts, n_exts,
383  sizeof(fib_path_ext_t));
384 }
385 
386 /*
387  * The FIB path-list's graph node virtual function table
388  */
389 static const fib_node_vft_t fib_entry_vft = {
391  .fnv_last_lock = fib_entry_last_lock_gone,
392  .fnv_back_walk = fib_entry_back_walk_notify,
393  .fnv_mem_show = fib_entry_show_memory,
394 };
395 
396 /**
397  * @brief Contribute the set of Adjacencies that this entry forwards with
398  * to build the uRPF list of its children
399  */
400 void
402  index_t urpf)
403 {
404  fib_entry_t *fib_entry;
405 
406  fib_entry = fib_entry_get(entry_index);
407 
408  return (fib_path_list_contribute_urpf(fib_entry->fe_parent, urpf));
409 }
410 
411 /*
412  * If the client is request a chain for multicast forwarding then swap
413  * the chain type to one that can provide such transport.
414  */
417 {
418  switch (fct)
419  {
422  /*
423  * we can only transport IP multicast packets if there is an
424  * LSP.
425  */
427  break;
435  break;
436  }
437 
438  return (fct);
439 }
440 
441 /*
442  * fib_entry_contribute_forwarding
443  *
444  * Get an lock the forwarding information (DPO) contributed by the FIB entry.
445  */
446 void
449  dpo_id_t *dpo)
450 {
452  fib_entry_t *fib_entry;
453 
454  fib_entry = fib_entry_get(fib_entry_index);
455 
456  /*
457  * mfib children ask for mcast chains. fix these to the appropriate ucast types.
458  */
460 
461  if (fct == fib_entry_get_default_chain_type(fib_entry))
462  {
463  dpo_copy(dpo, &fib_entry->fe_lb);
464  }
465  else
466  {
467  fed = fib_entry_delegate_get(fib_entry,
469 
470  if (NULL == fed)
471  {
472  /*
473  * use a temporary DPO lest the delegate realloc in the recursive
474  * calculation.
475  */
476  dpo_id_t tmp = DPO_INVALID;
477 
478  /*
479  * on-demand create eos/non-eos.
480  * There is no on-demand delete because:
481  * - memory versus complexity & reliability:
482  * leaving unrequired [n]eos LB arounds wastes memory, cleaning
483  * then up on the right trigger is more code. i favour the latter.
484  */
485  fib_entry_src_mk_lb(fib_entry,
486  fib_entry_get_best_src_i(fib_entry),
487  fct,
488  &tmp);
489 
491  fib_entry,
493 
494  dpo_copy(&fed->fd_dpo, &tmp);
495  dpo_reset(&tmp);
496  }
497 
498  dpo_copy(dpo, &fed->fd_dpo);
499  }
500  /*
501  * use the drop DPO is nothing else is present
502  */
503  if (!dpo_id_is_valid(dpo))
504  {
506  }
507 
508  /*
509  * don't allow the special index indicating replicate.vs.load-balance
510  * to escape to the clients
511  */
512  dpo->dpoi_index &= ~MPLS_IS_REPLICATE;
513 }
514 
515 const dpo_id_t *
517 {
519  fib_entry_t *fib_entry;
520 
521  fib_entry = fib_entry_get(fib_entry_index);
522  fct = fib_entry_get_default_chain_type(fib_entry);
523 
526 
527  if (dpo_id_is_valid(&fib_entry->fe_lb))
528  {
529  return (&fib_entry->fe_lb);
530  }
531 
533 }
534 
537 {
538  const dpo_id_t *dpo;
539 
540  dpo = fib_entry_contribute_ip_forwarding(fib_entry_index);
541 
542  if (dpo_id_is_valid(dpo))
543  {
544  dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
545 
546  if (dpo_is_adj(dpo))
547  {
548  return (dpo->dpoi_index);
549  }
550  }
551  return (ADJ_INDEX_INVALID);
552 }
553 
556 {
557  fib_entry_t *fib_entry;
558 
559  fib_entry = fib_entry_get(fib_entry_index);
560 
561  return (fib_entry->fe_parent);
562 }
563 
564 u32
566  fib_node_type_t child_type,
567  fib_node_index_t child_index)
568 {
570  fib_entry_index,
571  child_type,
572  child_index));
573 };
574 
575 void
577  u32 sibling_index)
578 {
580  fib_entry_index,
581  sibling_index);
582 
584  fib_entry_index))
585  {
586  /*
587  * if there are no children left then there is no reason to keep
588  * the non-default forwarding chains. those chains are built only
589  * because the children want them.
590  */
593  fib_entry_t *fib_entry;
594 
595  fib_entry = fib_entry_get(fib_entry_index);
596 
597  FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
598  {
599  dpo_reset(&fed->fd_dpo);
600  fib_entry_delegate_remove(fib_entry, fdt);
601  });
602  }
603 }
604 
605 static fib_entry_t *
606 fib_entry_alloc (u32 fib_index,
607  const fib_prefix_t *prefix,
608  fib_node_index_t *fib_entry_index)
609 {
610  fib_entry_t *fib_entry;
611  fib_prefix_t *fep;
612 
613  pool_get(fib_entry_pool, fib_entry);
614  clib_memset(fib_entry, 0, sizeof(*fib_entry));
615 
616  fib_node_init(&fib_entry->fe_node,
618 
619  fib_entry->fe_fib_index = fib_index;
620 
621  /*
622  * the one time we need to update the const prefix is when
623  * the entry is first created
624  */
625  fep = (fib_prefix_t*)&(fib_entry->fe_prefix);
626  *fep = *prefix;
627 
628  if (FIB_PROTOCOL_MPLS == fib_entry->fe_prefix.fp_proto)
629  {
630  fep->fp_len = 21;
631  if (MPLS_NON_EOS == fep->fp_eos)
632  {
634  }
636  }
637 
638  dpo_reset(&fib_entry->fe_lb);
639 
640  *fib_entry_index = fib_entry_get_index(fib_entry);
641 
642  return (fib_entry);
643 }
644 
645 static fib_entry_t*
647  fib_entry_flag_t old_flags)
648 {
649  fib_node_index_t fei;
650 
651  /*
652  * save the index so we can recover from pool reallocs
653  */
654  fei = fib_entry_get_index(fib_entry);
655 
656  /*
657  * handle changes to attached export for import entries
658  */
659  int is_import = (FIB_ENTRY_FLAG_IMPORT & fib_entry_get_flags_i(fib_entry));
660  int was_import = (FIB_ENTRY_FLAG_IMPORT & old_flags);
661 
662  if (!was_import && is_import)
663  {
664  /*
665  * transition from not exported to exported
666  */
667 
668  /*
669  * there is an assumption here that the entry resolves via only
670  * one interface and that it is the cross VRF interface.
671  */
673 
674  fib_attached_export_import(fib_entry,
676  fib_entry_get_proto(fib_entry),
677  sw_if_index));
678  }
679  else if (was_import && !is_import)
680  {
681  /*
682  * transition from exported to not exported
683  */
684  fib_attached_export_purge(fib_entry);
685  }
686  /*
687  * else
688  * no change. nothing to do.
689  */
690 
691  /*
692  * reload the entry address post possible pool realloc
693  */
694  fib_entry = fib_entry_get(fei);
695 
696  /*
697  * handle changes to attached export for export entries
698  */
699  int is_attached = (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(fib_entry));
700  int was_attached = (FIB_ENTRY_FLAG_ATTACHED & old_flags);
701 
702  if (!was_attached && is_attached)
703  {
704  /*
705  * transition to attached. time to export
706  */
707  // FIXME
708  }
709  // else FIXME
710 
711  return (fib_entry);
712 }
713 
714 static void
716  fib_source_t source,
717  fib_entry_flag_t old_flags)
718 {
719  fib_entry = fib_entry_post_flag_update_actions(fib_entry,
720  old_flags);
721  fib_entry_src_action_installed(fib_entry, source);
722 }
723 
726  const fib_prefix_t *prefix,
727  fib_source_t source,
729  const fib_route_path_t *paths)
730 {
731  fib_node_index_t fib_entry_index;
732  fib_entry_t *fib_entry;
733 
734  ASSERT(0 < vec_len(paths));
735 
736  fib_entry = fib_entry_alloc(fib_index, prefix, &fib_entry_index);
737 
738  /*
739  * since this is a new entry create, we don't need to check for winning
740  * sources - there is only one.
741  */
742  fib_entry = fib_entry_src_action_add(fib_entry, source, flags,
743  drop_dpo_get(
745  fib_entry_get_proto(fib_entry))));
747  source,
748  flags,
749  paths);
750  /*
751  * handle possible realloc's by refetching the pointer
752  */
753  fib_entry = fib_entry_get(fib_entry_index);
754  fib_entry_src_action_activate(fib_entry, source);
755 
757 
758  FIB_ENTRY_DBG(fib_entry, "create");
759 
760  return (fib_entry_index);
761 }
762 
765  const fib_prefix_t *prefix,
766  fib_source_t source,
768  const dpo_id_t *dpo)
769 {
770  fib_node_index_t fib_entry_index;
771  fib_entry_t *fib_entry;
772 
773  /*
774  * create and initialize the new enty
775  */
776  fib_entry = fib_entry_alloc(fib_index, prefix, &fib_entry_index);
777 
778  /*
779  * create the path-list
780  */
781  fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
782  fib_entry_src_action_activate(fib_entry, source);
783 
785 
786  FIB_ENTRY_DBG(fib_entry, "create-special");
787 
788  return (fib_entry_index);
789 }
790 
791 static void
793  fib_source_t source,
794  fib_entry_flag_t old_flags)
795 {
796  /*
797  * backwalk to children to inform then of the change to forwarding.
798  */
799  fib_node_back_walk_ctx_t bw_ctx = {
801  };
802 
804 
805  /*
806  * then inform any covered prefixes
807  */
809 
810  fib_entry_post_install_actions(fib_entry, source, old_flags);
811 }
812 
813 void
815 {
816  fib_source_t best_source;
817  fib_entry_t *fib_entry;
818  fib_entry_src_t *bsrc;
819 
820  fib_entry = fib_entry_get(fib_entry_index);
821 
822  bsrc = fib_entry_get_best_src_i(fib_entry);
823  best_source = fib_entry_src_get_source(bsrc);
824 
825  fib_entry_src_action_reactivate(fib_entry, best_source);
826 }
827 
828 static void
830  fib_source_t old_source,
831  fib_entry_flag_t old_flags,
832  fib_source_t new_source)
833 {
834  if (new_source < old_source)
835  {
836  /*
837  * we have a new winning source.
838  */
839  fib_entry_src_action_deactivate(fib_entry, old_source);
840  fib_entry_src_action_activate(fib_entry, new_source);
841  }
842  else if (new_source > old_source)
843  {
844  /*
845  * the new source loses. Re-activate the winning sources
846  * in case it is an interposer and hence relied on the losing
847  * source's path-list.
848  */
849  fib_entry_src_action_reactivate(fib_entry, old_source);
850  return;
851  }
852  else
853  {
854  /*
855  * the new source is one this entry already has.
856  * But the path-list was updated, which will contribute new forwarding,
857  * so install it.
858  */
859  fib_entry_src_action_reactivate(fib_entry, new_source);
860  }
861 
862  fib_entry_post_update_actions(fib_entry, new_source, old_flags);
863 }
864 
865 void
867  fib_source_t old_source,
868  fib_source_t new_source)
869 {
870  fib_entry_flag_t old_flags;
871 
872  old_flags = fib_entry_get_flags_for_source(
873  fib_entry_get_index(fib_entry), old_source);
874 
875  return (fib_entry_source_change_w_flags(fib_entry, old_source,
876  old_flags, new_source));
877 }
878 
879 void
881  fib_source_t source,
883  const dpo_id_t *dpo)
884 {
885  fib_source_t best_source;
886  fib_entry_t *fib_entry;
887 
888  fib_entry = fib_entry_get(fib_entry_index);
889  best_source = fib_entry_get_best_source(fib_entry_index);
890 
891  fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
892  fib_entry_source_change(fib_entry, best_source, source);
893  FIB_ENTRY_DBG(fib_entry, "special-add:%U", format_fib_source, source);
894 }
895 
896 void
898  fib_source_t source,
900  const dpo_id_t *dpo)
901 {
902  fib_source_t best_source;
903  fib_entry_t *fib_entry;
904 
905  fib_entry = fib_entry_get(fib_entry_index);
906  best_source = fib_entry_get_best_source(fib_entry_index);
907 
908  fib_entry = fib_entry_src_action_update(fib_entry, source, flags, dpo);
909  fib_entry_source_change(fib_entry, best_source, source);
910 
911  FIB_ENTRY_DBG(fib_entry, "special-updated:%U", format_fib_source, source);
912 }
913 
914 
915 void
917  fib_source_t source,
919  const fib_route_path_t *rpath)
920 {
921  fib_source_t best_source;
922  fib_entry_t *fib_entry;
923  fib_entry_src_t *bsrc;
924 
925  ASSERT(1 == vec_len(rpath));
926 
927  fib_entry = fib_entry_get(fib_entry_index);
928  ASSERT(NULL != fib_entry);
929 
930  bsrc = fib_entry_get_best_src_i(fib_entry);
931  best_source = fib_entry_src_get_source(bsrc);
932 
933  fib_entry = fib_entry_src_action_path_add(fib_entry, source, flags, rpath);
934 
935  fib_entry_source_change(fib_entry, best_source, source);
936 
937  FIB_ENTRY_DBG(fib_entry, "path add:%U", format_fib_source, source);
938 }
939 
942 {
944  fib_source_t source;
945  int has_only_inherited_sources = 1;
946 
947  FOR_EACH_SRC_ADDED(fib_entry, src, source,
948  ({
950  {
951  has_only_inherited_sources = 0;
952  break;
953  }
954  }));
955  if (has_only_inherited_sources)
956  {
957  FOR_EACH_SRC_ADDED(fib_entry, src, source,
958  ({
959  fib_entry_src_action_remove(fib_entry, source);
960  }));
961  return (FIB_ENTRY_SRC_FLAG_NONE);
962  }
963  else
964  {
965  return (FIB_ENTRY_SRC_FLAG_ADDED);
966  }
967 }
968 
971  fib_entry_flag_t old_flags)
972 {
973  const fib_entry_src_t *bsrc;
974  fib_source_t best_source;
975 
976  /*
977  * if all that is left are inherited sources, then burn them
978  */
980 
981  bsrc = fib_entry_get_best_src_i(fib_entry);
982  best_source = fib_entry_src_get_source(bsrc);
983 
984  if (FIB_SOURCE_MAX == best_source)
985  {
986  /*
987  * no more sources left. this entry is toast.
988  */
989  fib_entry = fib_entry_post_flag_update_actions(fib_entry, old_flags);
991 
992  return (FIB_ENTRY_SRC_FLAG_NONE);
993  }
994  else
995  {
996  fib_entry_src_action_activate(fib_entry, best_source);
997  }
998 
999  fib_entry_post_update_actions(fib_entry, best_source, old_flags);
1000 
1001  /*
1002  * still have sources
1003  */
1004  return (FIB_ENTRY_SRC_FLAG_ADDED);
1005 }
1006 
1007 /*
1008  * fib_entry_path_remove
1009  *
1010  * remove a path from the entry.
1011  * return the fib_entry's index if it is still present, INVALID otherwise.
1012  */
1015  fib_source_t source,
1016  const fib_route_path_t *rpath)
1017 {
1018  fib_entry_src_flag_t sflag;
1019  fib_source_t best_source;
1020  fib_entry_flag_t bflags;
1021  fib_entry_t *fib_entry;
1022  fib_entry_src_t *bsrc;
1023 
1024  ASSERT(1 == vec_len(rpath));
1025 
1026  fib_entry = fib_entry_get(fib_entry_index);
1027  ASSERT(NULL != fib_entry);
1028 
1029  bsrc = fib_entry_get_best_src_i(fib_entry);
1030  best_source = fib_entry_src_get_source(bsrc);
1031  bflags = fib_entry_src_get_flags(bsrc);
1032 
1033  sflag = fib_entry_src_action_path_remove(fib_entry, source, rpath);
1034 
1035  FIB_ENTRY_DBG(fib_entry, "path remove:%U", format_fib_source, source);
1036 
1037  /*
1038  * if the path list for the source passed is invalid,
1039  * then we need to create a new one. else we are updating
1040  * an existing.
1041  */
1042  if (source < best_source)
1043  {
1044  /*
1045  * Que! removing a path from a source that is better than the
1046  * one this entry is using.
1047  */
1048  ASSERT(0);
1049  }
1050  else if (source > best_source )
1051  {
1052  /*
1053  * the source is not the best. no need to update forwarding
1054  */
1055  if (FIB_ENTRY_SRC_FLAG_ADDED & sflag)
1056  {
1057  /*
1058  * the source being removed still has paths
1059  */
1060  return (FIB_ENTRY_SRC_FLAG_ADDED);
1061  }
1062  else
1063  {
1064  /*
1065  * that was the last path from this source, check if those
1066  * that remain are non-inherited
1067  */
1068  return (fib_entry_src_burn_only_inherited(fib_entry));
1069  }
1070  }
1071  else
1072  {
1073  /*
1074  * removing a path from the path-list we were using.
1075  */
1076  if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag))
1077  {
1078  /*
1079  * the last path from the source was removed.
1080  * fallback to lower source
1081  */
1082  return (fib_entry_source_removed(fib_entry, bflags));
1083  }
1084  else
1085  {
1086  /*
1087  * re-install the new forwarding information
1088  */
1089  fib_entry_src_action_reactivate(fib_entry, source);
1090  }
1091  }
1092 
1093  fib_entry_post_update_actions(fib_entry, source, bflags);
1094 
1095  /*
1096  * still have sources
1097  */
1098  return (FIB_ENTRY_SRC_FLAG_ADDED);
1099 }
1100 
1101 /*
1102  * fib_entry_special_remove
1103  *
1104  * remove a special source from the entry.
1105  * return the fib_entry's index if it is still present, INVALID otherwise.
1106  */
1109  fib_source_t source)
1110 {
1111  fib_entry_src_flag_t sflag;
1112  fib_source_t best_source;
1113  fib_entry_flag_t bflags;
1114  fib_entry_t *fib_entry;
1115  fib_entry_src_t *bsrc;
1116 
1117  fib_entry = fib_entry_get(fib_entry_index);
1118  ASSERT(NULL != fib_entry);
1119 
1120  bsrc = fib_entry_get_best_src_i(fib_entry);
1121  best_source = fib_entry_src_get_source(bsrc);
1122  bflags = fib_entry_src_get_flags(bsrc);
1123 
1124  FIB_ENTRY_DBG(fib_entry, "special remove:%U", format_fib_source, source);
1125 
1126  sflag = fib_entry_src_action_remove_or_update_inherit(fib_entry, source);
1127 
1128  /*
1129  * if the path list for the source passed is invalid,
1130  * then we need to create a new one. else we are updating
1131  * an existing.
1132  */
1133  if (source < best_source )
1134  {
1135  /*
1136  * Que! removing a path from a source that is better than the
1137  * one this entry is using. This can only mean it is a source
1138  * this prefix does not have.
1139  */
1140  return (FIB_ENTRY_SRC_FLAG_ADDED);
1141  }
1142  else if (source > best_source ) {
1143  /*
1144  * the source is not the best. no need to update forwarding
1145  */
1146  if (FIB_ENTRY_SRC_FLAG_ADDED & sflag)
1147  {
1148  /*
1149  * the source being removed still has paths
1150  */
1151  return (FIB_ENTRY_SRC_FLAG_ADDED);
1152  }
1153  else
1154  {
1155  /*
1156  * that was the last path from this source, check if those
1157  * that remain are non-inherited
1158  */
1160  {
1161  /*
1162  * no more sources left. this entry is toast.
1163  */
1164  fib_entry = fib_entry_post_flag_update_actions(fib_entry, bflags);
1165  fib_entry_src_action_uninstall(fib_entry);
1166  return (FIB_ENTRY_SRC_FLAG_NONE);
1167  }
1168 
1169  /*
1170  * reactivate the best source so the interposer gets restacked
1171  */
1172  fib_entry_src_action_reactivate(fib_entry, best_source);
1173 
1174  return (FIB_ENTRY_SRC_FLAG_ADDED);
1175  }
1176  }
1177  else
1178  {
1179  if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag))
1180  {
1181  /*
1182  * the source was removed. use the next best.
1183  */
1184  return (fib_entry_source_removed(fib_entry, bflags));
1185  }
1186  else
1187  {
1188  /*
1189  * re-install the new forwarding information
1190  */
1191  fib_entry_src_action_reactivate(fib_entry, source);
1192  }
1193  }
1194 
1195  fib_entry_post_update_actions(fib_entry, source, bflags);
1196 
1197  /*
1198  * still have sources
1199  */
1200  return (FIB_ENTRY_SRC_FLAG_ADDED);
1201 }
1202 
1203 /**
1204  * fib_entry_inherit
1205  *
1206  * If the source on the cover is inheriting then push this source
1207  * down to the covered.
1208  */
1209 void
1211  fib_node_index_t covered)
1212 {
1214  fib_entry_get(covered));
1215 }
1216 
1217 /**
1218  * fib_entry_delete
1219  *
1220  * The source is withdrawing all the paths it provided
1221  */
1224  fib_source_t source)
1225 {
1226  return (fib_entry_special_remove(fib_entry_index, source));
1227 }
1228 
1229 /**
1230  * fib_entry_update
1231  *
1232  * The source has provided a new set of paths that will replace the old.
1233  */
1234 void
1236  fib_source_t source,
1238  const fib_route_path_t *paths)
1239 {
1240  fib_source_t best_source;
1241  fib_entry_flag_t bflags;
1242  fib_entry_t *fib_entry;
1243  fib_entry_src_t *bsrc;
1244 
1245  fib_entry = fib_entry_get(fib_entry_index);
1246  ASSERT(NULL != fib_entry);
1247 
1248  bsrc = fib_entry_get_best_src_i(fib_entry);
1249  best_source = fib_entry_src_get_source(bsrc);
1250  bflags = fib_entry_get_flags_i(fib_entry);
1251 
1252  fib_entry = fib_entry_src_action_path_swap(fib_entry,
1253  source,
1254  flags,
1255  paths);
1256 
1257  fib_entry_source_change_w_flags(fib_entry, best_source, bflags, source);
1258  FIB_ENTRY_DBG(fib_entry, "update");
1259 }
1260 
1261 
1262 /*
1263  * fib_entry_cover_changed
1264  *
1265  * this entry is tracking its cover and that cover has changed.
1266  */
1267 void
1269 {
1271  .install = !0,
1272  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
1273  };
1274  CLIB_UNUSED(fib_source_t source);
1275  fib_source_t best_source;
1276  fib_entry_flag_t bflags;
1277  fib_entry_t *fib_entry;
1278  fib_entry_src_t *esrc;
1279  u32 index;
1280 
1281  bflags = FIB_ENTRY_FLAG_NONE;
1282  best_source = FIB_SOURCE_FIRST;
1283  fib_entry = fib_entry_get(fib_entry_index);
1284 
1286 
1287  /*
1288  * propagate the notification to each of the added sources
1289  */
1290  index = 0;
1291  FOR_EACH_SRC_ADDED(fib_entry, esrc, source,
1292  ({
1293  if (0 == index)
1294  {
1295  /*
1296  * only the best source gets to set the back walk flags
1297  */
1298  res = fib_entry_src_action_cover_change(fib_entry, esrc);
1299  bflags = fib_entry_src_get_flags(esrc);
1300  best_source = fib_entry_src_get_source(esrc);
1301  }
1302  else
1303  {
1304  fib_entry_src_action_cover_change(fib_entry, esrc);
1305  }
1306  index++;
1307  }));
1308 
1309  if (res.install)
1310  {
1313  fib_entry_get_best_src_i(fib_entry)));
1314  fib_entry_post_install_actions(fib_entry, best_source, bflags);
1315  }
1316  else
1317  {
1318  fib_entry_src_action_uninstall(fib_entry);
1319  }
1320 
1322  {
1323  /*
1324  * time for walkies fido.
1325  */
1326  fib_node_back_walk_ctx_t bw_ctx = {
1327  .fnbw_reason = res.bw_reason,
1328  };
1329 
1330  fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx);
1331  }
1332  FIB_ENTRY_DBG(fib_entry, "cover-changed");
1333 }
1334 
1335 /*
1336  * fib_entry_cover_updated
1337  *
1338  * this entry is tracking its cover and that cover has been updated
1339  * (i.e. its forwarding information has changed).
1340  */
1341 void
1343 {
1345  .install = !0,
1346  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
1347  };
1348  CLIB_UNUSED(fib_source_t source);
1349  fib_source_t best_source;
1350  fib_entry_flag_t bflags;
1351  fib_entry_t *fib_entry;
1352  fib_entry_src_t *esrc;
1353  u32 index;
1354 
1355  bflags = FIB_ENTRY_FLAG_NONE;
1356  best_source = FIB_SOURCE_FIRST;
1357  fib_entry = fib_entry_get(fib_entry_index);
1358 
1360 
1361  /*
1362  * propagate the notification to each of the added sources
1363  */
1364  index = 0;
1365  FOR_EACH_SRC_ADDED(fib_entry, esrc, source,
1366  ({
1367  if (0 == index)
1368  {
1369  /*
1370  * only the best source gets to set the back walk flags
1371  */
1372  res = fib_entry_src_action_cover_update(fib_entry, esrc);
1373  bflags = fib_entry_src_get_flags(esrc);
1374  best_source = fib_entry_src_get_source(esrc);
1375  }
1376  else
1377  {
1378  fib_entry_src_action_cover_update(fib_entry, esrc);
1379  }
1380  index++;
1381  }));
1382 
1383  if (res.install)
1384  {
1387  fib_entry_get_best_src_i(fib_entry)));
1388  fib_entry_post_install_actions(fib_entry, best_source, bflags);
1389  }
1390  else
1391  {
1392  fib_entry_src_action_uninstall(fib_entry);
1393  }
1394 
1396  {
1397  /*
1398  * time for walkies fido.
1399  */
1400  fib_node_back_walk_ctx_t bw_ctx = {
1401  .fnbw_reason = res.bw_reason,
1402  };
1403 
1404  fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx);
1405  }
1406  FIB_ENTRY_DBG(fib_entry, "cover-updated");
1407 }
1408 
1409 int
1411  fib_node_index_t **entry_indicies)
1412 {
1413  fib_entry_t *fib_entry;
1414  int was_looped, is_looped;
1415 
1416  fib_entry = fib_entry_get(entry_index);
1417 
1418  if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent)
1419  {
1420  fib_node_index_t *entries = *entry_indicies;
1421 
1422  vec_add1(entries, entry_index);
1423  was_looped = fib_path_list_is_looped(fib_entry->fe_parent);
1424  is_looped = fib_path_list_recursive_loop_detect(fib_entry->fe_parent,
1425  &entries);
1426 
1427  *entry_indicies = entries;
1428 
1429  if (!!was_looped != !!is_looped)
1430  {
1431  /*
1432  * re-evaluate all the entry's forwarding
1433  * NOTE: this is an inplace modify
1434  */
1436  fib_entry_delegate_t *fed;
1437 
1438  FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
1439  {
1440  fib_entry_src_mk_lb(fib_entry,
1441  fib_entry_get_best_src_i(fib_entry),
1443  &fed->fd_dpo);
1444  });
1445  }
1446  }
1447  else
1448  {
1449  /*
1450  * the entry is currently not linked to a path-list. this happens
1451  * when it is this entry that is re-linking path-lists and has thus
1452  * broken the loop
1453  */
1454  is_looped = 0;
1455  }
1456 
1457  return (is_looped);
1458 }
1459 
1460 u32
1462 {
1463  fib_entry_t *fib_entry;
1464 
1465  fib_entry = fib_entry_get(entry_index);
1466 
1467  return (fib_path_list_get_resolving_interface(fib_entry->fe_parent));
1468 }
1469 
1472 {
1473  fib_entry_t *fib_entry;
1474  fib_entry_src_t *bsrc;
1475 
1476  fib_entry = fib_entry_get(entry_index);
1477 
1478  bsrc = fib_entry_get_best_src_i(fib_entry);
1479  return (fib_entry_src_get_source(bsrc));
1480 }
1481 
1482 /**
1483  * Return !0 is the entry represents a host prefix
1484  */
1485 int
1487 {
1488  return (fib_prefix_is_host(fib_entry_get_prefix(fib_entry_index)));
1489 }
1490 
1491 /**
1492  * Return !0 is the entry is resolved, i.e. will return a valid forwarding
1493  * chain
1494  */
1495 int
1497 {
1498  fib_entry_delegate_t *fed;
1499  fib_entry_t *fib_entry;
1500 
1501  fib_entry = fib_entry_get(fib_entry_index);
1502 
1504 
1505  if (NULL == fed)
1506  {
1507  /*
1508  * no BFD tracking - consider it resolved.
1509  */
1510  return (!0);
1511  }
1512  else
1513  {
1514  /*
1515  * defer to the state of the BFD tracking
1516  */
1517  return (FIB_BFD_STATE_UP == fed->fd_bfd_state);
1518  }
1519 }
1520 
1521 void
1523  flow_hash_config_t hash_config)
1524 {
1525  fib_entry_t *fib_entry;
1526 
1527  fib_entry = fib_entry_get(fib_entry_index);
1528 
1529  /*
1530  * pass the hash-config on to the load-balance object where it is cached.
1531  * we can ignore LBs in the delegate chains, since they will not be of the
1532  * correct protocol type (i.e. they are not IP)
1533  * There's no way, nor need, to change the hash config for MPLS.
1534  */
1535  if (dpo_id_is_valid(&fib_entry->fe_lb))
1536  {
1537  load_balance_t *lb;
1538 
1539  ASSERT(DPO_LOAD_BALANCE == fib_entry->fe_lb.dpoi_type);
1540 
1541  lb = load_balance_get(fib_entry->fe_lb.dpoi_index);
1542 
1543  /*
1544  * atomic update for packets in flight
1545  */
1546  lb->lb_hash_config = hash_config;
1547  }
1548 }
1549 
1550 u32
1552 {
1553  fib_entry_t *fib_entry;
1554 
1555  fib_entry = fib_entry_get(fib_entry_index);
1556 
1557  return (fib_entry->fe_lb.dpoi_index);
1558 }
1559 
1560 static int
1562  const ip4_address_t * a2)
1563 {
1564  /*
1565  * IP addresses are unsigned ints. the return value here needs to be signed
1566  * a simple subtraction won't cut it.
1567  * If the addresses are the same, the sort order is undefined, so phoey.
1568  */
1569  return ((clib_net_to_host_u32(a1->data_u32) >
1570  clib_net_to_host_u32(a2->data_u32) ) ?
1571  1 : -1);
1572 }
1573 
1574 static int
1576  const ip6_address_t * a2)
1577 {
1578  int i;
1579  for (i = 0; i < ARRAY_LEN (a1->as_u16); i++)
1580  {
1581  int cmp = (clib_net_to_host_u16 (a1->as_u16[i]) -
1582  clib_net_to_host_u16 (a2->as_u16[i]));
1583  if (cmp != 0)
1584  return cmp;
1585  }
1586  return 0;
1587 }
1588 
1589 static int
1591  fib_node_index_t fib_entry_index2)
1592 {
1593  fib_entry_t *fib_entry1, *fib_entry2;
1594  int cmp = 0;
1595 
1596  fib_entry1 = fib_entry_get(fib_entry_index1);
1597  fib_entry2 = fib_entry_get(fib_entry_index2);
1598 
1599  switch (fib_entry1->fe_prefix.fp_proto)
1600  {
1601  case FIB_PROTOCOL_IP4:
1602  cmp = fib_ip4_address_compare(&fib_entry1->fe_prefix.fp_addr.ip4,
1603  &fib_entry2->fe_prefix.fp_addr.ip4);
1604  break;
1605  case FIB_PROTOCOL_IP6:
1606  cmp = fib_ip6_address_compare(&fib_entry1->fe_prefix.fp_addr.ip6,
1607  &fib_entry2->fe_prefix.fp_addr.ip6);
1608  break;
1609  case FIB_PROTOCOL_MPLS:
1610  cmp = (fib_entry1->fe_prefix.fp_label - fib_entry2->fe_prefix.fp_label);
1611 
1612  if (0 == cmp)
1613  {
1614  cmp = (fib_entry1->fe_prefix.fp_eos - fib_entry2->fe_prefix.fp_eos);
1615  }
1616  break;
1617  }
1618 
1619  if (0 == cmp) {
1620  cmp = (fib_entry1->fe_prefix.fp_len - fib_entry2->fe_prefix.fp_len);
1621  }
1622  return (cmp);
1623 }
1624 
1625 int
1626 fib_entry_cmp_for_sort (void *i1, void *i2)
1627 {
1628  fib_node_index_t *fib_entry_index1 = i1, *fib_entry_index2 = i2;
1629 
1630  return (fib_entry_cmp(*fib_entry_index1,
1631  *fib_entry_index2));
1632 }
1633 
1634 void
1636 {
1637  fib_entry_t *fib_entry;
1638 
1639  fib_entry = fib_entry_get(fib_entry_index);
1640 
1641  fib_node_lock(&fib_entry->fe_node);
1642 }
1643 
1644 void
1646 {
1647  fib_entry_t *fib_entry;
1648 
1649  fib_entry = fib_entry_get(fib_entry_index);
1650 
1651  fib_node_unlock(&fib_entry->fe_node);
1652 }
1653 
1654 void
1656 {
1658  fib_entry_logger = vlib_log_register_class("fib", "entry");
1659 }
1660 
1661 void
1663  fib_route_path_encode_t **api_rpaths)
1664 {
1665  fib_path_ext_list_t *ext_list;
1666  fib_entry_t *fib_entry;
1667  fib_entry_src_t *bsrc;
1668 
1669  ext_list = NULL;
1670  fib_entry = fib_entry_get(fib_entry_index);
1671  bsrc = fib_entry_get_best_src_i(fib_entry);
1672 
1673  if (bsrc)
1674  {
1675  ext_list = &bsrc->fes_path_exts;
1676  }
1677 
1678  if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent)
1679  {
1681  ext_list,
1683  api_rpaths);
1684  }
1685 }
1686 
1687 const fib_prefix_t *
1689 {
1690  fib_entry_t *fib_entry;
1691 
1692  fib_entry = fib_entry_get(fib_entry_index);
1693 
1694  return (&fib_entry->fe_prefix);
1695 }
1696 
1697 u32
1699 {
1700  fib_entry_t *fib_entry;
1701 
1702  fib_entry = fib_entry_get(fib_entry_index);
1703 
1704  return (fib_entry->fe_fib_index);
1705 }
1706 
1707 u32
1709 {
1710  return (pool_elts(fib_entry_pool));
1711 }
1712 
1713 static clib_error_t *
1715  unformat_input_t * input,
1716  vlib_cli_command_t * cmd)
1717 {
1718  fib_node_index_t fei;
1719 
1720  if (unformat (input, "%d", &fei))
1721  {
1722  /*
1723  * show one in detail
1724  */
1725  if (!pool_is_free_index(fib_entry_pool, fei))
1726  {
1727  vlib_cli_output (vm, "%d@%U",
1728  fei,
1729  format_fib_entry, fei,
1731  }
1732  else
1733  {
1734  vlib_cli_output (vm, "entry %d invalid", fei);
1735  }
1736  }
1737  else
1738  {
1739  /*
1740  * show all
1741  */
1742  vlib_cli_output (vm, "FIB Entries:");
1743  pool_foreach_index(fei, fib_entry_pool,
1744  ({
1745  vlib_cli_output (vm, "%d@%U",
1746  fei,
1747  format_fib_entry, fei,
1749  }));
1750  }
1751 
1752  return (NULL);
1753 }
1754 
1755 VLIB_CLI_COMMAND (show_fib_entry, static) = {
1756  .path = "show fib entry",
1757  .function = show_fib_entry_command,
1758  .short_help = "show fib entry",
1759 };
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:227
u32 sw_if_index
Definition: ipsec_gre.api:37
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
Contribute an object that is to be used to forward BIER packets.
Definition: fib_types.h:122
u8 * format_fib_entry(u8 *s, va_list *args)
Definition: fib_entry.c:139
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1698
static fib_entry_src_flag_t fib_entry_source_removed(fib_entry_t *fib_entry, fib_entry_flag_t old_flags)
Definition: fib_entry.c:970
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:137
#define FIB_ENTRY_DBG(_e, _fmt, _args...)
Definition: fib_entry_src.h:28
u8 * format_fib_entry_src_flags(u8 *s, va_list *args)
Definition: fib_entry.c:124
void fib_entry_unlock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1645
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:113
u32 flags
Definition: vhost_user.h:115
An entry in a FIB table.
Definition: fib_entry.h:462
#define CLIB_UNUSED(x)
Definition: clib.h:82
A representation of a fib path for fib_path_encode to convey the information to the caller...
Definition: fib_types.h:588
static const char * fib_attribute_names[]
Definition: fib_entry.c:36
fib_node_bw_reason_flag_t bw_reason
Definition: fib_entry_src.h:93
int fib_entry_is_resolved(fib_node_index_t fib_entry_index)
Return !0 is the entry is resolved, i.e.
Definition: fib_entry.c:1496
fib_protocol_t fib_entry_get_proto(const fib_entry_t *fib_entry)
Definition: fib_entry.c:68
fib_entry_flag_t fib_entry_get_flags_i(const fib_entry_t *fib_entry)
A representation of a path as described by a route producer.
Definition: fib_types.h:470
void fib_attached_export_cover_change(fib_entry_t *fib_entry)
If this entry is tracking a cover (in another table) then that cover has changed. ...
int dpo_is_adj(const dpo_id_t *dpo)
Return TRUE is the DPO is any type of adjacency.
Definition: dpo.c:277
static clib_error_t * show_fib_entry_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: fib_entry.c:1714
BFD session state.
void fib_path_list_contribute_urpf(fib_node_index_t path_list_index, index_t urpf)
Contribute (add) this path list&#39;s uRPF list.
void fib_entry_set_flow_hash_config(fib_node_index_t fib_entry_index, flow_hash_config_t hash_config)
Definition: fib_entry.c:1522
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:185
u32 fib_path_list_get_resolving_interface(fib_node_index_t path_list_index)
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 fib_forward_chain_type_t fib_entry_chain_type_mcast_to_ucast(fib_forward_chain_type_t fct)
Definition: fib_entry.c:416
fib_entry_src_flag_t fib_entry_path_remove(fib_node_index_t fib_entry_index, fib_source_t source, const fib_route_path_t *rpath)
Definition: fib_entry.c:1014
void fib_entry_path_add(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *rpath)
Definition: fib_entry.c:916
#define FIB_ENTRY_FORMAT_DETAIL
Definition: fib_entry.h:517
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
static fib_entry_src_t * fib_entry_get_best_src_i(const fib_entry_t *fib_entry)
Definition: fib_entry.c:261
fib_node_index_t fib_entry_get_path_list(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:555
Definitions for all things IP (v4|v6) unicast and multicast lookup related.
#define NULL
Definition: clib.h:58
Information related to the source of a FIB entry.
Definition: fib_entry.h:354
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: fib_table.c:956
Definition: fib_entry.h:281
static int fib_ip6_address_compare(const ip6_address_t *a1, const ip6_address_t *a2)
Definition: fib_entry.c:1575
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
void fib_entry_contribute_forwarding(fib_node_index_t fib_entry_index, fib_forward_chain_type_t fct, dpo_id_t *dpo)
Definition: fib_entry.c:447
void fib_entry_src_action_deactivate(fib_entry_t *fib_entry, fib_source_t source)
flow_hash_config_t lb_hash_config
the hash config to use when selecting a bucket.
Definition: load_balance.h:161
const dpo_id_t * fib_entry_contribute_ip_forwarding(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:516
enum fib_entry_delegate_type_t_ fib_entry_delegate_type_t
Delegate types.
fib_bfd_state_t fd_bfd_state
BFD state.
dpo_proto_t fib_forw_chain_type_to_dpo_proto(fib_forward_chain_type_t fct)
Convert from a chain type to the DPO proto it will install.
Definition: fib_types.c:410
void fib_entry_child_remove(fib_node_index_t fib_entry_index, u32 sibling_index)
Definition: fib_entry.c:576
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:261
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
int i
Result from a cover update/change.
Definition: fib_entry_src.h:91
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:109
static const char * fib_src_attribute_names[]
Definition: fib_entry.c:37
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
void fib_node_deinit(fib_node_t *node)
Definition: fib_node.c:197
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1688
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u32 fib_entry_pool_size(void)
Definition: fib_entry.c:1708
void fib_entry_module_init(void)
Definition: fib_entry.c:1655
u32 fe_fib_index
The index of the FIB table this entry is in.
Definition: fib_entry.h:475
Definition: fib_entry.h:277
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
fib_entry_src_t * fe_srcs
Vector of source infos.
Definition: fib_entry.h:494
dpo_id_t fd_dpo
Valid for the forwarding chain delegates.
unsigned char u8
Definition: types.h:56
fib_node_index_t fe_parent
the path-list for which this entry is a child.
Definition: fib_entry.h:499
int fib_prefix_is_host(const fib_prefix_t *prefix)
Return true is the prefix is a host prefix.
Definition: fib_types.c:162
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:140
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
u32 fib_node_child_add(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_type_t type, fib_node_index_t index)
Definition: fib_node.c:98
static void fib_entry_post_install_actions(fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t old_flags)
Definition: fib_entry.c:715
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:60
static fib_entry_src_flag_t fib_entry_src_burn_only_inherited(fib_entry_t *fib_entry)
Definition: fib_entry.c:941
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
dpo_proto_t fp_payload_proto
This protocol determines the payload protocol of packets that will be forwarded by this entry once th...
Definition: fib_types.h:236
void fib_attached_export_purge(fib_entry_t *fib_entry)
All the imported entries need to be purged.
enum fib_entry_src_attribute_t_ fib_entry_src_attribute_t
Flags for the source data.
u32 vlib_log_class_t
Definition: vlib.h:50
#define FIB_ENTRY_ATTRIBUTES
Definition: fib_entry.h:255
void fib_entry_special_update(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Definition: fib_entry.c:897
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
fib_entry_src_flag_t fib_entry_src_action_path_remove(fib_entry_t *fib_entry, fib_source_t source, const fib_route_path_t *rpath)
fib_entry_t * fib_entry_src_action_path_add(fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *rpath)
void fib_entry_delegate_remove(fib_entry_t *fib_entry, fib_entry_delegate_type_t type)
void fib_walk_sync(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_back_walk_ctx_t *ctx)
Back walk all the children of a FIB node.
Definition: fib_walk.c:745
#define DPO_PROTO_NONE
Definition: dpo.h:71
int fib_entry_is_host(fib_node_index_t fib_entry_index)
Return !0 is the entry represents a host prefix.
Definition: fib_entry.c:1486
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:177
#define MPLS_IS_REPLICATE
The top bit of the index, which is the result of the MPLS lookup is used to determine if the DPO is a...
Definition: mpls_types.h:66
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Aggregrate type for a prefix.
Definition: fib_types.h:203
fib_node_index_t fib_entry_get_index(const fib_entry_t *fib_entry)
Definition: fib_entry.c:62
void fib_entry_contribute_urpf(fib_node_index_t entry_index, index_t urpf)
Contribute the set of Adjacencies that this entry forwards with to build the uRPF list of its childre...
Definition: fib_entry.c:401
void fib_show_memory_usage(const char *name, u32 in_use_elts, u32 allocd_elts, size_t size_elt)
Show the memory usage for a type.
Definition: fib_node.c:220
unsigned int u32
Definition: types.h:88
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:141
static fib_node_back_walk_rc_t fib_entry_back_walk_notify(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Definition: fib_entry.c:312
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
u16 fp_len
The mask length.
Definition: fib_types.h:207
fib_entry_delegate_t * fib_entry_delegate_get(const fib_entry_t *fib_entry, fib_entry_delegate_type_t type)
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1626
u16 install
Definition: fib_entry_src.h:92
adj_index_t fib_entry_get_adj(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:536
Definition: fib_entry.h:275
#define FOR_EACH_SRC_ADDED(_entry, _src, _source, action)
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
Contribute an object that is to be used to forward end-of-stack MPLS packets.
Definition: fib_types.h:129
fib_node_bw_reason_flag_t fnbw_reason
The reason/trigger for the backwalk.
Definition: fib_node.h:208
void fib_entry_src_mk_lb(fib_entry_t *fib_entry, const fib_entry_src_t *esrc, fib_forward_chain_type_t fct, dpo_id_t *dpo_lb)
static fib_source_t fib_entry_src_get_source(const fib_entry_src_t *esrc)
Definition: fib_entry.c:281
#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
u8 * format_fib_node_bw_reason(u8 *s, va_list *args)
Definition: fib_walk.c:973
static int fib_ip4_address_compare(const ip4_address_t *a1, const ip4_address_t *a2)
Definition: fib_entry.c:1561
fib_entry_t * fib_entry_src_action_add(fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
enum fib_source_t_ fib_source_t
The different sources that can create a route.
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
#define FOR_EACH_DELEGATE_CHAIN(_entry, _fdt, _fed, _body)
dpo_type_t dpoi_type
the type
Definition: dpo.h:172
void fib_node_lock(fib_node_t *node)
Definition: fib_node.c:203
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
Definition: fib_entry.h:339
load-balancing over a choice of [un]equal cost paths
Definition: dpo.h:102
#define FOR_EACH_FIB_SRC_ATTRIBUTE(_item)
Definition: fib_entry.h:329
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
The FIB DPO provieds;.
Definition: load_balance.h:106
fib_node_bw_flags_t fnbw_flags
additional flags for the walk
Definition: fib_node.h:213
fib_entry_src_flag_t fib_entry_delete(fib_node_index_t fib_entry_index, fib_source_t source)
fib_entry_delete
Definition: fib_entry.c:1223
u8 * format_fib_entry_deletegate(u8 *s, va_list *args)
fib_node_index_t fib_entry_create_special(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Definition: fib_entry.c:764
A list of path-extensions.
Definition: fib_types.h:605
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
enum fib_entry_attribute_t_ fib_entry_attribute_t
The different sources that can create a route.
fib_node_type_t fn_type
The node&#39;s type.
Definition: fib_node.h:295
An node in the FIB graph.
Definition: fib_node.h:291
void fib_node_unlock(fib_node_t *node)
Definition: fib_node.c:209
const dpo_id_t * load_balance_get_bucket(index_t lbi, u32 bucket)
Definition: load_balance.c:317
#define FIB_SOURCE_MAX
The maximum number of sources.
Definition: fib_entry.h:157
fib_entry_src_flag_t fib_entry_src_action_remove_or_update_inherit(fib_entry_t *fib_entry, fib_source_t source)
void fib_entry_inherit(fib_node_index_t cover, fib_node_index_t covered)
fib_entry_inherit
Definition: fib_entry.c:1210
static void fib_entry_source_change_w_flags(fib_entry_t *fib_entry, fib_source_t old_source, fib_entry_flag_t old_flags, fib_source_t new_source)
Definition: fib_entry.c:829
#define FOR_EACH_FIB_ATTRIBUTE(_item)
Definition: fib_entry.h:269
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1461
fib_entry_src_flag_t fib_entry_src_action_remove(fib_entry_t *fib_entry, fib_source_t source)
static fib_node_t * fib_entry_get_node(fib_node_index_t index)
Definition: fib_entry.c:56
static void fib_entry_last_lock_gone(fib_node_t *node)
Definition: fib_entry.c:234
fib_node_list_t fn_children
Vector of nodes that depend upon/use/share this node.
Definition: fib_node.h:305
fib_entry_delegate_type_t fib_entry_chain_type_to_delegate_type(fib_forward_chain_type_t fct)
vlib_main_t * vm
Definition: buffer.c:312
u8 * format_fib_source(u8 *s, va_list *args)
Definition: fib_entry.c:99
void fib_entry_src_action_installed(const fib_entry_t *fib_entry, fib_source_t source)
Definition: fib_entry.h:335
static fib_entry_t * fib_entry_from_fib_node(fib_node_t *node)
Definition: fib_entry.c:227
Contribute an object that is to be used to forward NSH packets.
Definition: fib_types.h:147
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
void fib_entry_src_action_activate(fib_entry_t *fib_entry, fib_source_t source)
void fib_entry_source_change(fib_entry_t *fib_entry, fib_source_t old_source, fib_source_t new_source)
Definition: fib_entry.c:866
Force the walk to be synchronous.
Definition: fib_node.h:170
int fib_entry_recursive_loop_detect(fib_node_index_t entry_index, fib_node_index_t **entry_indicies)
Definition: fib_entry.c:1410
fib_node_get_t fnv_get
Definition: fib_node.h:279
fib_entry_src_cover_res_t fib_entry_src_action_cover_change(fib_entry_t *fib_entry, fib_entry_src_t *esrc)
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
static fib_entry_t * fib_entry_post_flag_update_actions(fib_entry_t *fib_entry, fib_entry_flag_t old_flags)
Definition: fib_entry.c:646
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:283
u32 fib_node_get_n_children(fib_node_type_t parent_type, fib_node_index_t parent_index)
Definition: fib_node.c:142
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
#define ARRAY_LEN(x)
Definition: clib.h:62
fib_forward_chain_type_t fib_entry_delegate_type_to_chain_type(fib_entry_delegate_type_t fdt)
u8 * format_fib_entry_flags(u8 *s, va_list *args)
Definition: fib_entry.c:109
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:50
enum fib_entry_flag_t_ fib_entry_flag_t
mpls_label_t fp_label
Definition: fib_types.h:229
Context passed between object during a back walk.
Definition: fib_node.h:204
void fib_entry_lock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1635
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
int fib_path_list_recursive_loop_detect(fib_node_index_t path_list_index, fib_node_index_t **entry_indicies)
fib_entry_flag_t fes_entry_flags
Flags the source contributes to the entry.
Definition: fib_entry.h:368
int fib_path_list_is_looped(fib_node_index_t path_list_index)
fib_source_t fes_src
Which source this info block is for.
Definition: fib_entry.h:373
#define ASSERT(truth)
fib_entry_src_flag_t fes_flags
Flags on the source.
Definition: fib_entry.h:378
fib_entry_t * fib_entry_src_action_path_swap(fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *rpaths)
static void fib_entry_show_memory(void)
Definition: fib_entry.c:359
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:219
fib_node_t fe_node
Base class.
Definition: fib_entry.h:466
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
fib_entry_t * fib_entry_src_action_update(fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
u8 * format_fib_forw_chain_type(u8 *s, va_list *args)
Definition: fib_types.c:48
Definition: fib_entry.h:336
int fib_path_ext_list_length(const fib_path_ext_list_t *list)
Definition: fib_path_ext.c:481
void fib_node_child_remove(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_index_t sibling_index)
Definition: fib_node.c:123
static void fib_entry_post_update_actions(fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t old_flags)
Definition: fib_entry.c:792
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:237
enum fib_entry_src_flag_t_ fib_entry_src_flag_t
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:147
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:84
static fib_entry_t * fib_entry_pool
Definition: fib_entry.c:42
u32 entries
void fib_entry_cover_changed(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1268
void fib_entry_encode(fib_node_index_t fib_entry_index, fib_route_path_encode_t **api_rpaths)
Definition: fib_entry.c:1662
dpo_id_t fe_lb
The load-balance used for forwarding.
Definition: fib_entry.h:488
void fib_attached_export_cover_update(fib_entry_t *fib_entry)
If this entry is tracking a cover (in another table) then that cover has been updated.
fib_entry_delegate_t * fe_delegates
A vector of delegates.
Definition: fib_entry.h:510
fib_node_index_t fes_pl
The path-list created by the source.
Definition: fib_entry.h:363
void fib_entry_src_inherit(const fib_entry_t *cover, fib_entry_t *covered)
void fib_attached_export_import(fib_entry_t *fib_entry, fib_node_index_t export_fib)
FIB attached export.
#define FIB_ENTRY_FORMAT_BRIEF
Definition: fib_entry.h:516
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
static fib_entry_flag_t fib_entry_src_get_flags(const fib_entry_src_t *esrc)
Definition: fib_entry.c:291
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
fib_node_index_t fib_entry_create(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *paths)
Definition: fib_entry.c:725
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
Marker.
Definition: fib_entry.h:34
void fib_entry_recalculate_forwarding(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:814
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 fn_locks
Number of dependents on this node.
Definition: fib_node.h:311
u8 * fib_path_list_format(fib_node_index_t path_list_index, u8 *s)
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:195
u32 fib_entry_get_stats_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1551
typedef prefix
Definition: ip_types.api:35
u8 * fib_entry_src_format(fib_entry_t *fib_entry, fib_source_t source, u8 *s)
#define FOR_EACH_DELEGATE(_entry, _fdt, _fed, _body)
void fib_entry_cover_updated(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1342
A FIB graph nodes virtual function table.
Definition: fib_node.h:278
enum fib_node_type_t_ fib_node_type_t
The types of nodes in a FIB graph.
void fib_entry_src_action_reactivate(fib_entry_t *fib_entry, fib_source_t source)
void fib_entry_update(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *paths)
fib_entry_update
Definition: fib_entry.c:1235
#define FIB_ENTRY_FORMAT_DETAIL2
Definition: fib_entry.h:518
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:231
#define vec_foreach(var, vec)
Vector iterator.
A path extension is a per-entry addition to the forwarding information when packets are sent for that...
Definition: fib_path_ext.h:98
fib_path_list_walk_rc_t fib_path_encode(fib_node_index_t path_list_index, fib_node_index_t path_index, const fib_path_ext_t *path_ext, void *ctx)
Definition: fib_path.c:2627
u8 fes_ref_count
1 bytes ref count.
Definition: fib_entry.h:385
fib_path_ext_list_t fes_path_exts
A vector of path extensions.
Definition: fib_entry.h:358
dpo_proto_t fib_entry_get_dpo_proto(const fib_entry_t *fib_entry)
Definition: fib_entry.c:74
u8 * format_fib_path_ext_list(u8 *s, va_list *args)
Definition: fib_path_ext.c:461
void fib_path_list_walk_w_ext(fib_node_index_t path_list_index, const fib_path_ext_list_t *ext_list, fib_path_list_walk_w_ext_fn_t func, void *ctx)
u16 as_u16[8]
Definition: ip6_packet.h:49
Contribute an object that is to be used to forward non-end-of-stack MPLS packets. ...
Definition: fib_types.h:118
void fib_entry_cover_update_notify(fib_entry_t *fib_entry)
static int fib_entry_cmp(fib_node_index_t fib_entry_index1, fib_node_index_t fib_entry_index2)
Definition: fib_entry.c:1590
A Delagate is a means to implmenet the Delagation design pattern; the extension of an objects functio...
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:538
u8 * fib_node_children_format(fib_node_list_t list, u8 *s)
Definition: fib_node.c:176
static fib_entry_t * fib_entry_alloc(u32 fib_index, const fib_prefix_t *prefix, fib_node_index_t *fib_entry_index)
Definition: fib_entry.c:606
fib_source_t fib_entry_get_best_source(fib_node_index_t entry_index)
Definition: fib_entry.c:1471
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:133
fib_entry_delegate_t * fib_entry_delegate_find_or_add(fib_entry_t *fib_entry, fib_entry_delegate_type_t fdt)
#define FIB_ENTRY_SRC_ATTRIBUTES
Definition: fib_entry.h:322
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:762
void fib_entry_special_add(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Definition: fib_entry.c:880
vlib_log_class_t fib_entry_logger
the logger
Definition: fib_entry.c:47
fib_forward_chain_type_t fib_entry_get_default_chain_type(const fib_entry_t *fib_entry)
Definition: fib_entry.c:80
fib_entry_src_cover_res_t fib_entry_src_action_cover_update(fib_entry_t *fib_entry, fib_entry_src_t *esrc)
const fib_prefix_t fe_prefix
The prefix of the route.
Definition: fib_entry.h:471
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry.c:1108
static const char * fib_source_names[]
Definition: fib_entry.c:35
void fib_entry_src_action_uninstall(fib_entry_t *fib_entry)
#define FIB_SOURCES
Definition: fib_entry.h:159
mpls_eos_bit_t fp_eos
Definition: fib_types.h:230
fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:301
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128