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