FD.io VPP  v17.01.1-3-gc6833f8
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;
37 
38 /*
39  * Pool for all fib_entries
40  */
42 
45 {
46  return (pool_elt_at_index(fib_entry_pool, index));
47 }
48 
49 static fib_node_t *
51 {
52  return ((fib_node_t*)fib_entry_get(index));
53 }
54 
56 fib_entry_get_index (const fib_entry_t * fib_entry)
57 {
58  return (fib_entry - fib_entry_pool);
59 }
60 
61 static fib_protocol_t
62 fib_entry_get_proto (const fib_entry_t * fib_entry)
63 {
64  return (fib_entry->fe_prefix.fp_proto);
65 }
66 
69 {
70  switch (fib_entry->fe_prefix.fp_proto)
71  {
72  case FIB_PROTOCOL_IP4:
74  case FIB_PROTOCOL_IP6:
76  case FIB_PROTOCOL_MPLS:
77  if (MPLS_EOS == fib_entry->fe_prefix.fp_eos)
78  /*
79  * If the entry being asked is a eos-MPLS label entry,
80  * then use the payload-protocol field, that we stashed there
81  * for just this purpose
82  */
84  fib_entry->fe_prefix.fp_payload_proto));
85  else
87  }
88 
90 }
91 
92 u8 *
93 format_fib_entry (u8 * s, va_list * args)
94 {
97  fib_path_ext_t *path_ext;
98  fib_entry_t *fib_entry;
99  fib_entry_src_t *src;
100  fib_node_index_t fei;
101  fib_source_t source;
102  u32 n_covered;
103  int level;
104 
105  fei = va_arg (*args, fib_node_index_t);
106  level = va_arg (*args, int);
107  fib_entry = fib_entry_get(fei);
108 
109  s = format (s, "%U", format_fib_prefix, &fib_entry->fe_prefix);
110 
111  if (level >= FIB_ENTRY_FORMAT_DETAIL)
112  {
113  s = format (s, " fib:%d", fib_entry->fe_fib_index);
114  s = format (s, " index:%d", fib_entry_get_index(fib_entry));
115  s = format (s, " locks:%d", fib_entry->fe_node.fn_locks);
116 
117  FOR_EACH_SRC_ADDED(fib_entry, src, source,
118  ({
119  s = format (s, "\n src:%s ",
120  fib_source_names[source]);
121  s = fib_entry_src_format(fib_entry, source, s);
122  s = format (s, " refs:%d ", src->fes_ref_count);
123  if (FIB_ENTRY_FLAG_NONE != src->fes_entry_flags) {
124  s = format(s, "flags:");
125  FOR_EACH_FIB_ATTRIBUTE(attr) {
126  if ((1<<attr) & src->fes_entry_flags) {
127  s = format (s, "%s,", fib_attribute_names[attr]);
128  }
129  }
130  }
131  s = format (s, "\n");
132  if (FIB_NODE_INDEX_INVALID != src->fes_pl)
133  {
134  s = fib_path_list_format(src->fes_pl, s);
135  }
136  if (NULL != src->fes_path_exts)
137  {
138  s = format(s, " Extensions:");
139  vec_foreach(path_ext, src->fes_path_exts)
140  {
141  s = format(s, "\n %U", format_fib_path_ext, path_ext);
142  }
143  }
144  }));
145 
146  n_covered = fib_entry_cover_get_size(fib_entry);
147  if (n_covered > 0) {
148  s = format(s, "\n tracking %d covered: ", n_covered);
149  s = fib_entry_cover_list_format(fib_entry, s);
150  }
151  s = fib_ae_import_format(fib_entry, s);
152  s = fib_ae_export_format(fib_entry, s);
153 
154  s = format (s, "\n forwarding: ");
155  }
156  else
157  {
158  s = format (s, "\n");
159  }
160 
161  fct = fib_entry_get_default_chain_type(fib_entry);
162 
163  if (!dpo_id_is_valid(&fib_entry->fe_lb))
164  {
165  s = format (s, " UNRESOLVED\n");
166  return (s);
167  }
168  else
169  {
170  s = format(s, " %U-chain\n %U",
173  &fib_entry->fe_lb,
174  2);
175  s = format(s, "\n");
176 
177  if (level >= FIB_ENTRY_FORMAT_DETAIL2)
178  {
181 
182  FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
183  {
184  s = format(s, " %U-chain\n %U",
187  format_dpo_id, &fed->fd_dpo, 2);
188  s = format(s, "\n");
189  });
190  }
191  }
192 
193  if (level >= FIB_ENTRY_FORMAT_DETAIL2)
194  {
195  s = format(s, "\nchildren:");
196  s = fib_node_children_format(fib_entry->fe_node.fn_children, s);
197  }
198 
199  return (s);
200 }
201 
202 static fib_entry_t*
204 {
205 #if CLIB_DEBUG > 0
207 #endif
208  return ((fib_entry_t*)node);
209 }
210 
211 static void
213 {
216  fib_entry_t *fib_entry;
217 
218  fib_entry = fib_entry_from_fib_node(node);
219 
220  FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
221  {
222  dpo_reset(&fed->fd_dpo);
223  fib_entry_delegate_remove(fib_entry, fdt);
224  });
225 
226  FIB_ENTRY_DBG(fib_entry, "last-lock");
227 
228  fib_node_deinit(&fib_entry->fe_node);
229  // FIXME -RR Backwalk
230 
231  ASSERT(0 == vec_len(fib_entry->fe_delegates));
232  vec_free(fib_entry->fe_delegates);
233  vec_free(fib_entry->fe_srcs);
234  pool_put(fib_entry_pool, fib_entry);
235 }
236 
237 static fib_entry_src_t*
239 {
240  fib_entry_src_t *bsrc;
241 
242  /*
243  * the enum of sources is deliberately arranged in priority order
244  */
245  if (0 == vec_len(fib_entry->fe_srcs))
246  {
247  bsrc = NULL;
248  }
249  else
250  {
251  bsrc = vec_elt_at_index(fib_entry->fe_srcs, 0);
252  }
253 
254  return (bsrc);
255 }
256 
257 static fib_source_t
259 {
260  if (NULL != esrc)
261  {
262  return (esrc->fes_src);
263  }
264  return (FIB_SOURCE_MAX);
265 }
266 
267 static fib_entry_flag_t
269 {
270  if (NULL != esrc)
271  {
272  return (esrc->fes_entry_flags);
273  }
274  return (FIB_ENTRY_FLAG_NONE);
275 }
276 
279 {
280  return (fib_entry_get_flags_i(fib_entry_get(fib_entry_index)));
281 }
282 
283 /*
284  * fib_entry_back_walk_notify
285  *
286  * A back walk has reach this entry.
287  */
291 {
292  fib_entry_t *fib_entry;
293 
294  fib_entry = fib_entry_from_fib_node(node);
295 
302  {
305  fib_entry_get_index(fib_entry)));
306  }
307 
308  /*
309  * all other walk types can be reclassifed to a re-evaluate to
310  * all recursive dependents.
311  * By reclassifying we ensure that should any of these walk types meet
312  * they can be merged.
313  */
315 
316  /*
317  * ... and nothing is forced sync from now on.
318  */
320 
321  /*
322  * propagate the backwalk further if we haven't already reached the
323  * maximum depth.
324  */
326  fib_entry_get_index(fib_entry),
327  ctx);
328 
330 }
331 
332 static void
334 {
335  u32 n_srcs = 0, n_exts = 0;
336  fib_entry_src_t *esrc;
337  fib_entry_t *entry;
338 
339  fib_show_memory_usage("Entry",
340  pool_elts(fib_entry_pool),
341  pool_len(fib_entry_pool),
342  sizeof(fib_entry_t));
343 
344  pool_foreach(entry, fib_entry_pool,
345  ({
346  n_srcs += vec_len(entry->fe_srcs);
347  vec_foreach(esrc, entry->fe_srcs)
348  {
349  n_exts += vec_len(esrc->fes_path_exts);
350  }
351  }));
352 
353  fib_show_memory_usage("Entry Source",
354  n_srcs, n_srcs, sizeof(fib_entry_src_t));
355  fib_show_memory_usage("Entry Path-Extensions",
356  n_exts, n_exts,
357  sizeof(fib_path_ext_t));
358 }
359 
360 /*
361  * The FIB path-list's graph node virtual function table
362  */
363 static const fib_node_vft_t fib_entry_vft = {
365  .fnv_last_lock = fib_entry_last_lock_gone,
366  .fnv_back_walk = fib_entry_back_walk_notify,
367  .fnv_mem_show = fib_entry_show_memory,
368 };
369 
370 /**
371  * @brief Contribute the set of Adjacencies that this entry forwards with
372  * to build the uRPF list of its children
373  */
374 void
376  index_t urpf)
377 {
378  fib_entry_t *fib_entry;
379 
380  fib_entry = fib_entry_get(entry_index);
381 
382  return (fib_path_list_contribute_urpf(fib_entry->fe_parent, urpf));
383 }
384 
385 /*
386  * fib_entry_contribute_forwarding
387  *
388  * Get an lock the forwarding information (DPO) contributed by the FIB entry.
389  */
390 void
393  dpo_id_t *dpo)
394 {
396  fib_entry_t *fib_entry;
397 
398  fib_entry = fib_entry_get(fib_entry_index);
399 
400  if (fct == fib_entry_get_default_chain_type(fib_entry))
401  {
402  dpo_copy(dpo, &fib_entry->fe_lb);
403  }
404  else
405  {
406  fed = fib_entry_delegate_get(fib_entry,
408 
409  if (NULL == fed)
410  {
412  fib_entry,
414  /*
415  * on-demand create eos/non-eos.
416  * There is no on-demand delete because:
417  * - memory versus complexity & reliability:
418  * leaving unrequired [n]eos LB arounds wastes memory, cleaning
419  * then up on the right trigger is more code. i favour the latter.
420  */
421  fib_entry_src_mk_lb(fib_entry,
422  fib_entry_get_best_src_i(fib_entry),
423  fct,
424  &fed->fd_dpo);
425  }
426 
427  dpo_copy(dpo, &fed->fd_dpo);
428  }
429 }
430 
431 const dpo_id_t *
433 {
435  fib_entry_t *fib_entry;
436 
437  fib_entry = fib_entry_get(fib_entry_index);
438  fct = fib_entry_get_default_chain_type(fib_entry);
439 
442 
443  return (&fib_entry->fe_lb);
444 }
445 
448 {
449  const dpo_id_t *dpo;
450 
451  dpo = fib_entry_contribute_ip_forwarding(fib_entry_index);
452  dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
453 
454  if (dpo_is_adj(dpo))
455  {
456  return (dpo->dpoi_index);
457  }
458  return (ADJ_INDEX_INVALID);
459 }
460 
463 {
464  fib_entry_t *fib_entry;
465 
466  fib_entry = fib_entry_get(fib_entry_index);
467 
468  return (fib_entry->fe_parent);
469 }
470 
471 u32
473  fib_node_type_t child_type,
474  fib_node_index_t child_index)
475 {
477  fib_entry_index,
478  child_type,
479  child_index));
480 };
481 
482 void
484  u32 sibling_index)
485 {
487  fib_entry_index,
488  sibling_index);
489 
491  fib_entry_index))
492  {
493  /*
494  * if there are no children left then there is no reason to keep
495  * the non-default forwarding chains. those chains are built only
496  * because the children want them.
497  */
500  fib_entry_t *fib_entry;
501 
502  fib_entry = fib_entry_get(fib_entry_index);
503 
504  FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
505  {
506  dpo_reset(&fed->fd_dpo);
507  fib_entry_delegate_remove(fib_entry, fdt);
508  });
509  }
510 }
511 
512 static fib_entry_t *
513 fib_entry_alloc (u32 fib_index,
514  const fib_prefix_t *prefix,
515  fib_node_index_t *fib_entry_index)
516 {
517  fib_entry_t *fib_entry;
518  fib_prefix_t *fep;
519 
520  pool_get(fib_entry_pool, fib_entry);
521  memset(fib_entry, 0, sizeof(*fib_entry));
522 
523  fib_node_init(&fib_entry->fe_node,
525 
526  fib_entry->fe_fib_index = fib_index;
527 
528  /*
529  * the one time we need to update the const prefix is when
530  * the entry is first created
531  */
532  fep = (fib_prefix_t*)&(fib_entry->fe_prefix);
533  *fep = *prefix;
534 
535  if (FIB_PROTOCOL_MPLS == fib_entry->fe_prefix.fp_proto)
536  {
537  fep->fp_len = 21;
538  if (MPLS_NON_EOS == fep->fp_eos)
539  {
541  }
543  }
544 
545  dpo_reset(&fib_entry->fe_lb);
546 
547  *fib_entry_index = fib_entry_get_index(fib_entry);
548 
549  FIB_ENTRY_DBG(fib_entry, "alloc");
550 
551  return (fib_entry);
552 }
553 
554 static void
556  fib_source_t source,
557  fib_entry_flag_t old_flags)
558 {
559  /*
560  * handle changes to attached export for import entries
561  */
562  int is_import = (FIB_ENTRY_FLAG_IMPORT & fib_entry_get_flags_i(fib_entry));
563  int was_import = (FIB_ENTRY_FLAG_IMPORT & old_flags);
564 
565  if (!was_import && is_import)
566  {
567  /*
568  * transition from not exported to exported
569  */
570 
571  /*
572  * there is an assumption here that the entry resolves via only
573  * one interface and that it is the cross VRF interface.
574  */
575  u32 sw_if_index = fib_path_list_get_resolving_interface(fib_entry->fe_parent);
576 
577  fib_attached_export_import(fib_entry,
579  fib_entry_get_proto(fib_entry),
580  sw_if_index));
581  }
582  else if (was_import && !is_import)
583  {
584  /*
585  * transition from exported to not exported
586  */
587  fib_attached_export_purge(fib_entry);
588  }
589  /*
590  * else
591  * no change. nothing to do.
592  */
593 
594  /*
595  * handle changes to attached export for export entries
596  */
597  int is_attached = (FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags_i(fib_entry));
598  int was_attached = (FIB_ENTRY_FLAG_ATTACHED & old_flags);
599 
600  if (!was_attached && is_attached)
601  {
602  /*
603  * transition to attached. time to export
604  */
605  // FIXME
606  }
607  // else FIXME
608 }
609 
610 static void
612  fib_source_t source,
613  fib_entry_flag_t old_flags)
614 {
615  fib_entry_post_flag_update_actions(fib_entry, source, old_flags);
616  fib_entry_src_action_installed(fib_entry, source);
617 }
618 
621  const fib_prefix_t *prefix,
622  fib_source_t source,
624  const fib_route_path_t *paths)
625 {
626  fib_node_index_t fib_entry_index;
627  fib_entry_t *fib_entry;
628 
629  ASSERT(0 < vec_len(paths));
630 
631  fib_entry = fib_entry_alloc(fib_index, prefix, &fib_entry_index);
632 
633  /*
634  * since this is a new entry create, we don't need to check for winning
635  * sources - there is only one.
636  */
637  fib_entry = fib_entry_src_action_add(fib_entry, source, flags,
638  drop_dpo_get(
640  fib_entry_get_proto(fib_entry))));
642  source,
643  flags,
644  paths);
645  /*
646  * handle possible realloc's by refetching the pointer
647  */
648  fib_entry = fib_entry_get(fib_entry_index);
649  fib_entry_src_action_activate(fib_entry, source);
650 
652 
653  return (fib_entry_index);
654 }
655 
658  const fib_prefix_t *prefix,
659  fib_source_t source,
661  const dpo_id_t *dpo)
662 {
663  fib_node_index_t fib_entry_index;
664  fib_entry_t *fib_entry;
665 
666  /*
667  * create and initiliase the new enty
668  */
669  fib_entry = fib_entry_alloc(fib_index, prefix, &fib_entry_index);
670 
671  /*
672  * create the path-list
673  */
674  fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
675  fib_entry_src_action_activate(fib_entry, source);
676 
678 
679  return (fib_entry_index);
680 }
681 
682 static void
684  fib_source_t source,
685  fib_entry_flag_t old_flags)
686 {
687  /*
688  * backwalk to children to inform then of the change to forwarding.
689  */
690  fib_node_back_walk_ctx_t bw_ctx = {
692  };
693 
695 
696  /*
697  * then inform any covered prefixes
698  */
700 
701  fib_entry_post_install_actions(fib_entry, source, old_flags);
702 }
703 
704 static void
706  fib_source_t best_source,
707  fib_source_t new_source,
708  fib_entry_flag_t old_flags)
709 {
710  /*
711  * if the path list for the source passed is invalid,
712  * then we need to create a new one. else we are updating
713  * an existing.
714  */
715  if (new_source < best_source)
716  {
717  /*
718  * we have a new winning source.
719  */
720  fib_entry_src_action_deactivate(fib_entry, best_source);
721  fib_entry_src_action_activate(fib_entry, new_source);
722  }
723  else if (new_source > best_source)
724  {
725  /*
726  * the new source loses. nothing to do here.
727  * the data from the source is saved in the path-list created
728  */
729  return;
730  }
731  else
732  {
733  /*
734  * the new source is one this entry already has.
735  * But the path-list was updated, which will contribute new forwarding,
736  * so install it.
737  */
738  fib_entry_src_action_deactivate(fib_entry, new_source);
739  fib_entry_src_action_activate(fib_entry, new_source);
740  }
741 
742  fib_entry_post_update_actions(fib_entry, new_source, old_flags);
743 }
744 
745 void
747  fib_source_t source,
749  const dpo_id_t *dpo)
750 {
751  fib_source_t best_source;
752  fib_entry_flag_t bflags;
753  fib_entry_t *fib_entry;
754  fib_entry_src_t *bsrc;
755 
756  fib_entry = fib_entry_get(fib_entry_index);
757 
758  bsrc = fib_entry_get_best_src_i(fib_entry);
759  best_source = fib_entry_src_get_source(bsrc);
760  bflags = fib_entry_src_get_flags(bsrc);
761 
762  fib_entry = fib_entry_src_action_add(fib_entry, source, flags, dpo);
763  fib_entry_source_change(fib_entry, best_source, source, bflags);
764 }
765 
766 void
768  fib_source_t source,
770  const dpo_id_t *dpo)
771 {
772  fib_source_t best_source;
773  fib_entry_flag_t bflags;
774  fib_entry_t *fib_entry;
775  fib_entry_src_t *bsrc;
776 
777  fib_entry = fib_entry_get(fib_entry_index);
778 
779  bsrc = fib_entry_get_best_src_i(fib_entry);
780  best_source = fib_entry_src_get_source(bsrc);
781  bflags = fib_entry_src_get_flags(bsrc);
782 
783  fib_entry = fib_entry_src_action_update(fib_entry, source, flags, dpo);
784  fib_entry_source_change(fib_entry, best_source, source, bflags);
785 }
786 
787 
788 void
790  fib_source_t source,
792  const fib_route_path_t *rpath)
793 {
794  fib_source_t best_source;
795  fib_entry_flag_t bflags;
796  fib_entry_t *fib_entry;
797  fib_entry_src_t *bsrc;
798 
799  ASSERT(1 == vec_len(rpath));
800 
801  fib_entry = fib_entry_get(fib_entry_index);
802  ASSERT(NULL != fib_entry);
803 
804  bsrc = fib_entry_get_best_src_i(fib_entry);
805  best_source = fib_entry_src_get_source(bsrc);
806  bflags = fib_entry_src_get_flags(bsrc);
807 
808  fib_entry = fib_entry_src_action_path_add(fib_entry, source, flags, rpath);
809 
810  /*
811  * if the path list for the source passed is invalid,
812  * then we need to create a new one. else we are updating
813  * an existing.
814  */
815  if (source < best_source)
816  {
817  /*
818  * we have a new winning source.
819  */
820  fib_entry_src_action_deactivate(fib_entry, best_source);
821  fib_entry_src_action_activate(fib_entry, source);
822  }
823  else if (source > best_source)
824  {
825  /*
826  * the new source loses. nothing to do here.
827  * the data from the source is saved in the path-list created
828  */
829  return;
830  }
831  else
832  {
833  /*
834  * the new source is one this entry already has.
835  * But the path-list was updated, which will contribute new forwarding,
836  * so install it.
837  */
838  fib_entry_src_action_deactivate(fib_entry, source);
839  fib_entry_src_action_activate(fib_entry, source);
840  }
841 
842  fib_entry_post_update_actions(fib_entry, source, bflags);
843 }
844 
845 /*
846  * fib_entry_path_remove
847  *
848  * remove a path from the entry.
849  * return the fib_entry's index if it is still present, INVALID otherwise.
850  */
853  fib_source_t source,
854  const fib_route_path_t *rpath)
855 {
856  fib_entry_src_flag_t sflag;
857  fib_source_t best_source;
858  fib_entry_flag_t bflags;
859  fib_entry_t *fib_entry;
860  fib_entry_src_t *bsrc;
861 
862  ASSERT(1 == vec_len(rpath));
863 
864  fib_entry = fib_entry_get(fib_entry_index);
865  ASSERT(NULL != fib_entry);
866 
867  bsrc = fib_entry_get_best_src_i(fib_entry);
868  best_source = fib_entry_src_get_source(bsrc);
869  bflags = fib_entry_src_get_flags(bsrc);
870 
871  sflag = fib_entry_src_action_path_remove(fib_entry, source, rpath);
872 
873  /*
874  * if the path list for the source passed is invalid,
875  * then we need to create a new one. else we are updating
876  * an existing.
877  */
878  if (source < best_source )
879  {
880  /*
881  * Que! removing a path from a source that is better than the
882  * one this entry is using.
883  */
884  ASSERT(0);
885  }
886  else if (source > best_source )
887  {
888  /*
889  * the source is not the best. nothing to do.
890  */
891  return (FIB_ENTRY_SRC_FLAG_ADDED);
892  }
893  else
894  {
895  /*
896  * removing a path from the path-list we were using.
897  */
898  if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag))
899  {
900  /*
901  * the last path from the source was removed.
902  * fallback to lower source
903  */
904  bsrc = fib_entry_get_best_src_i(fib_entry);
905  best_source = fib_entry_src_get_source(bsrc);
906 
907  if (FIB_SOURCE_MAX == best_source) {
908  /*
909  * no more sources left. this entry is toast.
910  */
912  fib_entry_post_flag_update_actions(fib_entry, source, bflags);
913 
914  return (FIB_ENTRY_SRC_FLAG_NONE);
915  }
916  else
917  {
918  fib_entry_src_action_activate(fib_entry, best_source);
919  source = best_source;
920  }
921  }
922  else
923  {
924  /*
925  * re-install the new forwarding information
926  */
927  fib_entry_src_action_deactivate(fib_entry, source);
928  fib_entry_src_action_activate(fib_entry, source);
929  }
930  }
931 
932  fib_entry_post_update_actions(fib_entry, source, bflags);
933 
934  /*
935  * still have sources
936  */
937  return (FIB_ENTRY_SRC_FLAG_ADDED);
938 }
939 
940 /*
941  * fib_entry_special_remove
942  *
943  * remove a special source from the entry.
944  * return the fib_entry's index if it is still present, INVALID otherwise.
945  */
948  fib_source_t source)
949 {
950  fib_entry_src_flag_t sflag;
951  fib_source_t best_source;
952  fib_entry_flag_t bflags;
953  fib_entry_t *fib_entry;
954  fib_entry_src_t *bsrc;
955 
956  fib_entry = fib_entry_get(fib_entry_index);
957  ASSERT(NULL != fib_entry);
958 
959  bsrc = fib_entry_get_best_src_i(fib_entry);
960  best_source = fib_entry_src_get_source(bsrc);
961  bflags = fib_entry_src_get_flags(bsrc);
962 
963  sflag = fib_entry_src_action_remove(fib_entry, source);
964 
965  /*
966  * if the path list for the source passed is invalid,
967  * then we need to create a new one. else we are updating
968  * an existing.
969  */
970  if (source < best_source )
971  {
972  /*
973  * Que! removing a path from a source that is better than the
974  * one this entry is using. This can only mean it is a source
975  * this prefix does not have.
976  */
977  return (FIB_ENTRY_SRC_FLAG_ADDED);
978  }
979  else if (source > best_source ) {
980  /*
981  * the source is not the best. nothing to do.
982  */
983  return (FIB_ENTRY_SRC_FLAG_ADDED);
984  }
985  else
986  {
987  if (!(FIB_ENTRY_SRC_FLAG_ADDED & sflag))
988  {
989  /*
990  * the source was removed. use the next best.
991  */
992  bsrc = fib_entry_get_best_src_i(fib_entry);
993  best_source = fib_entry_src_get_source(bsrc);
994 
995  if (FIB_SOURCE_MAX == best_source) {
996  /*
997  * no more sources left. this entry is toast.
998  */
1000  fib_entry_post_flag_update_actions(fib_entry, source, bflags);
1001 
1002  return (FIB_ENTRY_SRC_FLAG_NONE);
1003  }
1004  else
1005  {
1006  fib_entry_src_action_activate(fib_entry, best_source);
1007  source = best_source;
1008  }
1009  }
1010  else
1011  {
1012  /*
1013  * re-install the new forwarding information
1014  */
1015  fib_entry_src_action_reactivate(fib_entry, source);
1016  }
1017  }
1018 
1019  fib_entry_post_update_actions(fib_entry, source, bflags);
1020 
1021  /*
1022  * still have sources
1023  */
1024  return (FIB_ENTRY_SRC_FLAG_ADDED);
1025 }
1026 
1027 /**
1028  * fib_entry_delete
1029  *
1030  * The source is withdrawing all the paths it provided
1031  */
1034  fib_source_t source)
1035 {
1036  return (fib_entry_special_remove(fib_entry_index, source));
1037 }
1038 
1039 /**
1040  * fib_entry_update
1041  *
1042  * The source has provided a new set of paths that will replace the old.
1043  */
1044 void
1046  fib_source_t source,
1048  const fib_route_path_t *paths)
1049 {
1050  fib_source_t best_source;
1051  fib_entry_flag_t bflags;
1052  fib_entry_t *fib_entry;
1053  fib_entry_src_t *bsrc;
1054 
1055  fib_entry = fib_entry_get(fib_entry_index);
1056  ASSERT(NULL != fib_entry);
1057 
1058  bsrc = fib_entry_get_best_src_i(fib_entry);
1059  best_source = fib_entry_src_get_source(bsrc);
1060  bflags = fib_entry_src_get_flags(bsrc);
1061 
1063  source,
1064  flags,
1065  paths);
1066  /*
1067  * handle possible realloc's by refetching the pointer
1068  */
1069  fib_entry = fib_entry_get(fib_entry_index);
1070 
1071  /*
1072  * if the path list for the source passed is invalid,
1073  * then we need to create a new one. else we are updating
1074  * an existing.
1075  */
1076  if (source < best_source)
1077  {
1078  /*
1079  * we have a new winning source.
1080  */
1081  fib_entry_src_action_deactivate(fib_entry, best_source);
1082  fib_entry_src_action_activate(fib_entry, source);
1083  }
1084  else if (source > best_source) {
1085  /*
1086  * the new source loses. nothing to do here.
1087  * the data from the source is saved in the path-list created
1088  */
1089  return;
1090  }
1091  else
1092  {
1093  /*
1094  * the new source is one this entry already has.
1095  * But the path-list was updated, which will contribute new forwarding,
1096  * so install it.
1097  */
1098  fib_entry_src_action_deactivate(fib_entry, source);
1099  fib_entry_src_action_activate(fib_entry, source);
1100  }
1101 
1102  fib_entry_post_update_actions(fib_entry, source, bflags);
1103 }
1104 
1105 
1106 /*
1107  * fib_entry_cover_changed
1108  *
1109  * this entry is tracking its cover and that cover has changed.
1110  */
1111 void
1113 {
1115  .install = !0,
1116  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
1117  };
1118  fib_source_t source, best_source;
1119  fib_entry_flag_t bflags;
1120  fib_entry_t *fib_entry;
1121  fib_entry_src_t *esrc;
1122  u32 index;
1123 
1124  bflags = FIB_ENTRY_FLAG_NONE;
1125  best_source = FIB_SOURCE_FIRST;
1126  fib_entry = fib_entry_get(fib_entry_index);
1127 
1129 
1130  /*
1131  * propagate the notificuation to each of the added sources
1132  */
1133  index = 0;
1134  FOR_EACH_SRC_ADDED(fib_entry, esrc, source,
1135  ({
1136  if (0 == index)
1137  {
1138  /*
1139  * only the best source gets to set the back walk flags
1140  */
1141  res = fib_entry_src_action_cover_change(fib_entry, source);
1142  bflags = fib_entry_src_get_flags(esrc);
1143  best_source = fib_entry_src_get_source(esrc);
1144  }
1145  else
1146  {
1147  fib_entry_src_action_cover_change(fib_entry, source);
1148  }
1149  index++;
1150  }));
1151 
1152  if (res.install)
1153  {
1156  fib_entry_get_best_src_i(fib_entry)));
1157  fib_entry_post_install_actions(fib_entry, best_source, bflags);
1158  }
1159  else
1160  {
1161  fib_entry_src_action_uninstall(fib_entry);
1162  }
1163 
1165  {
1166  /*
1167  * time for walkies fido.
1168  */
1169  fib_node_back_walk_ctx_t bw_ctx = {
1170  .fnbw_reason = res.bw_reason,
1171  };
1172 
1173  fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx);
1174  }
1175 }
1176 
1177 /*
1178  * fib_entry_cover_updated
1179  *
1180  * this entry is tracking its cover and that cover has been updated
1181  * (i.e. its forwarding information has changed).
1182  */
1183 void
1185 {
1187  .install = !0,
1188  .bw_reason = FIB_NODE_BW_REASON_FLAG_NONE,
1189  };
1190  fib_source_t source, best_source;
1191  fib_entry_flag_t bflags;
1192  fib_entry_t *fib_entry;
1193  fib_entry_src_t *esrc;
1194  u32 index;
1195 
1196  bflags = FIB_ENTRY_FLAG_NONE;
1197  best_source = FIB_SOURCE_FIRST;
1198  fib_entry = fib_entry_get(fib_entry_index);
1199 
1201 
1202  /*
1203  * propagate the notificuation to each of the added sources
1204  */
1205  index = 0;
1206  FOR_EACH_SRC_ADDED(fib_entry, esrc, source,
1207  ({
1208  if (0 == index)
1209  {
1210  /*
1211  * only the best source gets to set the back walk flags
1212  */
1213  res = fib_entry_src_action_cover_update(fib_entry, source);
1214  bflags = fib_entry_src_get_flags(esrc);
1215  best_source = fib_entry_src_get_source(esrc);
1216  }
1217  else
1218  {
1219  fib_entry_src_action_cover_update(fib_entry, source);
1220  }
1221  index++;
1222  }));
1223 
1224  if (res.install)
1225  {
1228  fib_entry_get_best_src_i(fib_entry)));
1229  fib_entry_post_install_actions(fib_entry, best_source, bflags);
1230  }
1231  else
1232  {
1233  fib_entry_src_action_uninstall(fib_entry);
1234  }
1235 
1237  {
1238  /*
1239  * time for walkies fido.
1240  */
1241  fib_node_back_walk_ctx_t bw_ctx = {
1242  .fnbw_reason = res.bw_reason,
1243  };
1244 
1245  fib_walk_sync(FIB_NODE_TYPE_ENTRY, fib_entry_index, &bw_ctx);
1246  }
1247 }
1248 
1249 int
1251  fib_node_index_t **entry_indicies)
1252 {
1253  fib_entry_t *fib_entry;
1254  int was_looped, is_looped;
1255 
1256  fib_entry = fib_entry_get(entry_index);
1257 
1258  if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent)
1259  {
1260  fib_node_index_t *entries = *entry_indicies;
1261 
1262  vec_add1(entries, entry_index);
1263  was_looped = fib_path_list_is_looped(fib_entry->fe_parent);
1264  is_looped = fib_path_list_recursive_loop_detect(fib_entry->fe_parent,
1265  &entries);
1266 
1267  *entry_indicies = entries;
1268 
1269  if (!!was_looped != !!is_looped)
1270  {
1271  /*
1272  * re-evaluate all the entry's forwarding
1273  * NOTE: this is an inplace modify
1274  */
1276  fib_entry_delegate_t *fed;
1277 
1278  FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
1279  {
1280  fib_entry_src_mk_lb(fib_entry,
1281  fib_entry_get_best_src_i(fib_entry),
1283  &fed->fd_dpo);
1284  });
1285  }
1286  }
1287  else
1288  {
1289  /*
1290  * the entry is currently not linked to a path-list. this happens
1291  * when it is this entry that is re-linking path-lists and has thus
1292  * broken the loop
1293  */
1294  is_looped = 0;
1295  }
1296 
1297  return (is_looped);
1298 }
1299 
1300 u32
1302 {
1303  fib_entry_t *fib_entry;
1304 
1305  fib_entry = fib_entry_get(entry_index);
1306 
1307  return (fib_path_list_get_resolving_interface(fib_entry->fe_parent));
1308 }
1309 
1312 {
1313  fib_entry_t *fib_entry;
1314  fib_entry_src_t *bsrc;
1315 
1316  fib_entry = fib_entry_get(entry_index);
1317 
1318  bsrc = fib_entry_get_best_src_i(fib_entry);
1319  return (fib_entry_src_get_source(bsrc));
1320 }
1321 
1322 static int
1324  const ip4_address_t * a2)
1325 {
1326  /*
1327  * IP addresses are unsiged ints. the return value here needs to be signed
1328  * a simple subtraction won't cut it.
1329  * If the addresses are the same, the sort order is undefiend, so phoey.
1330  */
1331  return ((clib_net_to_host_u32(a1->data_u32) >
1332  clib_net_to_host_u32(a2->data_u32) ) ?
1333  1 : -1);
1334 }
1335 
1336 static int
1338  const ip6_address_t * a2)
1339 {
1340  int i;
1341  for (i = 0; i < ARRAY_LEN (a1->as_u16); i++)
1342  {
1343  int cmp = (clib_net_to_host_u16 (a1->as_u16[i]) -
1344  clib_net_to_host_u16 (a2->as_u16[i]));
1345  if (cmp != 0)
1346  return cmp;
1347  }
1348  return 0;
1349 }
1350 
1351 static int
1353  fib_node_index_t fib_entry_index2)
1354 {
1355  fib_entry_t *fib_entry1, *fib_entry2;
1356  int cmp = 0;
1357 
1358  fib_entry1 = fib_entry_get(fib_entry_index1);
1359  fib_entry2 = fib_entry_get(fib_entry_index2);
1360 
1361  switch (fib_entry1->fe_prefix.fp_proto)
1362  {
1363  case FIB_PROTOCOL_IP4:
1364  cmp = fib_ip4_address_compare(&fib_entry1->fe_prefix.fp_addr.ip4,
1365  &fib_entry2->fe_prefix.fp_addr.ip4);
1366  break;
1367  case FIB_PROTOCOL_IP6:
1368  cmp = fib_ip6_address_compare(&fib_entry1->fe_prefix.fp_addr.ip6,
1369  &fib_entry2->fe_prefix.fp_addr.ip6);
1370  break;
1371  case FIB_PROTOCOL_MPLS:
1372  cmp = (fib_entry1->fe_prefix.fp_label - fib_entry2->fe_prefix.fp_label);
1373 
1374  if (0 == cmp)
1375  {
1376  cmp = (fib_entry1->fe_prefix.fp_eos - fib_entry2->fe_prefix.fp_eos);
1377  }
1378  break;
1379  }
1380 
1381  if (0 == cmp) {
1382  cmp = (fib_entry1->fe_prefix.fp_len - fib_entry2->fe_prefix.fp_len);
1383  }
1384  return (cmp);
1385 }
1386 
1387 int
1388 fib_entry_cmp_for_sort (void *i1, void *i2)
1389 {
1390  fib_node_index_t *fib_entry_index1 = i1, *fib_entry_index2 = i2;
1391 
1392  return (fib_entry_cmp(*fib_entry_index1,
1393  *fib_entry_index2));
1394 }
1395 
1396 void
1398 {
1399  fib_entry_t *fib_entry;
1400 
1401  fib_entry = fib_entry_get(fib_entry_index);
1402 
1403  fib_node_lock(&fib_entry->fe_node);
1404 }
1405 
1406 void
1408 {
1409  fib_entry_t *fib_entry;
1410 
1411  fib_entry = fib_entry_get(fib_entry_index);
1412 
1413  fib_node_unlock(&fib_entry->fe_node);
1414 }
1415 
1416 void
1418 {
1419  fib_node_register_type (FIB_NODE_TYPE_ENTRY, &fib_entry_vft);
1420 }
1421 
1422 void
1424  fib_route_path_encode_t **api_rpaths)
1425 {
1426  fib_entry_t *fib_entry;
1427 
1428  fib_entry = fib_entry_get(fib_entry_index);
1429  fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths);
1430 }
1431 
1432 void
1434  fib_prefix_t *pfx)
1435 {
1436  fib_entry_t *fib_entry;
1437 
1438  fib_entry = fib_entry_get(fib_entry_index);
1439  *pfx = fib_entry->fe_prefix;
1440 }
1441 
1442 u32
1444 {
1445  fib_entry_t *fib_entry;
1446 
1447  fib_entry = fib_entry_get(fib_entry_index);
1448 
1449  return (fib_entry->fe_fib_index);
1450 }
1451 
1452 u32
1454 {
1455  return (pool_elts(fib_entry_pool));
1456 }
1457 
1458 static clib_error_t *
1460  unformat_input_t * input,
1461  vlib_cli_command_t * cmd)
1462 {
1463  fib_node_index_t fei;
1464 
1465  if (unformat (input, "%d", &fei))
1466  {
1467  /*
1468  * show one in detail
1469  */
1470  if (!pool_is_free_index(fib_entry_pool, fei))
1471  {
1472  vlib_cli_output (vm, "%d@%U",
1473  fei,
1474  format_fib_entry, fei,
1476  }
1477  else
1478  {
1479  vlib_cli_output (vm, "entry %d invalid", fei);
1480  }
1481  }
1482  else
1483  {
1484  /*
1485  * show all
1486  */
1487  vlib_cli_output (vm, "FIB Entries:");
1488  pool_foreach_index(fei, fib_entry_pool,
1489  ({
1490  vlib_cli_output (vm, "%d@%U",
1491  fei,
1492  format_fib_entry, fei,
1494  }));
1495  }
1496 
1497  return (NULL);
1498 }
1499 
1500 VLIB_CLI_COMMAND (show_fib_entry, static) = {
1501  .path = "show fib entry",
1502  .function = show_fib_entry_command,
1503  .short_help = "show fib entry",
1504 };
fib_entry_src_cover_res_t fib_entry_src_action_cover_change(fib_entry_t *fib_entry, fib_source_t source)
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:154
u8 * format_fib_entry(u8 *s, va_list *args)
Definition: fib_entry.c:93
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1443
#define FIB_ENTRY_DBG(_e, _fmt, _args...)
Debug macro.
Definition: fib_entry_src.h:42
void fib_entry_unlock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1407
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:85
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
An entry in a FIB table.
Definition: fib_entry.h:361
A representation of a fib path for fib_path_encode to convey the information to the caller...
Definition: fib_types.h:335
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
static const char * fib_attribute_names[]
Definition: fib_entry.c:36
fib_node_bw_reason_flag_t bw_reason
Definition: fib_entry_src.h:89
enum fib_node_type_t_ fib_node_type_t
The types of nodes in a FIB graph.
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:285
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:237
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:1459
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_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:183
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:472
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:852
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:789
#define FIB_ENTRY_FORMAT_DETAIL
Definition: fib_entry.h:416
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
void fib_entry_get_prefix(fib_node_index_t fib_entry_index, fib_prefix_t *pfx)
Definition: fib_entry.c:1433
static fib_entry_src_t * fib_entry_get_best_src_i(const fib_entry_t *fib_entry)
Definition: fib_entry.c:238
fib_node_index_t fib_entry_get_path_list(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:462
Definitions for all things IP (v4|v6) unicast and multicast lookup related.
#define NULL
Definition: clib.h:55
static fib_protocol_t fib_entry_get_proto(const fib_entry_t *fib_entry)
Definition: fib_entry.c:62
Information related to the source of a FIB entry.
Definition: fib_entry.h:270
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:902
Definition: fib_entry.h:222
static int fib_ip6_address_compare(const ip6_address_t *a1, const ip6_address_t *a2)
Definition: fib_entry.c:1337
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:391
void fib_entry_src_action_deactivate(fib_entry_t *fib_entry, fib_source_t source)
const dpo_id_t * fib_entry_contribute_ip_forwarding(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:432
enum fib_entry_delegate_type_t_ fib_entry_delegate_type_t
Delegate types.
void fib_entry_child_remove(fib_node_index_t fib_entry_index, u32 sibling_index)
Definition: fib_entry.c:483
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:221
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:482
Result from a cover update/change.
Definition: fib_entry_src.h:87
void fib_path_list_walk(fib_node_index_t path_list_index, fib_path_list_walk_fn_t func, void *ctx)
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:81
void fib_node_deinit(fib_node_t *node)
Definition: fib_node.c:198
u32 fib_entry_pool_size(void)
Definition: fib_entry.c:1453
void fib_entry_module_init(void)
Definition: fib_entry.c:1417
u32 fe_fib_index
The index of the FIB table this entry is in.
Definition: fib_entry.h:374
Definition: fib_entry.h:218
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
fib_entry_src_t * fe_srcs
Vector of source infos.
Definition: fib_entry.h:393
dpo_id_t fd_dpo
Valid for the forwarding chain delegates.
fib_node_index_t fe_parent
the path-list for which this entry is a child.
Definition: fib_entry.h:398
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:121
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:96
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:611
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:58
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:178
void fib_attached_export_purge(fib_entry_t *fib_entry)
All the imported entries need to be pruged.
static void fib_entry_source_change(fib_entry_t *fib_entry, fib_source_t best_source, fib_source_t new_source, fib_entry_flag_t old_flags)
Definition: fib_entry.c:705
#define FIB_ENTRY_ATTRIBUTES
Definition: fib_entry.h:201
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:767
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
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:674
#define DPO_PROTO_NONE
Definition: dpo.h:73
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:150
#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:145
fib_node_index_t fib_entry_get_index(const fib_entry_t *fib_entry)
Definition: fib_entry.c:56
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:375
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:221
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:289
u16 fp_len
The mask length.
Definition: fib_types.h:149
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:1388
u16 install
Definition: fib_entry_src.h:88
adj_index_t fib_entry_get_adj(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:447
Definition: fib_entry.h:216
#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:138
fib_node_bw_reason_flag_t fnbw_reason
The reason/trigger for the backwalk.
Definition: fib_node.h:190
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:258
#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
static int fib_ip4_address_compare(const ip4_address_t *a1, const ip4_address_t *a2)
Definition: fib_entry.c:1323
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)
struct fib_path_ext_t_ * fes_path_exts
A vector of path extensions.
Definition: fib_entry.h:274
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:168
#define FOR_EACH_DELEGATE_CHAIN(_entry, _fdt, _fed, _body)
void fib_node_lock(fib_node_t *node)
Definition: fib_node.c:204
u32 fib_entry_cover_get_size(fib_entry_t *cover)
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:214
fib_node_bw_flags_t fnbw_flags
additional flags for the walk
Definition: fib_node.h:195
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:1033
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:657
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:278
An node in the FIB graph.
Definition: fib_node.h:273
void fib_node_unlock(fib_node_t *node)
Definition: fib_node.c:210
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:576
const dpo_id_t * load_balance_get_bucket(index_t lbi, u32 bucket)
Definition: load_balance.c:271
#define FIB_SOURCE_MAX
The maximum number of sources.
Definition: fib_entry.h:130
#define FOR_EACH_FIB_ATTRIBUTE(_item)
Definition: fib_entry.h:210
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1301
u8 * format_fib_path_ext(u8 *s, va_list *args)
Definition: fib_path_ext.c:28
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:50
static void fib_entry_last_lock_gone(fib_node_t *node)
Definition: fib_entry.c:212
fib_node_list_t fn_children
Vector of nodes that depend upon/use/share this node.
Definition: fib_node.h:290
fib_entry_delegate_type_t fib_entry_chain_type_to_delegate_type(fib_forward_chain_type_t fct)
void fib_entry_src_action_installed(const fib_entry_t *fib_entry, fib_source_t source)
Definition: fib_entry.h:255
static fib_entry_t * fib_entry_from_fib_node(fib_node_t *node)
Definition: fib_entry.c:203
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
void fib_entry_src_action_activate(fib_entry_t *fib_entry, fib_source_t source)
u8 * fib_ae_export_format(fib_entry_t *fib_entry, u8 *s)
Force the walk to be synchronous.
Definition: fib_node.h:152
int fib_entry_recursive_loop_detect(fib_node_index_t entry_index, fib_node_index_t **entry_indicies)
Definition: fib_entry.c:1250
fib_node_get_t fnv_get
Definition: fib_node.h:261
int fib_path_encode(fib_node_index_t path_list_index, fib_node_index_t path_index, void *ctx)
Definition: fib_path.c:1900
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:211
u32 fib_node_get_n_children(fib_node_type_t parent_type, fib_node_index_t parent_index)
Definition: fib_node.c:140
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
#define ARRAY_LEN(x)
Definition: clib.h:59
fib_forward_chain_type_t fib_entry_delegate_type_to_chain_type(fib_entry_delegate_type_t fdt)
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:44
static void fib_entry_post_flag_update_actions(fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t old_flags)
Definition: fib_entry.c:555
u8 * fib_ae_import_format(fib_entry_t *fib_entry, u8 *s)
mpls_label_t fp_label
Definition: fib_types.h:171
Context passed between object during a back walk.
Definition: fib_node.h:186
void fib_entry_lock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1397
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
enum fib_entry_flag_t_ fib_entry_flag_t
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:299
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:283
fib_entry_src_cover_res_t fib_entry_src_action_cover_update(fib_entry_t *fib_entry, fib_source_t source)
#define ASSERT(truth)
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)
unsigned int u32
Definition: types.h:88
static void fib_entry_show_memory(void)
Definition: fib_entry.c:333
fib_node_t fe_node
Base class.
Definition: fib_entry.h:365
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:46
Definition: fib_entry.h:256
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:121
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:683
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:220
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:118
static fib_entry_t * fib_entry_pool
Definition: fib_entry.c:41
void fib_entry_cover_changed(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1112
void fib_entry_encode(fib_node_index_t fib_entry_index, fib_route_path_encode_t **api_rpaths)
Definition: fib_entry.c:1423
dpo_id_t fe_lb
The load-balance used for forwarding.
Definition: fib_entry.h:387
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:409
fib_node_index_t fes_pl
The path-list created by the source.
Definition: fib_entry.h:279
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:415
static fib_entry_flag_t fib_entry_src_get_flags(const fib_entry_src_t *esrc)
Definition: fib_entry.c:268
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:154
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:620
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:29
Marker.
Definition: fib_entry.h:34
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
u32 fn_locks
Number of dependents on this node.
Definition: fib_node.h:296
u8 * fib_path_list_format(fib_node_index_t path_list_index, u8 *s)
u8 * fib_entry_src_format(fib_entry_t *fib_entry, fib_source_t source, u8 *s)
void fib_entry_cover_updated(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1184
A FIB graph nodes virtual function table.
Definition: fib_node.h:260
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:1045
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
#define FIB_ENTRY_FORMAT_DETAIL2
Definition: fib_entry.h:417
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:191
#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:32
u8 fes_ref_count
1 bytes ref count.
Definition: fib_entry.h:294
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:90
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:1352
struct _unformat_input_t unformat_input_t
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:390
u32 flags
Definition: vhost-user.h:75
u8 * fib_node_children_format(fib_node_list_t list, u8 *s)
Definition: fib_node.c:174
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:513
fib_source_t fib_entry_get_best_source(fib_node_index_t entry_index)
Definition: fib_entry.c:1311
fib_entry_delegate_t * fib_entry_delegate_find_or_add(fib_entry_t *fib_entry, fib_entry_delegate_type_t fdt)
fib_forward_chain_type_t fib_forw_chain_type_from_dpo_proto(dpo_proto_t proto)
Convert from a payload-protocol to a chain type.
Definition: fib_types.c:270
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:746
fib_forward_chain_type_t fib_entry_get_default_chain_type(const fib_entry_t *fib_entry)
Definition: fib_entry.c:68
const fib_prefix_t fe_prefix
The prefix of the route.
Definition: fib_entry.h:370
fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry.c:947
u8 * fib_entry_cover_list_format(fib_entry_t *fib_entry, u8 *s)
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:132
mpls_eos_bit_t fp_eos
Definition: fib_types.h:172
fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:278
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109