FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
fib_path.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/vnet.h>
18 #include <vnet/ip/format.h>
19 #include <vnet/ip/ip.h>
20 #include <vnet/dpo/drop_dpo.h>
21 #include <vnet/dpo/receive_dpo.h>
23 #include <vnet/dpo/lookup_dpo.h>
26 #include <vnet/dpo/dvr_dpo.h>
27 #include <vnet/dpo/ip_null_dpo.h>
28 #include <vnet/dpo/classify_dpo.h>
29 #include <vnet/dpo/pw_cw.h>
30 
31 #include <vnet/adj/adj.h>
32 #include <vnet/adj/adj_mcast.h>
33 
34 #include <vnet/fib/fib_path.h>
35 #include <vnet/fib/fib_node.h>
36 #include <vnet/fib/fib_table.h>
37 #include <vnet/fib/fib_entry.h>
38 #include <vnet/fib/fib_path_list.h>
39 #include <vnet/fib/fib_internal.h>
40 #include <vnet/fib/fib_urpf_list.h>
41 #include <vnet/fib/mpls_fib.h>
42 #include <vnet/fib/fib_path_ext.h>
43 #include <vnet/udp/udp_encap.h>
44 #include <vnet/bier/bier_fmask.h>
45 #include <vnet/bier/bier_table.h>
46 #include <vnet/bier/bier_imp.h>
48 
49 /**
50  * Enurmeration of path types
51  */
52 typedef enum fib_path_type_t_ {
53  /**
54  * Marker. Add new types after this one.
55  */
57  /**
58  * Attached-nexthop. An interface and a nexthop are known.
59  */
61  /**
62  * attached. Only the interface is known.
63  */
65  /**
66  * recursive. Only the next-hop is known.
67  */
69  /**
70  * special. nothing is known. so we drop.
71  */
73  /**
74  * exclusive. user provided adj.
75  */
77  /**
78  * deag. Link to a lookup adj in the next table
79  */
81  /**
82  * interface receive.
83  */
85  /**
86  * Path resolves via a UDP encap object.
87  */
89  /**
90  * receive. it's for-us.
91  */
93  /**
94  * bier-imp. it's via a BIER imposition.
95  */
97  /**
98  * bier-fmask. it's via a BIER ECMP-table.
99  */
101  /**
102  * bier-fmask. it's via a BIER f-mask.
103  */
105  /**
106  * via a DVR.
107  */
109  /**
110  * Marker. Add new types before this one, then update it.
111  */
113 } __attribute__ ((packed)) fib_path_type_t;
114 
115 /**
116  * The maximum number of path_types
117  */
118 #define FIB_PATH_TYPE_MAX (FIB_PATH_TYPE_LAST + 1)
119 
120 #define FIB_PATH_TYPES { \
121  [FIB_PATH_TYPE_ATTACHED_NEXT_HOP] = "attached-nexthop", \
122  [FIB_PATH_TYPE_ATTACHED] = "attached", \
123  [FIB_PATH_TYPE_RECURSIVE] = "recursive", \
124  [FIB_PATH_TYPE_SPECIAL] = "special", \
125  [FIB_PATH_TYPE_EXCLUSIVE] = "exclusive", \
126  [FIB_PATH_TYPE_DEAG] = "deag", \
127  [FIB_PATH_TYPE_INTF_RX] = "intf-rx", \
128  [FIB_PATH_TYPE_UDP_ENCAP] = "udp-encap", \
129  [FIB_PATH_TYPE_RECEIVE] = "receive", \
130  [FIB_PATH_TYPE_BIER_IMP] = "bier-imp", \
131  [FIB_PATH_TYPE_BIER_TABLE] = "bier-table", \
132  [FIB_PATH_TYPE_BIER_FMASK] = "bier-fmask", \
133  [FIB_PATH_TYPE_DVR] = "dvr", \
134 }
135 
136 #define FOR_EACH_FIB_PATH_TYPE(_item) \
137  for (_item = FIB_PATH_TYPE_FIRST; \
138  _item <= FIB_PATH_TYPE_LAST; \
139  _item++)
140 
141 /**
142  * Enurmeration of path operational (i.e. derived) attributes
143  */
145  /**
146  * Marker. Add new types after this one.
147  */
149  /**
150  * The path forms part of a recursive loop.
151  */
153  /**
154  * The path is resolved
155  */
157  /**
158  * The path is attached, despite what the next-hop may say.
159  */
161  /**
162  * The path has become a permanent drop.
163  */
165  /**
166  * Marker. Add new types before this one, then update it.
167  */
169 } __attribute__ ((packed)) fib_path_oper_attribute_t;
170 
171 /**
172  * The maximum number of path operational attributes
173  */
174 #define FIB_PATH_OPER_ATTRIBUTE_MAX (FIB_PATH_OPER_ATTRIBUTE_LAST + 1)
175 
176 #define FIB_PATH_OPER_ATTRIBUTES { \
177  [FIB_PATH_OPER_ATTRIBUTE_RECURSIVE_LOOP] = "recursive-loop", \
178  [FIB_PATH_OPER_ATTRIBUTE_RESOLVED] = "resolved", \
179  [FIB_PATH_OPER_ATTRIBUTE_DROP] = "drop", \
180 }
181 
182 #define FOR_EACH_FIB_PATH_OPER_ATTRIBUTE(_item) \
183  for (_item = FIB_PATH_OPER_ATTRIBUTE_FIRST; \
184  _item <= FIB_PATH_OPER_ATTRIBUTE_LAST; \
185  _item++)
186 
187 /**
188  * Path flags from the attributes
189  */
196 } __attribute__ ((packed)) fib_path_oper_flags_t;
197 
198 /**
199  * A FIB path
200  */
201 typedef struct fib_path_t_ {
202  /**
203  * A path is a node in the FIB graph.
204  */
206 
207  /**
208  * The index of the path-list to which this path belongs
209  */
211 
212  /**
213  * This marks the start of the memory area used to hash
214  * the path
215  */
216  STRUCT_MARK(path_hash_start);
217 
218  /**
219  * Configuration Flags
220  */
222 
223  /**
224  * The type of the path. This is the selector for the union
225  */
226  fib_path_type_t fp_type;
227 
228  /**
229  * The protocol of the next-hop, i.e. the address family of the
230  * next-hop's address. We can't derive this from the address itself
231  * since the address can be all zeros
232  */
234 
235  /**
236  * UCMP [unnormalised] weigth
237  */
239 
240  /**
241  * A path preference. 0 is the best.
242  * Only paths of the best preference, that are 'up', are considered
243  * for forwarding.
244  */
246 
247  /**
248  * per-type union of the data required to resolve the path
249  */
250  union {
251  struct {
252  /**
253  * The next-hop
254  */
255  ip46_address_t fp_nh;
256  /**
257  * The interface
258  */
261  struct {
262  /**
263  * The interface
264  */
266  } attached;
267  struct {
268  union
269  {
270  /**
271  * The next-hop
272  */
273  ip46_address_t fp_ip;
274  struct {
275  /**
276  * The local label to resolve through.
277  */
279  /**
280  * The EOS bit of the resolving label
281  */
283  };
284  } fp_nh;
285  union {
286  /**
287  * The FIB table index in which to find the next-hop.
288  */
290  /**
291  * The BIER FIB the fmask is in
292  */
294  };
295  } recursive;
296  struct {
297  /**
298  * BIER FMask ID
299  */
301  } bier_fmask;
302  struct {
303  /**
304  * The BIER table's ID
305  */
307  } bier_table;
308  struct {
309  /**
310  * The BIER imposition object
311  * this is part of the path's key, since the index_t
312  * of an imposition object is the object's key.
313  */
315  } bier_imp;
316  struct {
317  /**
318  * The FIB index in which to perfom the next lookup
319  */
321  /**
322  * The RPF-ID to tag the packets with
323  */
325  } deag;
326  struct {
327  } special;
328  struct {
329  /**
330  * The user provided 'exclusive' DPO
331  */
333  } exclusive;
334  struct {
335  /**
336  * The interface on which the local address is configured
337  */
339  /**
340  * The next-hop
341  */
342  ip46_address_t fp_addr;
343  } receive;
344  struct {
345  /**
346  * The interface on which the packets will be input.
347  */
349  } intf_rx;
350  struct {
351  /**
352  * The UDP Encap object this path resolves through
353  */
355  } udp_encap;
356  struct {
357  /**
358  * The UDP Encap object this path resolves through
359  */
361  } classify;
362  struct {
363  /**
364  * The interface
365  */
367  } dvr;
368  };
369  STRUCT_MARK(path_hash_end);
370 
371  /**
372  * Memebers in this last section represent information that is
373  * dervied during resolution. It should not be copied to new paths
374  * nor compared.
375  */
376 
377  /**
378  * Operational Flags
379  */
381 
382  union {
383  /**
384  * the resolving via fib. not part of the union, since it it not part
385  * of the path's hash.
386  */
388  /**
389  * the resolving bier-table
390  */
392  /**
393  * the resolving bier-fmask
394  */
396  };
397 
398  /**
399  * The Data-path objects through which this path resolves for IP.
400  */
402 
403  /**
404  * the index of this path in the parent's child list.
405  */
407 } fib_path_t;
408 
409 /*
410  * Array of strings/names for the path types and attributes
411  */
412 static const char *fib_path_type_names[] = FIB_PATH_TYPES;
413 static const char *fib_path_oper_attribute_names[] = FIB_PATH_OPER_ATTRIBUTES;
414 static const char *fib_path_cfg_attribute_names[] = FIB_PATH_CFG_ATTRIBUTES;
415 
416 /*
417  * The memory pool from which we allocate all the paths
418  */
420 
421 /**
422  * the logger
423  */
425 
426 /*
427  * Debug macro
428  */
429 #define FIB_PATH_DBG(_p, _fmt, _args...) \
430 { \
431  vlib_log_debug (fib_path_logger, \
432  "[%U]: " _fmt, \
433  format_fib_path, fib_path_get_index(_p), 0, \
434  FIB_PATH_FORMAT_FLAGS_ONE_LINE, \
435  ##_args); \
436 }
437 
438 static fib_path_t *
440 {
441  return (pool_elt_at_index(fib_path_pool, index));
442 }
443 
444 static fib_node_index_t
446 {
447  return (path - fib_path_pool);
448 }
449 
450 static fib_node_t *
452 {
453  return ((fib_node_t*)fib_path_get(index));
454 }
455 
456 static fib_path_t*
458 {
460  return ((fib_path_t*)node);
461 }
462 
463 u8 *
464 format_fib_path (u8 * s, va_list * args)
465 {
466  fib_node_index_t path_index = va_arg (*args, fib_node_index_t);
467  u32 indent = va_arg (*args, u32);
469  vnet_main_t * vnm = vnet_get_main();
470  fib_path_oper_attribute_t oattr;
472  fib_path_t *path;
473  const char *eol;
474 
475  if (flags & FIB_PATH_FORMAT_FLAGS_ONE_LINE)
476  {
477  eol = "";
478  }
479  else
480  {
481  eol = "\n";
482  }
483 
484  path = fib_path_get(path_index);
485 
486  s = format (s, "%Upath:[%d] ", format_white_space, indent,
487  fib_path_get_index(path));
488  s = format (s, "pl-index:%d ", path->fp_pl_index);
489  s = format (s, "%U ", format_dpo_proto, path->fp_nh_proto);
490  s = format (s, "weight=%d ", path->fp_weight);
491  s = format (s, "pref=%d ", path->fp_preference);
492  s = format (s, "%s: ", fib_path_type_names[path->fp_type]);
493  if (FIB_PATH_OPER_FLAG_NONE != path->fp_oper_flags) {
494  s = format(s, " oper-flags:");
496  if ((1<<oattr) & path->fp_oper_flags) {
497  s = format (s, "%s,", fib_path_oper_attribute_names[oattr]);
498  }
499  }
500  }
501  if (FIB_PATH_CFG_FLAG_NONE != path->fp_cfg_flags) {
502  s = format(s, " cfg-flags:");
504  if ((1<<cattr) & path->fp_cfg_flags) {
505  s = format (s, "%s,", fib_path_cfg_attribute_names[cattr]);
506  }
507  }
508  }
509  if (!(flags & FIB_PATH_FORMAT_FLAGS_ONE_LINE))
510  s = format(s, "\n%U", format_white_space, indent+2);
511 
512  switch (path->fp_type)
513  {
515  s = format (s, "%U", format_ip46_address,
516  &path->attached_next_hop.fp_nh,
517  IP46_TYPE_ANY);
519  {
520  s = format (s, " if_index:%d", path->attached_next_hop.fp_interface);
521  }
522  else
523  {
524  s = format (s, " %U",
526  vnm,
528  vnm,
529  path->attached_next_hop.fp_interface));
531  path->attached_next_hop.fp_interface))
532  {
533  s = format (s, " (p2p)");
534  }
535  }
536  if (!dpo_id_is_valid(&path->fp_dpo))
537  {
538  s = format(s, "%s%Uunresolved", eol, format_white_space, indent+2);
539  }
540  else
541  {
542  s = format(s, "%s%U%U", eol,
543  format_white_space, indent,
545  &path->fp_dpo, 13);
546  }
547  break;
550  {
551  s = format (s, "if_index:%d", path->attached_next_hop.fp_interface);
552  }
553  else
554  {
555  s = format (s, " %U",
557  vnm,
559  vnm,
560  path->attached.fp_interface));
561  }
562  break;
564  if (DPO_PROTO_MPLS == path->fp_nh_proto)
565  {
566  s = format (s, "via %U %U",
568  path->recursive.fp_nh.fp_local_label,
570  path->recursive.fp_nh.fp_eos);
571  }
572  else
573  {
574  s = format (s, "via %U",
576  &path->recursive.fp_nh.fp_ip,
577  IP46_TYPE_ANY);
578  }
579  s = format (s, " in fib:%d",
580  path->recursive.fp_tbl_id,
581  path->fp_via_fib);
582  s = format (s, " via-fib:%d", path->fp_via_fib);
583  s = format (s, " via-dpo:[%U:%d]",
585  path->fp_dpo.dpoi_index);
586 
587  break;
589  s = format (s, "UDP-encap ID:%d", path->udp_encap.fp_udp_encap_id);
590  break;
592  s = format (s, "via bier-table:[%U}",
594  &path->bier_table.fp_bier_tbl);
595  s = format (s, " via-dpo:[%U:%d]",
597  path->fp_dpo.dpoi_index);
598  break;
600  s = format (s, "via-fmask:%d", path->bier_fmask.fp_bier_fmask);
601  s = format (s, " via-dpo:[%U:%d]",
603  path->fp_dpo.dpoi_index);
604  break;
606  s = format (s, "via %U", format_bier_imp,
607  path->bier_imp.fp_bier_imp, 0, BIER_SHOW_BRIEF);
608  break;
609  case FIB_PATH_TYPE_DVR:
610  s = format (s, " %U",
612  vnm,
614  vnm,
615  path->dvr.fp_interface));
616  break;
617  case FIB_PATH_TYPE_DEAG:
618  s = format (s, " %sfib-index:%d",
619  (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ? "m" : ""),
620  path->deag.fp_tbl_id);
621  break;
626  if (dpo_id_is_valid(&path->fp_dpo))
627  {
628  s = format(s, "%U", format_dpo_id,
629  &path->fp_dpo, indent+2);
630  }
631  break;
632  }
633  return (s);
634 }
635 
636 /*
637  * fib_path_last_lock_gone
638  *
639  * We don't share paths, we share path lists, so the [un]lock functions
640  * are no-ops
641  */
642 static void
644 {
645  ASSERT(0);
646 }
647 
648 static fib_path_t*
650  vnet_link_t link,
651  dpo_id_t *dpo)
652 {
653  fib_node_index_t fib_path_index;
654  fib_protocol_t nh_proto;
655  adj_index_t ai;
656 
657  fib_path_index = fib_path_get_index(path);
658  nh_proto = dpo_proto_to_fib(path->fp_nh_proto);
659 
661  path->attached_next_hop.fp_interface))
662  {
663  /*
664  * if the interface is p2p then the adj for the specific
665  * neighbour on that link will never exist. on p2p links
666  * the subnet address (the attached route) links to the
667  * auto-adj (see below), we want that adj here too.
668  */
669  ai = adj_nbr_add_or_lock(nh_proto, link, &zero_addr,
670  path->attached_next_hop.fp_interface);
671  }
672  else
673  {
674  ai = adj_nbr_add_or_lock(nh_proto, link,
675  &path->attached_next_hop.fp_nh,
676  path->attached_next_hop.fp_interface);
677  }
678 
680  adj_unlock(ai);
681 
682  return (fib_path_get(fib_path_index));
683 }
684 
685 static void
687 {
688  /*
689  * resolve directly via the adjacency discribed by the
690  * interface and next-hop
691  */
694  &path->fp_dpo);
695 
696  ASSERT(dpo_is_adj(&path->fp_dpo));
697 
698  /*
699  * become a child of the adjacency so we receive updates
700  * when its rewrite changes
701  */
704  fib_path_get_index(path));
705 
707  path->attached_next_hop.fp_interface) ||
708  !adj_is_up(path->fp_dpo.dpoi_index))
709  {
711  }
712 }
713 
714 static void
716  vnet_link_t link,
717  dpo_id_t *dpo)
718 {
719  fib_protocol_t nh_proto;
720 
721  nh_proto = dpo_proto_to_fib(path->fp_nh_proto);
722 
724  path->attached.fp_interface))
725  {
726  /*
727  * point-2-point interfaces do not require a glean, since
728  * there is nothing to ARP. Install a rewrite/nbr adj instead
729  */
730  adj_index_t ai;
731 
732  ai = adj_nbr_add_or_lock(nh_proto, link, &zero_addr,
733  path->attached.fp_interface);
734 
736  adj_unlock(ai);
737  }
739  path->attached.fp_interface))
740  {
741  dpo_copy(dpo, drop_dpo_get(path->fp_nh_proto));
742  }
743  else
744  {
745  adj_index_t ai;
746 
747  ai = adj_glean_add_or_lock(nh_proto, link,
748  path->attached.fp_interface,
749  NULL);
751  adj_unlock(ai);
752  }
753 }
754 
755 /*
756  * create of update the paths recursive adj
757  */
758 static void
761  dpo_id_t *dpo)
762 {
763  dpo_id_t via_dpo = DPO_INVALID;
764 
765  /*
766  * get the DPO to resolve through from the via-entry
767  */
769  fct,
770  &via_dpo);
771 
772 
773  /*
774  * hope for the best - clear if restrictions apply.
775  */
777 
778  /*
779  * Validate any recursion constraints and over-ride the via
780  * adj if not met
781  */
783  {
785  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
786  }
788  {
789  /*
790  * the via FIB must be a host route.
791  * note the via FIB just added will always be a host route
792  * since it is an RR source added host route. So what we need to
793  * check is whether the route has other sources. If it does then
794  * some other source has added it as a host route. If it doesn't
795  * then it was added only here and inherits forwarding from a cover.
796  * the cover is not a host route.
797  * The RR source is the lowest priority source, so we check if it
798  * is the best. if it is there are no other sources.
799  */
801  {
803  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
804 
805  /*
806  * PIC edge trigger. let the load-balance maps know
807  */
809  }
810  }
812  {
813  /*
814  * RR source entries inherit the flags from the cover, so
815  * we can check the via directly
816  */
818  {
820  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
821 
822  /*
823  * PIC edge trigger. let the load-balance maps know
824  */
826  }
827  }
828  /*
829  * check for over-riding factors on the FIB entry itself
830  */
831  if (!fib_entry_is_resolved(path->fp_via_fib))
832  {
834  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
835 
836  /*
837  * PIC edge trigger. let the load-balance maps know
838  */
840  }
841 
842  /*
843  * If this path is contributing a drop, then it's not resolved
844  */
845  if (dpo_is_drop(&via_dpo) || load_balance_is_drop(&via_dpo))
846  {
848  }
849 
850  /*
851  * update the path's contributed DPO
852  */
853  dpo_copy(dpo, &via_dpo);
854 
855  FIB_PATH_DBG(path, "recursive update:");
856 
857  dpo_reset(&via_dpo);
858 }
859 
860 /*
861  * re-evaulate the forwarding state for a via fmask path
862  */
863 static void
865  dpo_id_t *dpo)
866 {
867  bier_fmask_contribute_forwarding(path->bier_fmask.fp_bier_fmask, dpo);
868 
869  /*
870  * if we are stakcing on the drop, then the path is not resolved
871  */
872  if (dpo_is_drop(dpo))
873  {
875  }
876  else
877  {
879  }
880 }
881 
882 /*
883  * fib_path_is_permanent_drop
884  *
885  * Return !0 if the path is configured to permanently drop,
886  * despite other attributes.
887  */
888 static int
890 {
891  return ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DROP) ||
893 }
894 
895 /*
896  * fib_path_unresolve
897  *
898  * Remove our dependency on the resolution target
899  */
900 static void
902 {
903  /*
904  * the forced drop path does not need unresolving
905  */
906  if (fib_path_is_permanent_drop(path))
907  {
908  return;
909  }
910 
911  switch (path->fp_type)
912  {
914  if (FIB_NODE_INDEX_INVALID != path->fp_via_fib)
915  {
917  path->fp_sibling);
920  FIB_SOURCE_RR);
921  fib_table_unlock(path->recursive.fp_tbl_id,
923  FIB_SOURCE_RR);
925  }
926  break;
929  path->fp_sibling);
930  break;
933  break;
936  break;
939  if (dpo_is_adj(&path->fp_dpo))
941  path->fp_sibling);
942  break;
945  break;
947  dpo_reset(&path->exclusive.fp_ex_dpo);
948  break;
952  case FIB_PATH_TYPE_DEAG:
953  case FIB_PATH_TYPE_DVR:
954  /*
955  * these hold only the path's DPO, which is reset below.
956  */
957  break;
958  }
959 
960  /*
961  * release the adj we were holding and pick up the
962  * drop just in case.
963  */
964  dpo_reset(&path->fp_dpo);
966 
967  return;
968 }
969 
972 {
973  if (DPO_PROTO_MPLS == path->fp_nh_proto)
974  {
975  if (FIB_PATH_TYPE_RECURSIVE == path->fp_type &&
976  MPLS_EOS == path->recursive.fp_nh.fp_eos)
977  {
979  }
980  else
981  {
983  }
984  }
985  else
986  {
988  }
989 }
990 
991 /*
992  * fib_path_back_walk_notify
993  *
994  * A back walk has reach this path.
995  */
999 {
1000  fib_path_t *path;
1001 
1002  path = fib_path_from_fib_node(node);
1003 
1004  FIB_PATH_DBG(path, "bw:%U",
1006 
1007  switch (path->fp_type)
1008  {
1011  {
1012  /*
1013  * modify the recursive adjacency to use the new forwarding
1014  * of the via-fib.
1015  * this update is visible to packets in flight in the DP.
1016  */
1018  path,
1019  fib_path_to_chain_type(path),
1020  &path->fp_dpo);
1021  }
1024  {
1025  /*
1026  * ADJ updates (complete<->incomplete) do not need to propagate to
1027  * recursive entries.
1028  * The only reason its needed as far back as here, is that the adj
1029  * and the incomplete adj are a different DPO type, so the LBs need
1030  * to re-stack.
1031  * If this walk was quashed in the fib_entry, then any non-fib_path
1032  * children (like tunnels that collapse out the LB when they stack)
1033  * would not see the update.
1034  */
1035  return (FIB_NODE_BACK_WALK_CONTINUE);
1036  }
1037  break;
1040  {
1041  /*
1042  * update to use the BIER fmask's new forwading
1043  */
1044  fib_path_bier_fmask_update(path, &path->fp_dpo);
1045  }
1048  {
1049  /*
1050  * ADJ updates (complete<->incomplete) do not need to propagate to
1051  * recursive entries.
1052  * The only reason its needed as far back as here, is that the adj
1053  * and the incomplete adj are a different DPO type, so the LBs need
1054  * to re-stack.
1055  * If this walk was quashed in the fib_entry, then any non-fib_path
1056  * children (like tunnels that collapse out the LB when they stack)
1057  * would not see the update.
1058  */
1059  return (FIB_NODE_BACK_WALK_CONTINUE);
1060  }
1061  break;
1063  /*
1064 FIXME comment
1065  * ADJ_UPDATE backwalk pass silently through here and up to
1066  * the path-list when the multipath adj collapse occurs.
1067  * The reason we do this is that the assumtption is that VPP
1068  * runs in an environment where the Control-Plane is remote
1069  * and hence reacts slowly to link up down. In order to remove
1070  * this down link from the ECMP set quickly, we back-walk.
1071  * VPP also has dedicated CPUs, so we are not stealing resources
1072  * from the CP to do so.
1073  */
1075  {
1077  {
1078  /*
1079  * alreday resolved. no need to walk back again
1080  */
1081  return (FIB_NODE_BACK_WALK_CONTINUE);
1082  }
1084  }
1086  {
1088  {
1089  /*
1090  * alreday unresolved. no need to walk back again
1091  */
1092  return (FIB_NODE_BACK_WALK_CONTINUE);
1093  }
1095  }
1097  {
1098  /*
1099  * The interface this path resolves through has been deleted.
1100  * This will leave the path in a permanent drop state. The route
1101  * needs to be removed and readded (and hence the path-list deleted)
1102  * before it can forward again.
1103  */
1104  fib_path_unresolve(path);
1106  }
1108  {
1109  /*
1110  * restack the DPO to pick up the correct DPO sub-type
1111  */
1112  uword if_is_up;
1113 
1114  if_is_up = vnet_sw_interface_is_up(
1115  vnet_get_main(),
1116  path->attached_next_hop.fp_interface);
1117 
1119  path,
1121  &path->fp_dpo);
1122 
1124  if (if_is_up && adj_is_up(path->fp_dpo.dpoi_index))
1125  {
1127  }
1128 
1129  if (!if_is_up)
1130  {
1131  /*
1132  * If the interface is not up there is no reason to walk
1133  * back to children. if we did they would only evalute
1134  * that this path is unresolved and hence it would
1135  * not contribute the adjacency - so it would be wasted
1136  * CPU time.
1137  */
1138  return (FIB_NODE_BACK_WALK_CONTINUE);
1139  }
1140  }
1142  {
1144  {
1145  /*
1146  * alreday unresolved. no need to walk back again
1147  */
1148  return (FIB_NODE_BACK_WALK_CONTINUE);
1149  }
1150  /*
1151  * the adj has gone down. the path is no longer resolved.
1152  */
1154  }
1155  break;
1157  case FIB_PATH_TYPE_DVR:
1158  /*
1159  * FIXME; this could schedule a lower priority walk, since attached
1160  * routes are not usually in ECMP configurations so the backwalk to
1161  * the FIB entry does not need to be high priority
1162  */
1164  {
1166  }
1168  {
1170  }
1172  {
1173  fib_path_unresolve(path);
1175  }
1176  break;
1178  {
1179  dpo_id_t via_dpo = DPO_INVALID;
1180 
1181  /*
1182  * hope for the best - clear if restrictions apply.
1183  */
1185 
1186  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
1187  path->fp_nh_proto,
1188  &via_dpo);
1189  /*
1190  * If this path is contributing a drop, then it's not resolved
1191  */
1192  if (dpo_is_drop(&via_dpo) || load_balance_is_drop(&via_dpo))
1193  {
1195  }
1196 
1197  /*
1198  * update the path's contributed DPO
1199  */
1200  dpo_copy(&path->fp_dpo, &via_dpo);
1201  dpo_reset(&via_dpo);
1202  break;
1203  }
1204  case FIB_PATH_TYPE_INTF_RX:
1205  ASSERT(0);
1206  case FIB_PATH_TYPE_DEAG:
1207  /*
1208  * FIXME When VRF delete is allowed this will need a poke.
1209  */
1210  case FIB_PATH_TYPE_SPECIAL:
1211  case FIB_PATH_TYPE_RECEIVE:
1215  /*
1216  * these path types have no parents. so to be
1217  * walked from one is unexpected.
1218  */
1219  ASSERT(0);
1220  break;
1221  }
1222 
1223  /*
1224  * propagate the backwalk further to the path-list
1225  */
1227 
1228  return (FIB_NODE_BACK_WALK_CONTINUE);
1229 }
1230 
1231 static void
1233 {
1234  fib_show_memory_usage("Path",
1235  pool_elts(fib_path_pool),
1236  pool_len(fib_path_pool),
1237  sizeof(fib_path_t));
1238 }
1239 
1240 /*
1241  * The FIB path's graph node virtual function table
1242  */
1243 static const fib_node_vft_t fib_path_vft = {
1245  .fnv_last_lock = fib_path_last_lock_gone,
1246  .fnv_back_walk = fib_path_back_walk_notify,
1247  .fnv_mem_show = fib_path_memory_show,
1248 };
1249 
1250 static fib_path_cfg_flags_t
1252 {
1254 
1255  if (rpath->frp_flags & FIB_ROUTE_PATH_POP_PW_CW)
1256  cfg_flags |= FIB_PATH_CFG_FLAG_POP_PW_CW;
1258  cfg_flags |= FIB_PATH_CFG_FLAG_RESOLVE_HOST;
1261  if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
1262  cfg_flags |= FIB_PATH_CFG_FLAG_LOCAL;
1263  if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED)
1264  cfg_flags |= FIB_PATH_CFG_FLAG_ATTACHED;
1265  if (rpath->frp_flags & FIB_ROUTE_PATH_INTF_RX)
1266  cfg_flags |= FIB_PATH_CFG_FLAG_INTF_RX;
1267  if (rpath->frp_flags & FIB_ROUTE_PATH_RPF_ID)
1268  cfg_flags |= FIB_PATH_CFG_FLAG_RPF_ID;
1269  if (rpath->frp_flags & FIB_ROUTE_PATH_EXCLUSIVE)
1270  cfg_flags |= FIB_PATH_CFG_FLAG_EXCLUSIVE;
1271  if (rpath->frp_flags & FIB_ROUTE_PATH_DROP)
1272  cfg_flags |= FIB_PATH_CFG_FLAG_DROP;
1274  cfg_flags |= FIB_PATH_CFG_FLAG_DEAG_SRC;
1276  cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_UNREACH;
1278  cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_PROHIBIT;
1279 
1280  return (cfg_flags);
1281 }
1282 
1283 /*
1284  * fib_path_create
1285  *
1286  * Create and initialise a new path object.
1287  * return the index of the path.
1288  */
1291  const fib_route_path_t *rpath)
1292 {
1293  fib_path_t *path;
1294 
1295  pool_get(fib_path_pool, path);
1296  clib_memset(path, 0, sizeof(*path));
1297 
1298  fib_node_init(&path->fp_node,
1300 
1301  dpo_reset(&path->fp_dpo);
1302  path->fp_pl_index = pl_index;
1303  path->fp_nh_proto = rpath->frp_proto;
1305  path->fp_weight = rpath->frp_weight;
1306  if (0 == path->fp_weight)
1307  {
1308  /*
1309  * a weight of 0 is a meaningless value. We could either reject it, and thus force
1310  * clients to always use 1, or we can accept it and fixup approrpiately.
1311  */
1312  path->fp_weight = 1;
1313  }
1314  path->fp_preference = rpath->frp_preference;
1316 
1317  /*
1318  * deduce the path's tpye from the parementers and save what is needed.
1319  */
1321  {
1323  path->receive.fp_interface = rpath->frp_sw_if_index;
1324  path->receive.fp_addr = rpath->frp_addr;
1325  }
1326  else if (rpath->frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
1327  {
1329  path->udp_encap.fp_udp_encap_id = rpath->frp_udp_encap_id;
1330  }
1331  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_INTF_RX)
1332  {
1334  path->intf_rx.fp_interface = rpath->frp_sw_if_index;
1335  }
1336  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID)
1337  {
1338  path->fp_type = FIB_PATH_TYPE_DEAG;
1339  path->deag.fp_tbl_id = rpath->frp_fib_index;
1340  path->deag.fp_rpf_id = rpath->frp_rpf_id;
1341  }
1342  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_FMASK)
1343  {
1345  path->bier_fmask.fp_bier_fmask = rpath->frp_bier_fmask;
1346  }
1347  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_IMP)
1348  {
1350  path->bier_imp.fp_bier_imp = rpath->frp_bier_imp;
1351  }
1352  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_TABLE)
1353  {
1355  path->bier_table.fp_bier_tbl = rpath->frp_bier_tbl;
1356  }
1357  else if (rpath->frp_flags & FIB_ROUTE_PATH_DEAG)
1358  {
1359  path->fp_type = FIB_PATH_TYPE_DEAG;
1360  path->deag.fp_tbl_id = rpath->frp_fib_index;
1361  }
1362  else if (rpath->frp_flags & FIB_ROUTE_PATH_DVR)
1363  {
1364  path->fp_type = FIB_PATH_TYPE_DVR;
1365  path->dvr.fp_interface = rpath->frp_sw_if_index;
1366  }
1367  else if (rpath->frp_flags & FIB_ROUTE_PATH_EXCLUSIVE)
1368  {
1370  dpo_copy(&path->exclusive.fp_ex_dpo, &rpath->dpo);
1371  }
1372  else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT) ||
1374  {
1376  }
1377  else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY))
1378  {
1380  path->classify.fp_classify_table_id = rpath->frp_classify_table_id;
1381  }
1382  else if (~0 != rpath->frp_sw_if_index)
1383  {
1384  if (ip46_address_is_zero(&rpath->frp_addr))
1385  {
1387  path->attached.fp_interface = rpath->frp_sw_if_index;
1388  }
1389  else
1390  {
1392  path->attached_next_hop.fp_interface = rpath->frp_sw_if_index;
1393  path->attached_next_hop.fp_nh = rpath->frp_addr;
1394  }
1395  }
1396  else
1397  {
1398  if (ip46_address_is_zero(&rpath->frp_addr))
1399  {
1400  if (~0 == rpath->frp_fib_index)
1401  {
1403  }
1404  else
1405  {
1406  path->fp_type = FIB_PATH_TYPE_DEAG;
1407  path->deag.fp_tbl_id = rpath->frp_fib_index;
1408  path->deag.fp_rpf_id = ~0;
1409  }
1410  }
1411  else
1412  {
1414  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1415  {
1416  path->recursive.fp_nh.fp_local_label = rpath->frp_local_label;
1417  path->recursive.fp_nh.fp_eos = rpath->frp_eos;
1418  }
1419  else
1420  {
1421  path->recursive.fp_nh.fp_ip = rpath->frp_addr;
1422  }
1423  path->recursive.fp_tbl_id = rpath->frp_fib_index;
1424  }
1425  }
1426 
1427  FIB_PATH_DBG(path, "create");
1428 
1429  return (fib_path_get_index(path));
1430 }
1431 
1432 /*
1433  * fib_path_create_special
1434  *
1435  * Create and initialise a new path object.
1436  * return the index of the path.
1437  */
1440  dpo_proto_t nh_proto,
1442  const dpo_id_t *dpo)
1443 {
1444  fib_path_t *path;
1445 
1446  pool_get(fib_path_pool, path);
1447  clib_memset(path, 0, sizeof(*path));
1448 
1449  fib_node_init(&path->fp_node,
1451  dpo_reset(&path->fp_dpo);
1452 
1453  path->fp_pl_index = pl_index;
1454  path->fp_weight = 1;
1455  path->fp_preference = 0;
1456  path->fp_nh_proto = nh_proto;
1458  path->fp_cfg_flags = flags;
1459 
1460  if (FIB_PATH_CFG_FLAG_DROP & flags)
1461  {
1463  }
1464  else if (FIB_PATH_CFG_FLAG_LOCAL & flags)
1465  {
1467  path->attached.fp_interface = FIB_NODE_INDEX_INVALID;
1468  }
1469  else
1470  {
1472  ASSERT(NULL != dpo);
1473  dpo_copy(&path->exclusive.fp_ex_dpo, dpo);
1474  }
1475 
1476  return (fib_path_get_index(path));
1477 }
1478 
1479 /*
1480  * fib_path_copy
1481  *
1482  * Copy a path. return index of new path.
1483  */
1486  fib_node_index_t path_list_index)
1487 {
1488  fib_path_t *path, *orig_path;
1489 
1490  pool_get(fib_path_pool, path);
1491 
1492  orig_path = fib_path_get(path_index);
1493  ASSERT(NULL != orig_path);
1494 
1495  clib_memcpy(path, orig_path, sizeof(*path));
1496 
1497  FIB_PATH_DBG(path, "create-copy:%d", path_index);
1498 
1499  /*
1500  * reset the dynamic section
1501  */
1504  path->fp_pl_index = path_list_index;
1506  clib_memset(&path->fp_dpo, 0, sizeof(path->fp_dpo));
1507  dpo_reset(&path->fp_dpo);
1508 
1509  return (fib_path_get_index(path));
1510 }
1511 
1512 /*
1513  * fib_path_destroy
1514  *
1515  * destroy a path that is no longer required
1516  */
1517 void
1519 {
1520  fib_path_t *path;
1521 
1522  path = fib_path_get(path_index);
1523 
1524  ASSERT(NULL != path);
1525  FIB_PATH_DBG(path, "destroy");
1526 
1527  fib_path_unresolve(path);
1528 
1529  fib_node_deinit(&path->fp_node);
1530  pool_put(fib_path_pool, path);
1531 }
1532 
1533 /*
1534  * fib_path_destroy
1535  *
1536  * destroy a path that is no longer required
1537  */
1538 uword
1540 {
1541  fib_path_t *path;
1542 
1543  path = fib_path_get(path_index);
1544 
1545  return (hash_memory(STRUCT_MARK_PTR(path, path_hash_start),
1546  (STRUCT_OFFSET_OF(fib_path_t, path_hash_end) -
1547  STRUCT_OFFSET_OF(fib_path_t, path_hash_start)),
1548  0));
1549 }
1550 
1551 /*
1552  * fib_path_cmp_i
1553  *
1554  * Compare two paths for equivalence.
1555  */
1556 static int
1558  const fib_path_t *path2)
1559 {
1560  int res;
1561 
1562  res = 1;
1563 
1564  /*
1565  * paths of different types and protocol are not equal.
1566  * different weights and/or preference only are the same path.
1567  */
1568  if (path1->fp_type != path2->fp_type)
1569  {
1570  res = (path1->fp_type - path2->fp_type);
1571  }
1572  else if (path1->fp_nh_proto != path2->fp_nh_proto)
1573  {
1574  res = (path1->fp_nh_proto - path2->fp_nh_proto);
1575  }
1576  else
1577  {
1578  /*
1579  * both paths are of the same type.
1580  * consider each type and its attributes in turn.
1581  */
1582  switch (path1->fp_type)
1583  {
1585  res = ip46_address_cmp(&path1->attached_next_hop.fp_nh,
1586  &path2->attached_next_hop.fp_nh);
1587  if (0 == res) {
1588  res = (path1->attached_next_hop.fp_interface -
1589  path2->attached_next_hop.fp_interface);
1590  }
1591  break;
1593  res = (path1->attached.fp_interface -
1594  path2->attached.fp_interface);
1595  break;
1597  res = ip46_address_cmp(&path1->recursive.fp_nh.fp_ip,
1598  &path2->recursive.fp_nh.fp_ip);
1599 
1600  if (0 == res)
1601  {
1602  res = (path1->recursive.fp_tbl_id - path2->recursive.fp_tbl_id);
1603  }
1604  break;
1606  res = (path1->bier_fmask.fp_bier_fmask -
1607  path2->bier_fmask.fp_bier_fmask);
1608  break;
1610  res = (path1->bier_imp.fp_bier_imp -
1611  path2->bier_imp.fp_bier_imp);
1612  break;
1614  res = bier_table_id_cmp(&path1->bier_table.fp_bier_tbl,
1615  &path2->bier_table.fp_bier_tbl);
1616  break;
1617  case FIB_PATH_TYPE_DEAG:
1618  res = (path1->deag.fp_tbl_id - path2->deag.fp_tbl_id);
1619  if (0 == res)
1620  {
1621  res = (path1->deag.fp_rpf_id - path2->deag.fp_rpf_id);
1622  }
1623  break;
1624  case FIB_PATH_TYPE_INTF_RX:
1625  res = (path1->intf_rx.fp_interface - path2->intf_rx.fp_interface);
1626  break;
1628  res = (path1->udp_encap.fp_udp_encap_id - path2->udp_encap.fp_udp_encap_id);
1629  break;
1630  case FIB_PATH_TYPE_DVR:
1631  res = (path1->dvr.fp_interface - path2->dvr.fp_interface);
1632  break;
1634  res = dpo_cmp(&path1->exclusive.fp_ex_dpo, &path2->exclusive.fp_ex_dpo);
1635  break;
1636  case FIB_PATH_TYPE_SPECIAL:
1637  case FIB_PATH_TYPE_RECEIVE:
1638  res = 0;
1639  break;
1640  }
1641  }
1642  return (res);
1643 }
1644 
1645 /*
1646  * fib_path_cmp_for_sort
1647  *
1648  * Compare two paths for equivalence. Used during path sorting.
1649  * As usual 0 means equal.
1650  */
1651 int
1653  void * v2)
1654 {
1655  fib_node_index_t *pi1 = v1, *pi2 = v2;
1656  fib_path_t *path1, *path2;
1657 
1658  path1 = fib_path_get(*pi1);
1659  path2 = fib_path_get(*pi2);
1660 
1661  /*
1662  * when sorting paths we want the highest preference paths
1663  * first, so that the choices set built is in prefernce order
1664  */
1665  if (path1->fp_preference != path2->fp_preference)
1666  {
1667  return (path1->fp_preference - path2->fp_preference);
1668  }
1669 
1670  return (fib_path_cmp_i(path1, path2));
1671 }
1672 
1673 /*
1674  * fib_path_cmp
1675  *
1676  * Compare two paths for equivalence.
1677  */
1678 int
1680  fib_node_index_t pi2)
1681 {
1682  fib_path_t *path1, *path2;
1683 
1684  path1 = fib_path_get(pi1);
1685  path2 = fib_path_get(pi2);
1686 
1687  return (fib_path_cmp_i(path1, path2));
1688 }
1689 
1690 int
1692  const fib_route_path_t *rpath)
1693 {
1694  fib_path_t *path;
1695  int res;
1696 
1697  path = fib_path_get(path_index);
1698 
1699  res = 1;
1700 
1701  if (path->fp_weight != rpath->frp_weight)
1702  {
1703  res = (path->fp_weight - rpath->frp_weight);
1704  }
1705  else
1706  {
1707  /*
1708  * both paths are of the same type.
1709  * consider each type and its attributes in turn.
1710  */
1711  switch (path->fp_type)
1712  {
1714  res = ip46_address_cmp(&path->attached_next_hop.fp_nh,
1715  &rpath->frp_addr);
1716  if (0 == res)
1717  {
1718  res = (path->attached_next_hop.fp_interface -
1719  rpath->frp_sw_if_index);
1720  }
1721  break;
1723  res = (path->attached.fp_interface - rpath->frp_sw_if_index);
1724  break;
1726  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1727  {
1728  res = path->recursive.fp_nh.fp_local_label - rpath->frp_local_label;
1729 
1730  if (res == 0)
1731  {
1732  res = path->recursive.fp_nh.fp_eos - rpath->frp_eos;
1733  }
1734  }
1735  else
1736  {
1737  res = ip46_address_cmp(&path->recursive.fp_nh.fp_ip,
1738  &rpath->frp_addr);
1739  }
1740 
1741  if (0 == res)
1742  {
1743  res = (path->recursive.fp_tbl_id - rpath->frp_fib_index);
1744  }
1745  break;
1747  res = (path->bier_fmask.fp_bier_fmask - rpath->frp_bier_fmask);
1748  break;
1750  res = (path->bier_imp.fp_bier_imp - rpath->frp_bier_imp);
1751  break;
1753  res = bier_table_id_cmp(&path->bier_table.fp_bier_tbl,
1754  &rpath->frp_bier_tbl);
1755  break;
1756  case FIB_PATH_TYPE_INTF_RX:
1757  res = (path->intf_rx.fp_interface - rpath->frp_sw_if_index);
1758  break;
1760  res = (path->udp_encap.fp_udp_encap_id - rpath->frp_udp_encap_id);
1761  break;
1762  case FIB_PATH_TYPE_DEAG:
1763  res = (path->deag.fp_tbl_id - rpath->frp_fib_index);
1764  if (0 == res)
1765  {
1766  res = (path->deag.fp_rpf_id - rpath->frp_rpf_id);
1767  }
1768  break;
1769  case FIB_PATH_TYPE_DVR:
1770  res = (path->dvr.fp_interface - rpath->frp_sw_if_index);
1771  break;
1773  res = dpo_cmp(&path->exclusive.fp_ex_dpo, &rpath->dpo);
1774  break;
1775  case FIB_PATH_TYPE_RECEIVE:
1776  if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
1777  {
1778  res = 0;
1779  }
1780  else
1781  {
1782  res = 1;
1783  }
1784  break;
1785  case FIB_PATH_TYPE_SPECIAL:
1786  res = 0;
1787  break;
1788  }
1789  }
1790  return (res);
1791 }
1792 
1793 /*
1794  * fib_path_recursive_loop_detect
1795  *
1796  * A forward walk of the FIB object graph to detect for a cycle/loop. This
1797  * walk is initiated when an entry is linking to a new path list or from an old.
1798  * The entry vector passed contains all the FIB entrys that are children of this
1799  * path (it is all the entries encountered on the walk so far). If this vector
1800  * contains the entry this path resolve via, then a loop is about to form.
1801  * The loop must be allowed to form, since we need the dependencies in place
1802  * so that we can track when the loop breaks.
1803  * However, we MUST not produce a loop in the forwarding graph (else packets
1804  * would loop around the switch path until the loop breaks), so we mark recursive
1805  * paths as looped so that they do not contribute forwarding information.
1806  * By marking the path as looped, an etry such as;
1807  * X/Y
1808  * via a.a.a.a (looped)
1809  * via b.b.b.b (not looped)
1810  * can still forward using the info provided by b.b.b.b only
1811  */
1812 int
1814  fib_node_index_t **entry_indicies)
1815 {
1816  fib_path_t *path;
1817 
1818  path = fib_path_get(path_index);
1819 
1820  /*
1821  * the forced drop path is never looped, cos it is never resolved.
1822  */
1823  if (fib_path_is_permanent_drop(path))
1824  {
1825  return (0);
1826  }
1827 
1828  switch (path->fp_type)
1829  {
1831  {
1832  fib_node_index_t *entry_index, *entries;
1833  int looped = 0;
1834  entries = *entry_indicies;
1835 
1836  vec_foreach(entry_index, entries) {
1837  if (*entry_index == path->fp_via_fib)
1838  {
1839  /*
1840  * the entry that is about to link to this path-list (or
1841  * one of this path-list's children) is the same entry that
1842  * this recursive path resolves through. this is a cycle.
1843  * abort the walk.
1844  */
1845  looped = 1;
1846  break;
1847  }
1848  }
1849 
1850  if (looped)
1851  {
1852  FIB_PATH_DBG(path, "recursive loop formed");
1854 
1855  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
1856  }
1857  else
1858  {
1859  /*
1860  * no loop here yet. keep forward walking the graph.
1861  */
1862  if (fib_entry_recursive_loop_detect(path->fp_via_fib, entry_indicies))
1863  {
1864  FIB_PATH_DBG(path, "recursive loop formed");
1866  }
1867  else
1868  {
1869  FIB_PATH_DBG(path, "recursive loop cleared");
1871  }
1872  }
1873  break;
1874  }
1877  if (dpo_is_adj(&path->fp_dpo) &&
1879  entry_indicies))
1880  {
1881  FIB_PATH_DBG(path, "recursive loop formed");
1883  }
1884  else
1885  {
1886  FIB_PATH_DBG(path, "recursive loop cleared");
1888  }
1889  break;
1890  case FIB_PATH_TYPE_SPECIAL:
1891  case FIB_PATH_TYPE_DEAG:
1892  case FIB_PATH_TYPE_DVR:
1893  case FIB_PATH_TYPE_RECEIVE:
1894  case FIB_PATH_TYPE_INTF_RX:
1900  /*
1901  * these path types cannot be part of a loop, since they are the leaves
1902  * of the graph.
1903  */
1904  break;
1905  }
1906 
1907  return (fib_path_is_looped(path_index));
1908 }
1909 
1910 int
1912 {
1913  fib_path_t *path;
1914 
1915  path = fib_path_get(path_index);
1916 
1917  /*
1918  * hope for the best.
1919  */
1921 
1922  /*
1923  * the forced drop path resolves via the drop adj
1924  */
1925  if (fib_path_is_permanent_drop(path))
1926  {
1927  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
1929  return (fib_path_is_resolved(path_index));
1930  }
1931 
1932  switch (path->fp_type)
1933  {
1936  break;
1938  {
1939  dpo_id_t tmp = DPO_INVALID;
1940 
1941  /*
1942  * path->attached.fp_interface
1943  */
1945  path->attached.fp_interface))
1946  {
1948  }
1951  &tmp);
1952 
1953  /*
1954  * re-fetch after possible mem realloc
1955  */
1956  path = fib_path_get(path_index);
1957  dpo_copy(&path->fp_dpo, &tmp);
1958 
1959  /*
1960  * become a child of the adjacency so we receive updates
1961  * when the interface state changes
1962  */
1963  if (dpo_is_adj(&path->fp_dpo))
1964  {
1965  path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
1967  fib_path_get_index(path));
1968  }
1969  dpo_reset(&tmp);
1970  break;
1971  }
1973  {
1974  /*
1975  * Create a RR source entry in the table for the address
1976  * that this path recurses through.
1977  * This resolve action is recursive, hence we may create
1978  * more paths in the process. more creates mean maybe realloc
1979  * of this path.
1980  */
1981  fib_node_index_t fei;
1982  fib_prefix_t pfx;
1983 
1985 
1986  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1987  {
1988  fib_prefix_from_mpls_label(path->recursive.fp_nh.fp_local_label,
1989  path->recursive.fp_nh.fp_eos,
1990  &pfx);
1991  }
1992  else
1993  {
1994  fib_prefix_from_ip46_addr(&path->recursive.fp_nh.fp_ip, &pfx);
1995  }
1996 
1997  fib_table_lock(path->recursive.fp_tbl_id,
1999  FIB_SOURCE_RR);
2000  fei = fib_table_entry_special_add(path->recursive.fp_tbl_id,
2001  &pfx,
2002  FIB_SOURCE_RR,
2004 
2005  path = fib_path_get(path_index);
2006  path->fp_via_fib = fei;
2007 
2008  /*
2009  * become a dependent child of the entry so the path is
2010  * informed when the forwarding for the entry changes.
2011  */
2014  fib_path_get_index(path));
2015 
2016  /*
2017  * create and configure the IP DPO
2018  */
2020  path,
2021  fib_path_to_chain_type(path),
2022  &path->fp_dpo);
2023 
2024  break;
2025  }
2027  {
2028  /*
2029  * become a dependent child of the entry so the path is
2030  * informed when the forwarding for the entry changes.
2031  */
2032  path->fp_sibling = bier_fmask_child_add(path->bier_fmask.fp_bier_fmask,
2034  fib_path_get_index(path));
2035 
2036  path->fp_via_bier_fmask = path->bier_fmask.fp_bier_fmask;
2037  fib_path_bier_fmask_update(path, &path->fp_dpo);
2038 
2039  break;
2040  }
2042  bier_imp_lock(path->bier_imp.fp_bier_imp);
2043  bier_imp_contribute_forwarding(path->bier_imp.fp_bier_imp,
2044  DPO_PROTO_IP4,
2045  &path->fp_dpo);
2046  break;
2048  {
2049  /*
2050  * Find/create the BIER table to link to
2051  */
2053 
2054  path->fp_via_bier_tbl =
2055  bier_table_ecmp_create_and_lock(&path->bier_table.fp_bier_tbl);
2056 
2058  &path->fp_dpo);
2059  break;
2060  }
2061  case FIB_PATH_TYPE_SPECIAL:
2063  {
2066  &path->fp_dpo);
2067  }
2069  {
2072  &path->fp_dpo);
2073  }
2074  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY)
2075  {
2076  dpo_set (&path->fp_dpo, DPO_CLASSIFY,
2077  path->fp_nh_proto,
2079  path->classify.fp_classify_table_id));
2080  }
2081  else
2082  {
2083  /*
2084  * Resolve via the drop
2085  */
2086  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
2087  }
2088  break;
2089  case FIB_PATH_TYPE_DEAG:
2090  {
2091  if (DPO_PROTO_BIER == path->fp_nh_proto)
2092  {
2094  &path->fp_dpo);
2095  }
2096  else
2097  {
2098  /*
2099  * Resolve via a lookup DPO.
2100  * FIXME. control plane should add routes with a table ID
2101  */
2102  lookup_input_t input;
2103  lookup_cast_t cast;
2104 
2105  cast = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ?
2107  LOOKUP_UNICAST);
2108  input = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DEAG_SRC ?
2111 
2112  lookup_dpo_add_or_lock_w_fib_index(path->deag.fp_tbl_id,
2113  path->fp_nh_proto,
2114  cast,
2115  input,
2117  &path->fp_dpo);
2118  }
2119  break;
2120  }
2121  case FIB_PATH_TYPE_DVR:
2122  dvr_dpo_add_or_lock(path->attached.fp_interface,
2123  path->fp_nh_proto,
2124  &path->fp_dpo);
2125  break;
2126  case FIB_PATH_TYPE_RECEIVE:
2127  /*
2128  * Resolve via a receive DPO.
2129  */
2131  path->receive.fp_interface,
2132  &path->receive.fp_addr,
2133  &path->fp_dpo);
2134  break;
2136  udp_encap_lock(path->udp_encap.fp_udp_encap_id);
2137  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
2138  path->fp_nh_proto,
2139  &path->fp_dpo);
2140  break;
2141  case FIB_PATH_TYPE_INTF_RX: {
2142  /*
2143  * Resolve via a receive DPO.
2144  */
2146  path->intf_rx.fp_interface,
2147  &path->fp_dpo);
2148  break;
2149  }
2151  /*
2152  * Resolve via the user provided DPO
2153  */
2154  dpo_copy(&path->fp_dpo, &path->exclusive.fp_ex_dpo);
2155  break;
2156  }
2157 
2158  return (fib_path_is_resolved(path_index));
2159 }
2160 
2161 u32
2163 {
2164  fib_path_t *path;
2165 
2166  path = fib_path_get(path_index);
2167 
2168  switch (path->fp_type)
2169  {
2171  return (path->attached_next_hop.fp_interface);
2173  return (path->attached.fp_interface);
2174  case FIB_PATH_TYPE_RECEIVE:
2175  return (path->receive.fp_interface);
2177  if (fib_path_is_resolved(path_index))
2178  {
2180  }
2181  break;
2182  case FIB_PATH_TYPE_DVR:
2183  return (path->dvr.fp_interface);
2184  case FIB_PATH_TYPE_INTF_RX:
2186  case FIB_PATH_TYPE_SPECIAL:
2187  case FIB_PATH_TYPE_DEAG:
2192  break;
2193  }
2194  return (dpo_get_urpf(&path->fp_dpo));
2195 }
2196 
2197 index_t
2199 {
2200  fib_path_t *path;
2201 
2202  path = fib_path_get(path_index);
2203 
2204  switch (path->fp_type)
2205  {
2208  case FIB_PATH_TYPE_RECEIVE:
2209  case FIB_PATH_TYPE_INTF_RX:
2210  case FIB_PATH_TYPE_SPECIAL:
2211  case FIB_PATH_TYPE_DEAG:
2212  case FIB_PATH_TYPE_DVR:
2214  break;
2216  return (path->udp_encap.fp_udp_encap_id);
2218  return (path->fp_via_fib);
2220  return (path->bier_fmask.fp_bier_fmask);
2222  return (path->fp_via_bier_tbl);
2224  return (path->bier_imp.fp_bier_imp);
2225  }
2226  return (~0);
2227 }
2228 
2231 {
2232  fib_path_t *path;
2233 
2234  path = fib_path_get(path_index);
2235 
2236  if (dpo_is_adj(&path->fp_dpo))
2237  {
2238  return (path->fp_dpo.dpoi_index);
2239  }
2240  return (ADJ_INDEX_INVALID);
2241 }
2242 
2243 u16
2245 {
2246  fib_path_t *path;
2247 
2248  path = fib_path_get(path_index);
2249 
2250  ASSERT(path);
2251 
2252  return (path->fp_weight);
2253 }
2254 
2255 u16
2257 {
2258  fib_path_t *path;
2259 
2260  path = fib_path_get(path_index);
2261 
2262  ASSERT(path);
2263 
2264  return (path->fp_preference);
2265 }
2266 
2267 u32
2269 {
2270  fib_path_t *path;
2271 
2272  path = fib_path_get(path_index);
2273 
2274  ASSERT(path);
2275 
2277  {
2278  return (path->deag.fp_rpf_id);
2279  }
2280 
2281  return (~0);
2282 }
2283 
2284 /**
2285  * @brief Contribute the path's adjacency to the list passed.
2286  * By calling this function over all paths, recursively, a child
2287  * can construct its full set of forwarding adjacencies, and hence its
2288  * uRPF list.
2289  */
2290 void
2292  index_t urpf)
2293 {
2294  fib_path_t *path;
2295 
2296  path = fib_path_get(path_index);
2297 
2298  /*
2299  * resolved and unresolved paths contribute to the RPF list.
2300  */
2301  switch (path->fp_type)
2302  {
2304  fib_urpf_list_append(urpf, path->attached_next_hop.fp_interface);
2305  break;
2306 
2308  fib_urpf_list_append(urpf, path->attached.fp_interface);
2309  break;
2310 
2312  if (FIB_NODE_INDEX_INVALID != path->fp_via_fib &&
2313  !fib_path_is_looped(path_index))
2314  {
2315  /*
2316  * there's unresolved due to constraints, and there's unresolved
2317  * due to ain't got no via. can't do nowt w'out via.
2318  */
2320  }
2321  break;
2322 
2324  case FIB_PATH_TYPE_SPECIAL:
2325  {
2326  /*
2327  * these path types may link to an adj, if that's what
2328  * the clinet gave
2329  */
2330  u32 rpf_sw_if_index;
2331 
2332  rpf_sw_if_index = dpo_get_urpf(&path->fp_dpo);
2333 
2334  if (~0 != rpf_sw_if_index)
2335  {
2336  fib_urpf_list_append(urpf, rpf_sw_if_index);
2337  }
2338  break;
2339  }
2340  case FIB_PATH_TYPE_DVR:
2341  fib_urpf_list_append(urpf, path->dvr.fp_interface);
2342  break;
2343  case FIB_PATH_TYPE_DEAG:
2344  case FIB_PATH_TYPE_RECEIVE:
2345  case FIB_PATH_TYPE_INTF_RX:
2350  /*
2351  * these path types don't link to an adj
2352  */
2353  break;
2354  }
2355 }
2356 
2357 void
2359  dpo_proto_t payload_proto,
2361  dpo_id_t *dpo)
2362 {
2363  fib_path_t *path;
2364 
2365  path = fib_path_get(path_index);
2366 
2367  ASSERT(path);
2368 
2369  switch (path->fp_type)
2370  {
2372  {
2373  dpo_id_t tmp = DPO_INVALID;
2374 
2375  dpo_copy(&tmp, dpo);
2376 
2377  mpls_disp_dpo_create(payload_proto, ~0, mode, &tmp, dpo);
2378  dpo_reset(&tmp);
2379  break;
2380  }
2381  case FIB_PATH_TYPE_DEAG:
2382  {
2383  dpo_id_t tmp = DPO_INVALID;
2384 
2385  dpo_copy(&tmp, dpo);
2386 
2387  mpls_disp_dpo_create(payload_proto,
2388  path->deag.fp_rpf_id,
2389  mode, &tmp, dpo);
2390  dpo_reset(&tmp);
2391  break;
2392  }
2393  case FIB_PATH_TYPE_RECEIVE:
2396  case FIB_PATH_TYPE_INTF_RX:
2399  case FIB_PATH_TYPE_SPECIAL:
2403  case FIB_PATH_TYPE_DVR:
2404  break;
2405  }
2406 
2408  {
2409  dpo_id_t tmp = DPO_INVALID;
2410 
2411  dpo_copy(&tmp, dpo);
2412 
2413  pw_cw_dpo_create(&tmp, dpo);
2414  dpo_reset(&tmp);
2415  }
2416 }
2417 
2418 void
2421  dpo_id_t *dpo)
2422 {
2423  fib_path_t *path;
2424 
2425  path = fib_path_get(path_index);
2426 
2427  ASSERT(path);
2429 
2430  /*
2431  * The DPO stored in the path was created when the path was resolved.
2432  * This then represents the path's 'native' protocol; IP.
2433  * For all others will need to go find something else.
2434  */
2435  if (fib_path_to_chain_type(path) == fct)
2436  {
2437  dpo_copy(dpo, &path->fp_dpo);
2438  }
2439  else
2440  {
2441  switch (path->fp_type)
2442  {
2444  switch (fct)
2445  {
2455  path,
2457  dpo);
2458  break;
2460  break;
2461  }
2462  break;
2464  switch (fct)
2465  {
2473  fib_path_recursive_adj_update(path, fct, dpo);
2474  break;
2477  ASSERT(0);
2478  break;
2479  }
2480  break;
2482  switch (fct)
2483  {
2486  break;
2495  ASSERT(0);
2496  break;
2497  }
2498  break;
2500  switch (fct)
2501  {
2503  fib_path_bier_fmask_update(path, dpo);
2504  break;
2513  ASSERT(0);
2514  break;
2515  }
2516  break;
2518  bier_imp_contribute_forwarding(path->bier_imp.fp_bier_imp,
2520  dpo);
2521  break;
2522  case FIB_PATH_TYPE_DEAG:
2523  switch (fct)
2524  {
2531  dpo);
2532  break;
2538  dpo_copy(dpo, &path->fp_dpo);
2539  break;
2541  break;
2544  ASSERT(0);
2545  break;
2546  }
2547  break;
2549  dpo_copy(dpo, &path->exclusive.fp_ex_dpo);
2550  break;
2552  switch (fct)
2553  {
2563  dpo);
2564  break;
2567  {
2568  adj_index_t ai;
2569 
2570  /*
2571  * Create the adj needed for sending IP multicast traffic
2572  */
2574  path->attached.fp_interface))
2575  {
2576  /*
2577  * point-2-point interfaces do not require a glean, since
2578  * there is nothing to ARP. Install a rewrite/nbr adj instead
2579  */
2582  &zero_addr,
2583  path->attached.fp_interface);
2584  }
2585  else
2586  {
2589  path->attached.fp_interface);
2590  }
2591  dpo_set(dpo, DPO_ADJACENCY,
2593  ai);
2594  adj_unlock(ai);
2595  }
2596  break;
2597  }
2598  break;
2599  case FIB_PATH_TYPE_INTF_RX:
2600  /*
2601  * Create the adj needed for sending IP multicast traffic
2602  */
2604  path->attached.fp_interface,
2605  dpo);
2606  break;
2608  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
2609  path->fp_nh_proto,
2610  dpo);
2611  break;
2612  case FIB_PATH_TYPE_RECEIVE:
2613  case FIB_PATH_TYPE_SPECIAL:
2614  case FIB_PATH_TYPE_DVR:
2615  dpo_copy(dpo, &path->fp_dpo);
2616  break;
2617  }
2618  }
2619 }
2620 
2624  load_balance_path_t *hash_key)
2625 {
2626  load_balance_path_t *mnh;
2627  fib_path_t *path;
2628 
2629  path = fib_path_get(path_index);
2630 
2631  ASSERT(path);
2632 
2633  vec_add2(hash_key, mnh, 1);
2634 
2635  mnh->path_weight = path->fp_weight;
2636  mnh->path_index = path_index;
2637 
2638  if (fib_path_is_resolved(path_index))
2639  {
2640  fib_path_contribute_forwarding(path_index, fct, &mnh->path_dpo);
2641  }
2642  else
2643  {
2644  dpo_copy(&mnh->path_dpo,
2646  }
2647  return (hash_key);
2648 }
2649 
2650 int
2652 {
2653  fib_path_t *path;
2654 
2655  path = fib_path_get(path_index);
2656 
2657  return ((FIB_PATH_TYPE_RECURSIVE == path->fp_type) &&
2660 }
2661 
2662 int
2664 {
2665  fib_path_t *path;
2666 
2667  path = fib_path_get(path_index);
2668 
2669  return (FIB_PATH_TYPE_EXCLUSIVE == path->fp_type);
2670 }
2671 
2672 int
2674 {
2675  fib_path_t *path;
2676 
2677  path = fib_path_get(path_index);
2678 
2679  return (FIB_PATH_TYPE_DEAG == path->fp_type);
2680 }
2681 
2682 int
2684 {
2685  fib_path_t *path;
2686 
2687  path = fib_path_get(path_index);
2688 
2689  return (dpo_id_is_valid(&path->fp_dpo) &&
2691  !fib_path_is_looped(path_index) &&
2693 }
2694 
2695 int
2697 {
2698  fib_path_t *path;
2699 
2700  path = fib_path_get(path_index);
2701 
2703 }
2704 
2707  fib_node_index_t path_index,
2708  const fib_path_ext_t *path_ext,
2709  void *args)
2710 {
2711  fib_path_encode_ctx_t *ctx = args;
2712  fib_route_path_t *rpath;
2713  fib_path_t *path;
2714 
2715  path = fib_path_get(path_index);
2716  if (!path)
2717  return (FIB_PATH_LIST_WALK_CONTINUE);
2718 
2719  vec_add2(ctx->rpaths, rpath, 1);
2720  rpath->frp_weight = path->fp_weight;
2721  rpath->frp_preference = path->fp_preference;
2722  rpath->frp_proto = path->fp_nh_proto;
2723  rpath->frp_sw_if_index = ~0;
2724  rpath->frp_fib_index = 0;
2725 
2726  switch (path->fp_type)
2727  {
2728  case FIB_PATH_TYPE_RECEIVE:
2729  rpath->frp_addr = path->receive.fp_addr;
2730  rpath->frp_sw_if_index = path->receive.fp_interface;
2731  rpath->frp_flags |= FIB_ROUTE_PATH_LOCAL;
2732  break;
2734  rpath->frp_sw_if_index = path->attached.fp_interface;
2735  break;
2737  rpath->frp_sw_if_index = path->attached_next_hop.fp_interface;
2738  rpath->frp_addr = path->attached_next_hop.fp_nh;
2739  break;
2741  rpath->frp_bier_fmask = path->bier_fmask.fp_bier_fmask;
2742  break;
2743  case FIB_PATH_TYPE_SPECIAL:
2744  break;
2745  case FIB_PATH_TYPE_DEAG:
2746  rpath->frp_fib_index = path->deag.fp_tbl_id;
2748  {
2749  rpath->frp_flags |= FIB_ROUTE_PATH_RPF_ID;
2750  }
2751  break;
2753  rpath->frp_addr = path->recursive.fp_nh.fp_ip;
2754  rpath->frp_fib_index = path->recursive.fp_tbl_id;
2755  break;
2756  case FIB_PATH_TYPE_DVR:
2757  rpath->frp_sw_if_index = path->dvr.fp_interface;
2758  rpath->frp_flags |= FIB_ROUTE_PATH_DVR;
2759  break;
2761  rpath->frp_udp_encap_id = path->udp_encap.fp_udp_encap_id;
2763  break;
2764  case FIB_PATH_TYPE_INTF_RX:
2765  rpath->frp_sw_if_index = path->receive.fp_interface;
2767  break;
2770  default:
2771  break;
2772  }
2773 
2774  if (path_ext && path_ext->fpe_type == FIB_PATH_EXT_MPLS)
2775  {
2776  rpath->frp_label_stack = path_ext->fpe_path.frp_label_stack;
2777  }
2778 
2780  rpath->frp_flags |= FIB_ROUTE_PATH_DROP;
2785 
2786  return (FIB_PATH_LIST_WALK_CONTINUE);
2787 }
2788 
2791 {
2792  fib_path_t *path;
2793 
2794  path = fib_path_get(path_index);
2795 
2796  return (path->fp_nh_proto);
2797 }
2798 
2799 void
2801 {
2802  fib_node_register_type (FIB_NODE_TYPE_PATH, &fib_path_vft);
2803  fib_path_logger = vlib_log_register_class ("fib", "path");
2804 }
2805 
2806 static clib_error_t *
2808  unformat_input_t * input,
2809  vlib_cli_command_t * cmd)
2810 {
2811  fib_node_index_t pi;
2812  fib_path_t *path;
2813 
2814  if (unformat (input, "%d", &pi))
2815  {
2816  /*
2817  * show one in detail
2818  */
2819  if (!pool_is_free_index(fib_path_pool, pi))
2820  {
2821  path = fib_path_get(pi);
2822  u8 *s = format(NULL, "%U", format_fib_path, pi, 1,
2824  s = format(s, "\n children:");
2826  vlib_cli_output (vm, "%v", s);
2827  vec_free(s);
2828  }
2829  else
2830  {
2831  vlib_cli_output (vm, "path %d invalid", pi);
2832  }
2833  }
2834  else
2835  {
2836  vlib_cli_output (vm, "FIB Paths");
2837  pool_foreach_index (pi, fib_path_pool,
2838  ({
2839  vlib_cli_output (vm, "%U", format_fib_path, pi, 0,
2841  }));
2842  }
2843 
2844  return (NULL);
2845 }
2846 
2847 VLIB_CLI_COMMAND (show_fib_path, static) = {
2848  .path = "show fib paths",
2849  .function = show_fib_path_command,
2850  .short_help = "show fib paths",
2851 };
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:209
int fib_path_is_resolved(fib_node_index_t path_index)
Definition: fib_path.c:2683
static uword vnet_sw_interface_is_up(vnet_main_t *vnm, u32 sw_if_index)
Contribute an object that is to be used to forward BIER packets.
Definition: fib_types.h:122
int fib_path_resolve(fib_node_index_t path_index)
Definition: fib_path.c:1911
void ip_null_dpo_add_and_lock(dpo_proto_t proto, ip_null_dpo_action_t action, dpo_id_t *dpo)
Definition: ip_null_dpo.c:78
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:137
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:506
fib_path_ext_type_t fpe_type
The type of path extension.
Definition: fib_path_ext.h:126
struct fib_path_t_::@257::@266 bier_imp
A path that resolves via a DVR DPO.
Definition: fib_types.h:387
void mpls_disp_dpo_create(dpo_proto_t payload_proto, fib_rpf_id_t rpf_id, fib_mpls_lsp_mode_t mode, const dpo_id_t *parent, dpo_id_t *dpo)
Create an MPLS label object.
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:113
void receive_dpo_add_or_lock(dpo_proto_t proto, u32 sw_if_index, const ip46_address_t *nh_addr, dpo_id_t *dpo)
Definition: receive_dpo.c:62
void pw_cw_dpo_create(const dpo_id_t *parent, dpo_id_t *dpo)
Create an PW CW pop.
Definition: pw_cw.c:43
static fib_path_t * fib_path_from_fib_node(fib_node_t *node)
Definition: fib_path.c:457
void bier_imp_contribute_forwarding(index_t bii, dpo_proto_t proto, dpo_id_t *dpo)
Definition: bier_imp.c:174
uword fib_path_hash(fib_node_index_t path_index)
Definition: fib_path.c:1539
fib_node_index_t path_index
The index of the FIB path.
Definition: load_balance.h:71
void fib_path_contribute_forwarding(fib_node_index_t path_index, fib_forward_chain_type_t fct, dpo_id_t *dpo)
Definition: fib_path.c:2419
enum fib_path_format_flags_t_ fib_format_path_flags_t
index_t fp_bier_fmask
BIER FMask ID.
Definition: fib_path.c:300
void lookup_dpo_add_or_lock_w_table_id(u32 table_id, dpo_proto_t proto, lookup_cast_t cast, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:159
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:517
fib_path_oper_attribute_t_
Enurmeration of path operational (i.e.
Definition: fib_path.c:144
u32 fp_classify_table_id
The UDP Encap object this path resolves through.
Definition: fib_path.c:360
struct fib_path_t_::@257::@267 deag
int fib_entry_is_resolved(fib_node_index_t fib_entry_index)
Return !0 is the entry is resolved, i.e.
Definition: fib_entry.c:1493
index_t fib_path_get_resolving_index(fib_node_index_t path_index)
Definition: fib_path.c:2198
void fib_path_contribute_urpf(fib_node_index_t path_index, index_t urpf)
Contribute the path&#39;s adjacency to the list passed.
Definition: fib_path.c:2291
A representation of a path as described by a route producer.
Definition: fib_types.h:490
u8 * format_dpo_type(u8 *s, va_list *args)
format a DPO type
Definition: dpo.c:138
dpo_id_t path_dpo
ID of the Data-path object.
Definition: load_balance.h:66
int dpo_is_adj(const dpo_id_t *dpo)
Return TRUE is the DPO is any type of adjacency.
Definition: dpo.c:278
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
u8 * format_bier_table_id(u8 *s, va_list *ap)
Format a BIER table ID.
Definition: bier_types.c:193
#define FIB_PATH_OPER_ATTRIBUTES
Definition: fib_path.c:176
#define STRUCT_MARK_PTR(v, f)
Definition: clib.h:75
int fib_path_cmp(fib_node_index_t pi1, fib_node_index_t pi2)
Definition: fib_path.c:1679
A Drop path - resolve the path on the drop DPO.
Definition: fib_types.h:346
void bier_fmask_contribute_forwarding(index_t bfmi, dpo_id_t *dpo)
Definition: bier_fmask.c:120
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:185
index_t fp_bier_imp
The BIER imposition object this is part of the path&#39;s key, since the index_t of an imposition object ...
Definition: fib_path.c:314
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:555
static int dpo_id_is_valid(const dpo_id_t *dpoi)
Return true if the DPO object is valid, i.e.
Definition: dpo.h:209
struct fib_path_t_::@257::@272 udp_encap
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
A path that resolves via a BIER impostion object.
Definition: fib_types.h:379
An MPLS extension that maintains the path&#39;s outgoing labels,.
Definition: fib_path_ext.h:31
void fib_path_module_init(void)
Definition: fib_path.c:2800
int fib_path_is_exclusive(fib_node_index_t path_index)
Definition: fib_path.c:2663
void bier_imp_lock(index_t bii)
Definition: bier_imp.c:48
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:437
static void fib_path_bier_fmask_update(fib_path_t *path, dpo_id_t *dpo)
Definition: fib_path.c:864
index_t frp_bier_imp
A path via a BIER imposition object.
Definition: fib_types.h:523
void bier_table_ecmp_unlock(index_t bti)
Definition: bier_table.c:462
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:26
dpo_proto_t fib_forw_chain_type_to_dpo_proto(fib_forward_chain_type_t fct)
Convert from a chain type to the DPO proto it will install.
Definition: fib_types.c:497
void load_balance_map_path_state_change(fib_node_index_t path_index)
the state of a path has changed (it has no doubt gone down).
void fib_entry_child_remove(fib_node_index_t fib_entry_index, u32 sibling_index)
Definition: fib_entry.c:566
fib_node_index_t fp_tbl_id
The FIB table index in which to find the next-hop.
Definition: fib_path.c:289
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:262
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
enum fib_path_type_t_ fib_path_type_t
Enurmeration of path types.
u32 dpo_get_urpf(const dpo_id_t *dpo)
Get a uRPF interface for the DPO.
Definition: dpo.c:382
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:628
A path that resolves via a BIER [ECMP] Table.
Definition: fib_types.h:375
The path is resolved.
Definition: fib_path.c:156
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:109
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:69
void fib_node_deinit(fib_node_t *node)
Definition: fib_node.c:197
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1691
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:495
vl_api_fib_path_t path
Definition: mfib_types.api:34
bier_table_id_t frp_bier_tbl
A path that resolves via a BIER Table.
Definition: fib_types.h:565
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:355
dpo_id_t fp_ex_dpo
The user provided &#39;exclusive&#39; DPO.
Definition: fib_path.c:332
int fib_path_is_looped(fib_node_index_t path_index)
Definition: fib_path.c:2696
Definition: fib_entry.h:114
The ID of a table.
Definition: bier_types.h:394
void adj_child_remove(adj_index_t adj_index, u32 sibling_index)
Remove a child dependent.
Definition: adj.c:361
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
The path has become a permanent drop.
Definition: fib_path.c:164
int fib_path_cmp_for_sort(void *v1, void *v2)
Definition: fib_path.c:1652
unsigned char u8
Definition: types.h:56
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:140
ip46_address_t fp_ip
The next-hop.
Definition: fib_path.c:273
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
load_balance_path_t * fib_path_append_nh_for_multipath_hash(fib_node_index_t path_index, fib_forward_chain_type_t fct, load_balance_path_t *hash_key)
Definition: fib_path.c:2622
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:60
#define clib_memcpy(d, s, n)
Definition: string.h:180
int vnet_sw_interface_is_nbma(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1255
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
fib_rpf_id_t frp_rpf_id
The RPF-ID.
Definition: fib_types.h:535
A local path with a RPF-ID => multicast traffic.
Definition: fib_types.h:359
#define FIB_PATH_TYPES
Definition: fib_path.c:120
u32 vlib_log_class_t
Definition: vlib.h:51
fib_path_type_t fp_type
The type of the path.
Definition: fib_path.c:226
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:530
struct fib_path_t_::@257::@270 receive
dpo_proto_t vnet_link_to_dpo_proto(vnet_link_t linkt)
Definition: dpo.c:96
mpls_eos_bit_t fp_eos
The EOS bit of the resolving label.
Definition: fib_path.c:282
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a &#39;special&#39; entry from the FIB.
Definition: fib_table.c:424
static int ip46_address_cmp(const ip46_address_t *ip46_1, const ip46_address_t *ip46_2)
Definition: ip46_address.h:80
void bier_table_contribute_forwarding(index_t bti, dpo_id_t *dpo)
Definition: bier_table.c:728
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
Recursion constraint of via a host prefix.
Definition: fib_types.h:330
Recursive resolution source.
Definition: fib_source.h:119
fib_node_index_t fib_path_copy(fib_node_index_t path_index, fib_node_index_t path_list_index)
Definition: fib_path.c:1485
u8 * format_bier_imp(u8 *s, va_list *args)
Definition: bier_imp.c:137
void bier_fmask_child_remove(fib_node_index_t bfmi, u32 sibling_index)
Definition: bier_fmask.c:152
Aggregate type for a prefix.
Definition: fib_types.h:203
fib_path_cfg_flags_t fp_cfg_flags
Configuration Flags.
Definition: fib_path.c:221
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:391
void fib_show_memory_usage(const char *name, u32 in_use_elts, u32 allocd_elts, size_t size_elt)
Show the memory usage for a type.
Definition: fib_node.c:220
fib_node_t fp_node
A path is a node in the FIB graph.
Definition: fib_path.c:205
interface receive.
Definition: fib_path.c:84
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:325
A path via a UDP encap object.
Definition: fib_types.h:367
dpo_id_t fp_dpo
The Data-path objects through which this path resolves for IP.
Definition: fib_path.c:401
unsigned int u32
Definition: types.h:88
#define FIB_PATH_CFG_ATTRIBUTES
Definition: fib_path.h:113
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:141
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:340
int load_balance_is_drop(const dpo_id_t *dpo)
Definition: load_balance.c:272
u16 fib_path_get_weight(fib_node_index_t path_index)
Definition: fib_path.c:2244
struct fib_path_t_::@257::@264 bier_fmask
enum lookup_cast_t_ lookup_cast_t
Switch to use the packet&#39;s source or destination address for lookup.
void fib_urpf_list_append(index_t ui, u32 sw_if_index)
Append another interface to the list.
static void fib_path_attached_next_hop_set(fib_path_t *path)
Definition: fib_path.c:686
fib_node_index_t fib_path_create_special(fib_node_index_t pl_index, dpo_proto_t nh_proto, fib_path_cfg_flags_t flags, const dpo_id_t *dpo)
Definition: fib_path.c:1439
Definition: fib_entry.h:112
fib_rpf_id_t fp_rpf_id
The RPF-ID to tag the packets with.
Definition: fib_path.c:324
void bier_disp_table_contribute_forwarding(index_t bdti, dpo_id_t *dpo)
index_t frp_bier_fmask
Resolving via a BIER Fmask.
Definition: fib_types.h:580
u8 * format_fib_path(u8 *s, va_list *args)
Definition: fib_path.c:464
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
u32 fp_sibling
the index of this path in the parent&#39;s child list.
Definition: fib_path.c:406
Contribute an object that is to be used to forward end-of-stack MPLS packets.
Definition: fib_types.h:129
fib_node_bw_reason_flag_t fnbw_reason
The reason/trigger for the backwalk.
Definition: fib_node.h:212
format_function_t format_mpls_eos_bit
Definition: mpls.h:69
format_function_t format_vnet_sw_interface_name
#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:534
int adj_is_up(adj_index_t ai)
Return true if the adjacency is &#39;UP&#39;, i.e.
Definition: adj.c:511
u8 * format_fib_node_bw_reason(u8 *s, va_list *args)
Definition: fib_walk.c:973
dpo_proto_t fp_nh_proto
The protocol of the next-hop, i.e.
Definition: fib_path.c:233
struct fib_path_t_ fib_path_t
A FIB path.
index_t classify_dpo_create(dpo_proto_t proto, u32 classify_table_index)
Definition: classify_dpo.c:43
dpo_type_t dpoi_type
the type
Definition: dpo.h:174
struct fib_path_t_::@257::@273 classify
int vnet_sw_interface_is_p2p(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1240
static u8 ip46_address_is_zero(const ip46_address_t *ip46)
Definition: ip46_address.h:87
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
STRUCT_MARK(path_hash_start)
This marks the start of the memory area used to hash the path.
adj_index_t fib_path_get_adj(fib_node_index_t path_index)
Definition: fib_path.c:2230
enum fib_mpls_lsp_mode_t_ fib_mpls_lsp_mode_t
MPLS LSP mode - only valid at the head and tail.
struct fib_path_t_::@257::@271 intf_rx
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
index_t fp_via_bier_tbl
the resolving bier-table
Definition: fib_path.c:391
fib_mpls_label_t * frp_label_stack
The outgoing MPLS label Stack.
Definition: fib_types.h:551
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:334
void lookup_dpo_add_or_lock_w_fib_index(fib_node_index_t fib_index, dpo_proto_t proto, lookup_cast_t cast, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:133
void fib_path_stack_mpls_disp(fib_node_index_t path_index, dpo_proto_t payload_proto, fib_mpls_lsp_mode_t mode, dpo_id_t *dpo)
Definition: fib_path.c:2358
fib_node_type_t fn_type
The node&#39;s type.
Definition: fib_node.h:299
enum fib_path_cfg_attribute_t_ fib_path_cfg_attribute_t
Given a route of the form; q.r.s.t/Y via <interface> <next-hop>
An node in the FIB graph.
Definition: fib_node.h:295
dpo_id_t dpo
Exclusive DPO.
Definition: fib_types.h:555
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1291
static fib_path_t * fib_path_pool
Definition: fib_path.c:419
vlib_main_t * vm
Definition: in2out_ed.c:1599
Pop a Psuedo Wire Control Word.
Definition: fib_types.h:396
vl_api_tunnel_mode_t mode
Definition: gre.api:48
static fib_path_t * fib_path_get(fib_node_index_t index)
Definition: fib_path.c:439
ip46_address_t fp_nh
The next-hop.
Definition: fib_path.c:255
void dvr_dpo_add_or_lock(u32 sw_if_index, dpo_proto_t dproto, dpo_id_t *dpo)
Definition: dvr_dpo.c:91
format_function_t format_ip46_address
Definition: ip46_address.h:50
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1458
fib_path_oper_flags_t_
Path flags from the attributes.
Definition: fib_path.c:190
fib_node_index_t fib_table_entry_special_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags)
Add a &#39;special&#39; entry to the FIB.
Definition: fib_table.c:405
#define FOR_EACH_FIB_PATH_OPER_ATTRIBUTE(_item)
Definition: fib_path.c:182
#define MPLS_FIB_DEFAULT_TABLE_ID
Definition: mpls_fib.h:28
The path forms part of a recursive loop.
Definition: fib_path.c:152
vnet_link_t fib_forw_chain_type_to_link_type(fib_forward_chain_type_t fct)
Convert from a chain type to the adjacency&#39;s link type.
Definition: fib_types.c:446
fib_node_list_t fn_children
Vector of nodes that depend upon/use/share this node.
Definition: fib_node.h:309
u32 frp_classify_table_id
Classify table ID.
Definition: fib_types.h:575
u32 flags
Definition: vhost_user.h:248
int adj_recursive_loop_detect(adj_index_t ai, fib_node_index_t **entry_indicies)
descend the FIB graph looking for loops
Definition: adj.c:201
int bier_table_id_cmp(const bier_table_id_t *btid1, const bier_table_id_t *btid2)
Compare to BIER table IDs for equality.
Definition: bier_types.c:112
via a DVR.
Definition: fib_path.c:108
void udp_encap_lock(index_t uei)
Definition: udp_encap.c:149
Contribute an object that is to be used to forward NSH packets.
Definition: fib_types.h:147
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
u32 fp_udp_encap_id
The UDP Encap object this path resolves through.
Definition: fib_path.c:354
static void fib_path_last_lock_gone(fib_node_t *node)
Definition: fib_path.c:643
static fib_node_index_t fib_path_get_index(fib_path_t *path)
Definition: fib_path.c:445
A FIB path.
Definition: fib_path.c:201
int fib_entry_recursive_loop_detect(fib_node_index_t entry_index, fib_node_index_t **entry_indicies)
Definition: fib_entry.c:1407
fib_node_get_t fnv_get
Definition: fib_node.h:283
enum fib_path_oper_flags_t_ fib_path_oper_flags_t
Path flags from the attributes.
index_t fp_via_bier_fmask
the resolving bier-fmask
Definition: fib_path.c:395
u32 fib_path_get_rpf_id(fib_node_index_t path_index)
Definition: fib_path.c:2268
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
void interface_rx_dpo_add_or_lock(dpo_proto_t proto, u32 sw_if_index, dpo_id_t *dpo)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:299
Don&#39;t resolve the path, use the DPO the client provides.
Definition: fib_types.h:350
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
void fib_prefix_from_ip46_addr(const ip46_address_t *addr, fib_prefix_t *pfx)
Host prefix from ip.
Definition: fib_types.c:81
static void fib_path_memory_show(void)
Definition: fib_path.c:1232
The path is attached, despite what the next-hop may say.
Definition: fib_path.c:160
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:186
void fib_prefix_from_mpls_label(mpls_label_t label, mpls_eos_bit_t eos, fib_prefix_t *prf)
Definition: fib_types.c:158
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1599
static fib_node_back_walk_rc_t fib_path_back_walk_notify(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
Definition: fib_path.c:997
Path resolves via a UDP encap object.
Definition: fib_path.c:88
enum lookup_input_t_ lookup_input_t
Switch to use the packet&#39;s source or destination address for lookup.
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
Definition: fib_table.c:1310
Context passed between object during a back walk.
Definition: fib_node.h:208
u32 fib_rpf_id_t
An RPF-ID is numerical value that is used RPF validate.
Definition: fib_types.h:411
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
u32 fp_pl_index
The index of the path-list to which this path belongs.
Definition: fib_path.c:210
static void fib_path_recursive_adj_update(fib_path_t *path, fib_forward_chain_type_t fct, dpo_id_t *dpo)
Definition: fib_path.c:759
#define ASSERT(truth)
int fib_path_is_deag(fib_node_index_t path_index)
Definition: fib_path.c:2673
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
vnet_link_t dpo_proto_to_link(dpo_proto_t dp)
format a DPO protocol
Definition: dpo.c:118
fib_node_index_t fp_via_fib
the resolving via fib.
Definition: fib_path.c:387
static int fib_path_is_permanent_drop(fib_path_t *path)
Definition: fib_path.c:889
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
index_t bier_table_ecmp_create_and_lock(const bier_table_id_t *btid)
Definition: bier_table.c:456
ip46_address_t fp_addr
The next-hop.
Definition: fib_path.c:342
static fib_forward_chain_type_t fib_path_to_chain_type(const fib_path_t *path)
Definition: fib_path.c:971
u8 frp_preference
A path preference.
Definition: fib_types.h:596
bier_table_id_t fp_bier_tbl
The BIER table&#39;s ID.
Definition: fib_path.c:306
uword hash_memory(void *p, word n_bytes, uword state)
Definition: hash.c:275
Path encode context to use when walking a path-list to encode paths.
Definition: fib_path.h:213
A deag path using the packet&#39;s source not destination address.
Definition: fib_types.h:363
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:600
static void fib_path_attached_get_adj(fib_path_t *path, vnet_link_t link, dpo_id_t *dpo)
Definition: fib_path.c:715
u32 fp_interface
The interface.
Definition: fib_path.c:259
static clib_error_t * show_fib_path_command(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: fib_path.c:2807
vlib_log_class_t fib_path_logger
the logger
Definition: fib_path.c:424
int dpo_cmp(const dpo_id_t *dpo1, const dpo_id_t *dpo2)
Compare two Data-path objects.
Definition: dpo.c:249
struct fib_path_t_::@257::@268 special
struct fib_path_t_::@257::@274 dvr
A path that resolves via a BIER F-Mask.
Definition: fib_types.h:371
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject.
Definition: dpo.c:148
A path that resolves via another table.
Definition: fib_types.h:383
u32 entries
struct fib_path_t_::@257::@262 attached
format_function_t format_mpls_unicast_label
Definition: mpls.h:71
static void fib_path_unresolve(fib_path_t *path)
Definition: fib_path.c:901
fib_route_path_t * rpaths
Definition: fib_path.h:215
mpls_label_t frp_local_label
The MPLS local Label to reursively resolve through.
Definition: fib_types.h:513
dpo_proto_t fib_path_get_proto(fib_node_index_t path_index)
Definition: fib_path.c:2790
fib_path_oper_flags_t fp_oper_flags
Memebers in this last section represent information that is dervied during resolution.
Definition: fib_path.c:380
int fib_path_is_recursive_constrained(fib_node_index_t path_index)
Definition: fib_path.c:2651
void fib_path_list_back_walk(fib_node_index_t path_list_index, fib_node_back_walk_ctx_t *ctx)
Attached-nexthop.
Definition: fib_path.c:60
enum fib_path_list_walk_rc_t_ fib_path_list_walk_rc_t
return code to control pat-hlist walk
u32 fib_path_get_resolving_interface(fib_node_index_t path_index)
Definition: fib_path.c:2162
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:186
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
A for-us/local path.
Definition: fib_types.h:338
u32 path_weight
weight for the path.
Definition: load_balance.h:76
u32 adj_child_add(adj_index_t adj_index, fib_node_type_t child_type, fib_node_index_t child_index)
Add a child dependent to an adjacency.
Definition: adj.c:344
struct fib_path_t_::@257::@261 attached_next_hop
u16 fib_path_get_preference(fib_node_index_t path_index)
Definition: fib_path.c:2256
u64 uword
Definition: types.h:112
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
#define FIB_PATH_DBG(_p, _fmt, _args...)
Definition: fib_path.c:429
adj_index_t adj_glean_add_or_lock(fib_protocol_t proto, vnet_link_t linkt, u32 sw_if_index, const ip46_address_t *nh_addr)
Glean Adjacency.
Definition: adj_glean.c:50
fib_node_index_t fib_path_create(fib_node_index_t pl_index, const fib_route_path_t *rpath)
Definition: fib_path.c:1290
u8 fp_weight
UCMP [unnormalised] weigth.
Definition: fib_path.c:238
One path from an [EU]CMP set that the client wants to add to a load-balance object.
Definition: load_balance.h:62
enum fib_path_cfg_flags_t_ fib_path_cfg_flags_t
Path config flags from the attributes.
u8 * format_dpo_proto(u8 *s, va_list *args)
format a DPO protocol
Definition: dpo.c:178
int fib_path_recursive_loop_detect(fib_node_index_t path_index, fib_node_index_t **entry_indicies)
Definition: fib_path.c:1813
A FIB graph nodes virtual function table.
Definition: fib_node.h:282
static fib_path_cfg_flags_t fib_path_route_flags_to_cfg_flags(const fib_route_path_t *rpath)
Definition: fib_path.c:1251
struct fib_path_t_::@257::@263 recursive
int dpo_is_drop(const dpo_id_t *dpo)
The Drop DPO will drop all packets, no questions asked.
Definition: drop_dpo.c:33
adj_index_t adj_mcast_add_or_lock(fib_protocol_t proto, vnet_link_t link_type, u32 sw_if_index)
Mcast Adjacency.
Definition: adj_mcast.c:51
adj_index_t adj_nbr_add_or_lock(fib_protocol_t nh_proto, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index)
Neighbour Adjacency sub-type.
Definition: adj_nbr.c:217
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
mpls_label_t fp_local_label
The local label to resolve through.
Definition: fib_path.c:278
#define vec_foreach(var, vec)
Vector iterator.
A path extension is a per-entry addition to the forwarding information when packets are sent for that...
Definition: fib_path_ext.h:98
fib_path_type_t_
Enurmeration of path types.
Definition: fib_path.c:52
Contribute an object that is to be used to forward non-end-of-stack MPLS packets. ...
Definition: fib_types.h:118
Attached path.
Definition: fib_types.h:342
void udp_encap_unlock(index_t uei)
Definition: udp_encap.c:162
struct fib_path_t_::@257::@269 exclusive
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:558
u8 * fib_node_children_format(fib_node_list_t list, u8 *s)
Definition: fib_node.c:176
u8 fp_preference
A path preference.
Definition: fib_path.c:245
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:590
static fib_path_t * fib_path_attached_next_hop_get_adj(fib_path_t *path, vnet_link_t link, dpo_id_t *dpo)
Definition: fib_path.c:649
fib_source_t fib_entry_get_best_source(fib_node_index_t entry_index)
Definition: fib_entry.c:1468
u32 frp_udp_encap_id
UDP encap ID.
Definition: fib_types.h:570
enum fib_path_oper_attribute_t_ fib_path_oper_attribute_t
Enurmeration of path operational (i.e.
struct fib_path_t_::@257::@265 bier_table
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:133
u32 bier_fmask_child_add(fib_node_index_t bfmi, fib_node_type_t child_type, fib_node_index_t child_index)
Definition: bier_fmask.c:141
void bier_imp_unlock(index_t bii)
Definition: bier_imp.c:110
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:542
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:408
void fib_path_destroy(fib_node_index_t path_index)
Definition: fib_path.c:1518
#define FOR_EACH_FIB_PATH_CFG_ATTRIBUTE(_item)
Definition: fib_path.h:129
static int fib_path_cmp_i(const fib_path_t *path1, const fib_path_t *path2)
Definition: fib_path.c:1557
const ip46_address_t zero_addr
Definition: lookup.c:181
int fib_path_cmp_w_route_path(fib_node_index_t path_index, const fib_route_path_t *rpath)
Definition: fib_path.c:1691
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
fib_route_path_t fpe_path
A description of the path that is being extended.
Definition: fib_path_ext.h:105
fib_path_list_walk_rc_t fib_path_encode(fib_node_index_t path_list_index, fib_node_index_t path_index, const fib_path_ext_t *path_ext, void *args)
Definition: fib_path.c:2706
void udp_encap_contribute_forwarding(index_t uei, dpo_proto_t proto, dpo_id_t *dpo)
Definition: udp_encap.c:131
static fib_node_t * fib_path_get_node(fib_node_index_t index)
Definition: fib_path.c:451
enum mpls_eos_bit_t_ mpls_eos_bit_t
index_t fp_bier_fib
The BIER FIB the fmask is in.
Definition: fib_path.c:293
fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:291
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128