FD.io VPP  v21.01.1
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 } __attribute__ ((packed)) fib_path_type_t;
110 
111 #define FIB_PATH_TYPES { \
112  [FIB_PATH_TYPE_ATTACHED_NEXT_HOP] = "attached-nexthop", \
113  [FIB_PATH_TYPE_ATTACHED] = "attached", \
114  [FIB_PATH_TYPE_RECURSIVE] = "recursive", \
115  [FIB_PATH_TYPE_SPECIAL] = "special", \
116  [FIB_PATH_TYPE_EXCLUSIVE] = "exclusive", \
117  [FIB_PATH_TYPE_DEAG] = "deag", \
118  [FIB_PATH_TYPE_INTF_RX] = "intf-rx", \
119  [FIB_PATH_TYPE_UDP_ENCAP] = "udp-encap", \
120  [FIB_PATH_TYPE_RECEIVE] = "receive", \
121  [FIB_PATH_TYPE_BIER_IMP] = "bier-imp", \
122  [FIB_PATH_TYPE_BIER_TABLE] = "bier-table", \
123  [FIB_PATH_TYPE_BIER_FMASK] = "bier-fmask", \
124  [FIB_PATH_TYPE_DVR] = "dvr", \
125 }
126 
127 /**
128  * Enurmeration of path operational (i.e. derived) attributes
129  */
131  /**
132  * Marker. Add new types after this one.
133  */
135  /**
136  * The path forms part of a recursive loop.
137  */
139  /**
140  * The path is resolved
141  */
143  /**
144  * The path has become a permanent drop.
145  */
147  /**
148  * Marker. Add new types before this one, then update it.
149  */
151 } __attribute__ ((packed)) fib_path_oper_attribute_t;
152 
153 /**
154  * The maximum number of path operational attributes
155  */
156 #define FIB_PATH_OPER_ATTRIBUTE_MAX (FIB_PATH_OPER_ATTRIBUTE_LAST + 1)
157 
158 #define FIB_PATH_OPER_ATTRIBUTES { \
159  [FIB_PATH_OPER_ATTRIBUTE_RECURSIVE_LOOP] = "recursive-loop", \
160  [FIB_PATH_OPER_ATTRIBUTE_RESOLVED] = "resolved", \
161  [FIB_PATH_OPER_ATTRIBUTE_DROP] = "drop", \
162 }
163 
164 #define FOR_EACH_FIB_PATH_OPER_ATTRIBUTE(_item) \
165  for (_item = FIB_PATH_OPER_ATTRIBUTE_FIRST; \
166  _item <= FIB_PATH_OPER_ATTRIBUTE_LAST; \
167  _item++)
168 
169 /**
170  * Path flags from the attributes
171  */
177 } __attribute__ ((packed)) fib_path_oper_flags_t;
178 
179 /**
180  * A FIB path
181  */
182 typedef struct fib_path_t_ {
183  /**
184  * A path is a node in the FIB graph.
185  */
187 
188  /**
189  * The index of the path-list to which this path belongs
190  */
192 
193  /**
194  * This marks the start of the memory area used to hash
195  * the path
196  */
197  STRUCT_MARK(path_hash_start);
198 
199  /**
200  * Configuration Flags
201  */
203 
204  /**
205  * The type of the path. This is the selector for the union
206  */
207  fib_path_type_t fp_type;
208 
209  /**
210  * The protocol of the next-hop, i.e. the address family of the
211  * next-hop's address. We can't derive this from the address itself
212  * since the address can be all zeros
213  */
215 
216  /**
217  * UCMP [unnormalised] weigth
218  */
220 
221  /**
222  * A path preference. 0 is the best.
223  * Only paths of the best preference, that are 'up', are considered
224  * for forwarding.
225  */
227 
228  /**
229  * per-type union of the data required to resolve the path
230  */
231  union {
232  struct {
233  /**
234  * The next-hop
235  */
236  ip46_address_t fp_nh;
237  /**
238  * The interface
239  */
242  struct {
243  /**
244  * The Connected local address
245  */
247  /**
248  * The interface
249  */
251  } attached;
252  struct {
253  union
254  {
255  /**
256  * The next-hop
257  */
258  ip46_address_t fp_ip;
259  struct {
260  /**
261  * The local label to resolve through.
262  */
264  /**
265  * The EOS bit of the resolving label
266  */
268  };
269  } fp_nh;
270  /**
271  * The FIB table index in which to find the next-hop.
272  */
274  } recursive;
275  struct {
276  /**
277  * BIER FMask ID
278  */
280  } bier_fmask;
281  struct {
282  /**
283  * The BIER table's ID
284  */
286  } bier_table;
287  struct {
288  /**
289  * The BIER imposition object
290  * this is part of the path's key, since the index_t
291  * of an imposition object is the object's key.
292  */
294  } bier_imp;
295  struct {
296  /**
297  * The FIB index in which to perfom the next lookup
298  */
300  /**
301  * The RPF-ID to tag the packets with
302  */
304  } deag;
305  struct {
306  } special;
307  struct {
308  /**
309  * The user provided 'exclusive' DPO
310  */
312  } exclusive;
313  struct {
314  /**
315  * The interface on which the local address is configured
316  */
318  /**
319  * The next-hop
320  */
321  ip46_address_t fp_addr;
322  } receive;
323  struct {
324  /**
325  * The interface on which the packets will be input.
326  */
328  } intf_rx;
329  struct {
330  /**
331  * The UDP Encap object this path resolves through
332  */
334  } udp_encap;
335  struct {
336  /**
337  * The UDP Encap object this path resolves through
338  */
340  } classify;
341  struct {
342  /**
343  * The interface
344  */
346  } dvr;
347  };
348  STRUCT_MARK(path_hash_end);
349 
350  /**
351  * Members in this last section represent information that is
352  * dervied during resolution. It should not be copied to new paths
353  * nor compared.
354  */
355 
356  /**
357  * Operational Flags
358  */
360 
361  union {
362  /**
363  * the resolving via fib. not part of the union, since it it not part
364  * of the path's hash.
365  */
367  /**
368  * the resolving bier-table
369  */
371  /**
372  * the resolving bier-fmask
373  */
375  };
376 
377  /**
378  * The Data-path objects through which this path resolves for IP.
379  */
381 
382  /**
383  * the index of this path in the parent's child list.
384  */
386 } fib_path_t;
387 
388 /*
389  * Array of strings/names for the path types and attributes
390  */
391 static const char *fib_path_type_names[] = FIB_PATH_TYPES;
392 static const char *fib_path_oper_attribute_names[] = FIB_PATH_OPER_ATTRIBUTES;
393 static const char *fib_path_cfg_attribute_names[] = FIB_PATH_CFG_ATTRIBUTES;
394 
395 /*
396  * The memory pool from which we allocate all the paths
397  */
399 
400 /**
401  * the logger
402  */
404 
405 /*
406  * Debug macro
407  */
408 #define FIB_PATH_DBG(_p, _fmt, _args...) \
409 { \
410  vlib_log_debug (fib_path_logger, \
411  "[%U]: " _fmt, \
412  format_fib_path, fib_path_get_index(_p), 0, \
413  FIB_PATH_FORMAT_FLAGS_ONE_LINE, \
414  ##_args); \
415 }
416 
417 static fib_path_t *
419 {
420  return (pool_elt_at_index(fib_path_pool, index));
421 }
422 
423 static fib_node_index_t
425 {
426  return (path - fib_path_pool);
427 }
428 
429 static fib_node_t *
431 {
432  return ((fib_node_t*)fib_path_get(index));
433 }
434 
435 static fib_path_t*
437 {
439  return ((fib_path_t*)node);
440 }
441 
442 u8 *
443 format_fib_path (u8 * s, va_list * args)
444 {
445  fib_node_index_t path_index = va_arg (*args, fib_node_index_t);
446  u32 indent = va_arg (*args, u32);
448  vnet_main_t * vnm = vnet_get_main();
449  fib_path_oper_attribute_t oattr;
451  fib_path_t *path;
452  const char *eol;
453 
454  if (flags & FIB_PATH_FORMAT_FLAGS_ONE_LINE)
455  {
456  eol = "";
457  }
458  else
459  {
460  eol = "\n";
461  }
462 
463  path = fib_path_get(path_index);
464 
465  s = format (s, "%Upath:[%d] ", format_white_space, indent,
466  fib_path_get_index(path));
467  s = format (s, "pl-index:%d ", path->fp_pl_index);
468  s = format (s, "%U ", format_dpo_proto, path->fp_nh_proto);
469  s = format (s, "weight=%d ", path->fp_weight);
470  s = format (s, "pref=%d ", path->fp_preference);
471  s = format (s, "%s: ", fib_path_type_names[path->fp_type]);
472  if (FIB_PATH_OPER_FLAG_NONE != path->fp_oper_flags) {
473  s = format(s, " oper-flags:");
475  if ((1<<oattr) & path->fp_oper_flags) {
476  s = format (s, "%s,", fib_path_oper_attribute_names[oattr]);
477  }
478  }
479  }
480  if (FIB_PATH_CFG_FLAG_NONE != path->fp_cfg_flags) {
481  s = format(s, " cfg-flags:");
483  if ((1<<cattr) & path->fp_cfg_flags) {
484  s = format (s, "%s,", fib_path_cfg_attribute_names[cattr]);
485  }
486  }
487  }
488  if (!(flags & FIB_PATH_FORMAT_FLAGS_ONE_LINE))
489  s = format(s, "\n%U", format_white_space, indent+2);
490 
491  switch (path->fp_type)
492  {
494  s = format (s, "%U", format_ip46_address,
495  &path->attached_next_hop.fp_nh,
496  IP46_TYPE_ANY);
498  {
499  s = format (s, " if_index:%d", path->attached_next_hop.fp_interface);
500  }
501  else
502  {
503  s = format (s, " %U",
505  vnm,
507  vnm,
508  path->attached_next_hop.fp_interface));
510  path->attached_next_hop.fp_interface))
511  {
512  s = format (s, " (p2p)");
513  }
514  }
515  if (!dpo_id_is_valid(&path->fp_dpo))
516  {
517  s = format(s, "%s%Uunresolved", eol, format_white_space, indent+2);
518  }
519  else
520  {
521  s = format(s, "%s%U%U", eol,
522  format_white_space, indent,
524  &path->fp_dpo, 13);
525  }
526  break;
529  {
530  s = format (s, "if_index:%d", path->attached_next_hop.fp_interface);
531  }
532  else
533  {
534  s = format (s, " %U",
536  vnm,
538  vnm,
539  path->attached.fp_interface));
540  }
541  break;
543  if (DPO_PROTO_MPLS == path->fp_nh_proto)
544  {
545  s = format (s, "via %U %U",
547  path->recursive.fp_nh.fp_local_label,
549  path->recursive.fp_nh.fp_eos);
550  }
551  else
552  {
553  s = format (s, "via %U",
555  &path->recursive.fp_nh.fp_ip,
556  IP46_TYPE_ANY);
557  }
558  s = format (s, " in fib:%d",
559  path->recursive.fp_tbl_id,
560  path->fp_via_fib);
561  s = format (s, " via-fib:%d", path->fp_via_fib);
562  s = format (s, " via-dpo:[%U:%d]",
564  path->fp_dpo.dpoi_index);
565 
566  break;
568  s = format (s, "UDP-encap ID:%d", path->udp_encap.fp_udp_encap_id);
569  break;
571  s = format (s, "via bier-table:[%U}",
573  &path->bier_table.fp_bier_tbl);
574  s = format (s, " via-dpo:[%U:%d]",
576  path->fp_dpo.dpoi_index);
577  break;
579  s = format (s, "via-fmask:%d", path->bier_fmask.fp_bier_fmask);
580  s = format (s, " via-dpo:[%U:%d]",
582  path->fp_dpo.dpoi_index);
583  break;
585  s = format (s, "via %U", format_bier_imp,
586  path->bier_imp.fp_bier_imp, 0, BIER_SHOW_BRIEF);
587  break;
588  case FIB_PATH_TYPE_DVR:
589  s = format (s, " %U",
591  vnm,
593  vnm,
594  path->dvr.fp_interface));
595  break;
596  case FIB_PATH_TYPE_DEAG:
597  s = format (s, " %sfib-index:%d",
598  (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ? "m" : ""),
599  path->deag.fp_tbl_id);
600  break;
605  if (dpo_id_is_valid(&path->fp_dpo))
606  {
607  s = format(s, "%U", format_dpo_id,
608  &path->fp_dpo, indent+2);
609  }
610  break;
611  }
612  return (s);
613 }
614 
615 /*
616  * fib_path_last_lock_gone
617  *
618  * We don't share paths, we share path lists, so the [un]lock functions
619  * are no-ops
620  */
621 static void
623 {
624  ASSERT(0);
625 }
626 
627 static fib_path_t*
629  vnet_link_t link,
630  dpo_id_t *dpo)
631 {
632  fib_node_index_t fib_path_index;
633  fib_protocol_t nh_proto;
634  adj_index_t ai;
635 
636  fib_path_index = fib_path_get_index(path);
637  nh_proto = dpo_proto_to_fib(path->fp_nh_proto);
638 
640  path->attached_next_hop.fp_interface))
641  {
642  /*
643  * if the interface is p2p then the adj for the specific
644  * neighbour on that link will never exist. on p2p links
645  * the subnet address (the attached route) links to the
646  * auto-adj (see below), we want that adj here too.
647  */
648  ai = adj_nbr_add_or_lock(nh_proto, link, &zero_addr,
649  path->attached_next_hop.fp_interface);
650  }
651  else
652  {
653  ai = adj_nbr_add_or_lock(nh_proto, link,
654  &path->attached_next_hop.fp_nh,
655  path->attached_next_hop.fp_interface);
656  }
657 
659  adj_unlock(ai);
660 
661  return (fib_path_get(fib_path_index));
662 }
663 
664 static void
666 {
667  /*
668  * resolve directly via the adjacency discribed by the
669  * interface and next-hop
670  */
673  &path->fp_dpo);
674 
675  ASSERT(dpo_is_adj(&path->fp_dpo));
676 
677  /*
678  * become a child of the adjacency so we receive updates
679  * when its rewrite changes
680  */
683  fib_path_get_index(path));
684 
686  path->attached_next_hop.fp_interface) ||
687  !adj_is_up(path->fp_dpo.dpoi_index))
688  {
690  }
691 }
692 
693 static void
695  vnet_link_t link,
696  dpo_id_t *dpo)
697 {
698  fib_protocol_t nh_proto;
699 
700  nh_proto = dpo_proto_to_fib(path->fp_nh_proto);
701 
703  path->attached.fp_interface))
704  {
705  /*
706  * point-2-point interfaces do not require a glean, since
707  * there is nothing to ARP. Install a rewrite/nbr adj instead
708  */
709  adj_index_t ai;
710 
711  ai = adj_nbr_add_or_lock(nh_proto, link, &zero_addr,
712  path->attached.fp_interface);
713 
715  adj_unlock(ai);
716  }
718  path->attached.fp_interface))
719  {
720  dpo_copy(dpo, drop_dpo_get(path->fp_nh_proto));
721  }
722  else
723  {
724  adj_index_t ai;
725 
726  ai = adj_glean_add_or_lock(nh_proto, link,
727  path->attached.fp_interface,
728  &path->attached.fp_connected);
730  adj_unlock(ai);
731  }
732 }
733 
734 /*
735  * create of update the paths recursive adj
736  */
737 static void
740  dpo_id_t *dpo)
741 {
742  dpo_id_t via_dpo = DPO_INVALID;
743 
744  /*
745  * get the DPO to resolve through from the via-entry
746  */
748  fct,
749  &via_dpo);
750 
751 
752  /*
753  * hope for the best - clear if restrictions apply.
754  */
756 
757  /*
758  * Validate any recursion constraints and over-ride the via
759  * adj if not met
760  */
762  {
764  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
765  }
767  {
768  /*
769  * the via FIB must be a host route.
770  * note the via FIB just added will always be a host route
771  * since it is an RR source added host route. So what we need to
772  * check is whether the route has other sources. If it does then
773  * some other source has added it as a host route. If it doesn't
774  * then it was added only here and inherits forwarding from a cover.
775  * the cover is not a host route.
776  * The RR source is the lowest priority source, so we check if it
777  * is the best. if it is there are no other sources.
778  */
780  {
782  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
783 
784  /*
785  * PIC edge trigger. let the load-balance maps know
786  */
788  }
789  }
791  {
792  /*
793  * RR source entries inherit the flags from the cover, so
794  * we can check the via directly
795  */
797  {
799  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
800 
801  /*
802  * PIC edge trigger. let the load-balance maps know
803  */
805  }
806  }
807  /*
808  * check for over-riding factors on the FIB entry itself
809  */
810  if (!fib_entry_is_resolved(path->fp_via_fib))
811  {
813  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
814 
815  /*
816  * PIC edge trigger. let the load-balance maps know
817  */
819  }
820 
821  /*
822  * If this path is contributing a drop, then it's not resolved
823  */
824  if (dpo_is_drop(&via_dpo) || load_balance_is_drop(&via_dpo))
825  {
827  }
828 
829  /*
830  * update the path's contributed DPO
831  */
832  dpo_copy(dpo, &via_dpo);
833 
834  FIB_PATH_DBG(path, "recursive update:");
835 
836  dpo_reset(&via_dpo);
837 }
838 
839 /*
840  * re-evaulate the forwarding state for a via fmask path
841  */
842 static void
844  dpo_id_t *dpo)
845 {
846  bier_fmask_contribute_forwarding(path->bier_fmask.fp_bier_fmask, dpo);
847 
848  /*
849  * if we are stakcing on the drop, then the path is not resolved
850  */
851  if (dpo_is_drop(dpo))
852  {
854  }
855  else
856  {
858  }
859 }
860 
861 /*
862  * fib_path_is_permanent_drop
863  *
864  * Return !0 if the path is configured to permanently drop,
865  * despite other attributes.
866  */
867 static int
869 {
870  return ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DROP) ||
872 }
873 
874 /*
875  * fib_path_unresolve
876  *
877  * Remove our dependency on the resolution target
878  */
879 static void
881 {
882  /*
883  * the forced drop path does not need unresolving
884  */
885  if (fib_path_is_permanent_drop(path))
886  {
887  return;
888  }
889 
890  switch (path->fp_type)
891  {
893  if (FIB_NODE_INDEX_INVALID != path->fp_via_fib)
894  {
896  path->fp_sibling);
899  FIB_SOURCE_RR);
900  fib_table_unlock(path->recursive.fp_tbl_id,
902  FIB_SOURCE_RR);
904  }
905  break;
908  path->fp_sibling);
909  break;
912  break;
915  break;
918  if (dpo_is_adj(&path->fp_dpo))
920  path->fp_sibling);
921  break;
924  break;
926  dpo_reset(&path->exclusive.fp_ex_dpo);
927  break;
931  case FIB_PATH_TYPE_DEAG:
932  case FIB_PATH_TYPE_DVR:
933  /*
934  * these hold only the path's DPO, which is reset below.
935  */
936  break;
937  }
938 
939  /*
940  * release the adj we were holding and pick up the
941  * drop just in case.
942  */
943  dpo_reset(&path->fp_dpo);
945 
946  return;
947 }
948 
951 {
952  if (DPO_PROTO_MPLS == path->fp_nh_proto)
953  {
954  if (FIB_PATH_TYPE_RECURSIVE == path->fp_type &&
955  MPLS_EOS == path->recursive.fp_nh.fp_eos)
956  {
958  }
959  else
960  {
962  }
963  }
964  else
965  {
967  }
968 }
969 
970 /*
971  * fib_path_back_walk_notify
972  *
973  * A back walk has reach this path.
974  */
978 {
979  fib_path_t *path;
980 
981  path = fib_path_from_fib_node(node);
982 
983  FIB_PATH_DBG(path, "bw:%U",
985 
986  switch (path->fp_type)
987  {
990  {
991  /*
992  * modify the recursive adjacency to use the new forwarding
993  * of the via-fib.
994  * this update is visible to packets in flight in the DP.
995  */
997  path,
999  &path->fp_dpo);
1000  }
1003  {
1004  /*
1005  * ADJ updates (complete<->incomplete) do not need to propagate to
1006  * recursive entries.
1007  * The only reason its needed as far back as here, is that the adj
1008  * and the incomplete adj are a different DPO type, so the LBs need
1009  * to re-stack.
1010  * If this walk was quashed in the fib_entry, then any non-fib_path
1011  * children (like tunnels that collapse out the LB when they stack)
1012  * would not see the update.
1013  */
1014  return (FIB_NODE_BACK_WALK_CONTINUE);
1015  }
1016  break;
1019  {
1020  /*
1021  * update to use the BIER fmask's new forwading
1022  */
1023  fib_path_bier_fmask_update(path, &path->fp_dpo);
1024  }
1027  {
1028  /*
1029  * ADJ updates (complete<->incomplete) do not need to propagate to
1030  * recursive entries.
1031  * The only reason its needed as far back as here, is that the adj
1032  * and the incomplete adj are a different DPO type, so the LBs need
1033  * to re-stack.
1034  * If this walk was quashed in the fib_entry, then any non-fib_path
1035  * children (like tunnels that collapse out the LB when they stack)
1036  * would not see the update.
1037  */
1038  return (FIB_NODE_BACK_WALK_CONTINUE);
1039  }
1040  break;
1042  /*
1043 FIXME comment
1044  * ADJ_UPDATE backwalk pass silently through here and up to
1045  * the path-list when the multipath adj collapse occurs.
1046  * The reason we do this is that the assumtption is that VPP
1047  * runs in an environment where the Control-Plane is remote
1048  * and hence reacts slowly to link up down. In order to remove
1049  * this down link from the ECMP set quickly, we back-walk.
1050  * VPP also has dedicated CPUs, so we are not stealing resources
1051  * from the CP to do so.
1052  */
1054  {
1056  {
1057  /*
1058  * alreday resolved. no need to walk back again
1059  */
1060  return (FIB_NODE_BACK_WALK_CONTINUE);
1061  }
1063  }
1065  {
1067  {
1068  /*
1069  * alreday unresolved. no need to walk back again
1070  */
1071  return (FIB_NODE_BACK_WALK_CONTINUE);
1072  }
1074  }
1076  {
1077  /*
1078  * The interface this path resolves through has been deleted.
1079  * This will leave the path in a permanent drop state. The route
1080  * needs to be removed and readded (and hence the path-list deleted)
1081  * before it can forward again.
1082  */
1083  fib_path_unresolve(path);
1085  }
1087  {
1088  /*
1089  * restack the DPO to pick up the correct DPO sub-type
1090  */
1091  uword if_is_up;
1092 
1093  if_is_up = vnet_sw_interface_is_up(
1094  vnet_get_main(),
1095  path->attached_next_hop.fp_interface);
1096 
1098  path,
1100  &path->fp_dpo);
1101 
1103  if (if_is_up && adj_is_up(path->fp_dpo.dpoi_index))
1104  {
1106  }
1107 
1108  if (!if_is_up)
1109  {
1110  /*
1111  * If the interface is not up there is no reason to walk
1112  * back to children. if we did they would only evalute
1113  * that this path is unresolved and hence it would
1114  * not contribute the adjacency - so it would be wasted
1115  * CPU time.
1116  */
1117  return (FIB_NODE_BACK_WALK_CONTINUE);
1118  }
1119  }
1121  {
1123  {
1124  /*
1125  * alreday unresolved. no need to walk back again
1126  */
1127  return (FIB_NODE_BACK_WALK_CONTINUE);
1128  }
1129  /*
1130  * the adj has gone down. the path is no longer resolved.
1131  */
1133  }
1134  break;
1136  case FIB_PATH_TYPE_DVR:
1137  /*
1138  * FIXME; this could schedule a lower priority walk, since attached
1139  * routes are not usually in ECMP configurations so the backwalk to
1140  * the FIB entry does not need to be high priority
1141  */
1143  {
1145  }
1147  {
1149  }
1151  {
1152  fib_path_unresolve(path);
1154  }
1155  break;
1157  {
1158  dpo_id_t via_dpo = DPO_INVALID;
1159 
1160  /*
1161  * hope for the best - clear if restrictions apply.
1162  */
1164 
1165  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
1166  path->fp_nh_proto,
1167  &via_dpo);
1168  /*
1169  * If this path is contributing a drop, then it's not resolved
1170  */
1171  if (dpo_is_drop(&via_dpo) || load_balance_is_drop(&via_dpo))
1172  {
1174  }
1175 
1176  /*
1177  * update the path's contributed DPO
1178  */
1179  dpo_copy(&path->fp_dpo, &via_dpo);
1180  dpo_reset(&via_dpo);
1181  break;
1182  }
1183  case FIB_PATH_TYPE_INTF_RX:
1184  ASSERT(0);
1185  case FIB_PATH_TYPE_DEAG:
1186  /*
1187  * FIXME When VRF delete is allowed this will need a poke.
1188  */
1189  case FIB_PATH_TYPE_SPECIAL:
1190  case FIB_PATH_TYPE_RECEIVE:
1194  /*
1195  * these path types have no parents. so to be
1196  * walked from one is unexpected.
1197  */
1198  ASSERT(0);
1199  break;
1200  }
1201 
1202  /*
1203  * propagate the backwalk further to the path-list
1204  */
1206 
1207  return (FIB_NODE_BACK_WALK_CONTINUE);
1208 }
1209 
1210 static void
1212 {
1213  fib_show_memory_usage("Path",
1214  pool_elts(fib_path_pool),
1215  pool_len(fib_path_pool),
1216  sizeof(fib_path_t));
1217 }
1218 
1219 /*
1220  * The FIB path's graph node virtual function table
1221  */
1222 static const fib_node_vft_t fib_path_vft = {
1224  .fnv_last_lock = fib_path_last_lock_gone,
1225  .fnv_back_walk = fib_path_back_walk_notify,
1226  .fnv_mem_show = fib_path_memory_show,
1227 };
1228 
1229 static fib_path_cfg_flags_t
1231 {
1233 
1234  if (rpath->frp_flags & FIB_ROUTE_PATH_POP_PW_CW)
1235  cfg_flags |= FIB_PATH_CFG_FLAG_POP_PW_CW;
1237  cfg_flags |= FIB_PATH_CFG_FLAG_RESOLVE_HOST;
1240  if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
1241  cfg_flags |= FIB_PATH_CFG_FLAG_LOCAL;
1242  if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED)
1243  cfg_flags |= FIB_PATH_CFG_FLAG_ATTACHED;
1244  if (rpath->frp_flags & FIB_ROUTE_PATH_INTF_RX)
1245  cfg_flags |= FIB_PATH_CFG_FLAG_INTF_RX;
1246  if (rpath->frp_flags & FIB_ROUTE_PATH_RPF_ID)
1247  cfg_flags |= FIB_PATH_CFG_FLAG_RPF_ID;
1248  if (rpath->frp_flags & FIB_ROUTE_PATH_EXCLUSIVE)
1249  cfg_flags |= FIB_PATH_CFG_FLAG_EXCLUSIVE;
1250  if (rpath->frp_flags & FIB_ROUTE_PATH_DROP)
1251  cfg_flags |= FIB_PATH_CFG_FLAG_DROP;
1253  cfg_flags |= FIB_PATH_CFG_FLAG_DEAG_SRC;
1255  cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_UNREACH;
1257  cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_PROHIBIT;
1258  if (rpath->frp_flags & FIB_ROUTE_PATH_GLEAN)
1259  cfg_flags |= FIB_PATH_CFG_FLAG_GLEAN;
1260 
1261  return (cfg_flags);
1262 }
1263 
1264 /*
1265  * fib_path_create
1266  *
1267  * Create and initialise a new path object.
1268  * return the index of the path.
1269  */
1272  const fib_route_path_t *rpath)
1273 {
1274  fib_path_t *path;
1275 
1276  pool_get(fib_path_pool, path);
1277  clib_memset(path, 0, sizeof(*path));
1278 
1279  fib_node_init(&path->fp_node,
1281 
1282  dpo_reset(&path->fp_dpo);
1283  path->fp_pl_index = pl_index;
1284  path->fp_nh_proto = rpath->frp_proto;
1286  path->fp_weight = rpath->frp_weight;
1287  if (0 == path->fp_weight)
1288  {
1289  /*
1290  * a weight of 0 is a meaningless value. We could either reject it, and thus force
1291  * clients to always use 1, or we can accept it and fixup approrpiately.
1292  */
1293  path->fp_weight = 1;
1294  }
1295  path->fp_preference = rpath->frp_preference;
1297 
1298  /*
1299  * deduce the path's tpye from the parementers and save what is needed.
1300  */
1302  {
1304  path->receive.fp_interface = rpath->frp_sw_if_index;
1305  path->receive.fp_addr = rpath->frp_addr;
1306  }
1307  else if (rpath->frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
1308  {
1310  path->udp_encap.fp_udp_encap_id = rpath->frp_udp_encap_id;
1311  }
1312  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_INTF_RX)
1313  {
1315  path->intf_rx.fp_interface = rpath->frp_sw_if_index;
1316  }
1317  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID)
1318  {
1319  path->fp_type = FIB_PATH_TYPE_DEAG;
1320  path->deag.fp_tbl_id = rpath->frp_fib_index;
1321  path->deag.fp_rpf_id = rpath->frp_rpf_id;
1322  }
1323  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_FMASK)
1324  {
1326  path->bier_fmask.fp_bier_fmask = rpath->frp_bier_fmask;
1327  }
1328  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_IMP)
1329  {
1331  path->bier_imp.fp_bier_imp = rpath->frp_bier_imp;
1332  }
1333  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_TABLE)
1334  {
1336  path->bier_table.fp_bier_tbl = rpath->frp_bier_tbl;
1337  }
1338  else if (rpath->frp_flags & FIB_ROUTE_PATH_DEAG)
1339  {
1340  path->fp_type = FIB_PATH_TYPE_DEAG;
1341  path->deag.fp_tbl_id = rpath->frp_fib_index;
1342  }
1343  else if (rpath->frp_flags & FIB_ROUTE_PATH_DVR)
1344  {
1345  path->fp_type = FIB_PATH_TYPE_DVR;
1346  path->dvr.fp_interface = rpath->frp_sw_if_index;
1347  }
1348  else if (rpath->frp_flags & FIB_ROUTE_PATH_EXCLUSIVE)
1349  {
1351  dpo_copy(&path->exclusive.fp_ex_dpo, &rpath->dpo);
1352  }
1353  else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT) ||
1355  {
1357  }
1358  else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY))
1359  {
1361  path->classify.fp_classify_table_id = rpath->frp_classify_table_id;
1362  }
1363  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_GLEAN)
1364  {
1366  path->attached.fp_interface = rpath->frp_sw_if_index;
1367  path->attached.fp_connected = rpath->frp_connected;
1368  }
1369  else if (~0 != rpath->frp_sw_if_index)
1370  {
1371  if (ip46_address_is_zero(&rpath->frp_addr))
1372  {
1374  path->attached.fp_interface = rpath->frp_sw_if_index;
1375  }
1376  else
1377  {
1379  path->attached_next_hop.fp_interface = rpath->frp_sw_if_index;
1380  path->attached_next_hop.fp_nh = rpath->frp_addr;
1381  }
1382  }
1383  else
1384  {
1385  if (ip46_address_is_zero(&rpath->frp_addr))
1386  {
1387  if (~0 == rpath->frp_fib_index)
1388  {
1390  }
1391  else
1392  {
1393  path->fp_type = FIB_PATH_TYPE_DEAG;
1394  path->deag.fp_tbl_id = rpath->frp_fib_index;
1395  path->deag.fp_rpf_id = ~0;
1396  }
1397  }
1398  else
1399  {
1401  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1402  {
1403  path->recursive.fp_nh.fp_local_label = rpath->frp_local_label;
1404  path->recursive.fp_nh.fp_eos = rpath->frp_eos;
1405  }
1406  else
1407  {
1408  path->recursive.fp_nh.fp_ip = rpath->frp_addr;
1409  }
1410  path->recursive.fp_tbl_id = rpath->frp_fib_index;
1411  }
1412  }
1413 
1414  FIB_PATH_DBG(path, "create");
1415 
1416  return (fib_path_get_index(path));
1417 }
1418 
1419 /*
1420  * fib_path_create_special
1421  *
1422  * Create and initialise a new path object.
1423  * return the index of the path.
1424  */
1427  dpo_proto_t nh_proto,
1429  const dpo_id_t *dpo)
1430 {
1431  fib_path_t *path;
1432 
1433  pool_get(fib_path_pool, path);
1434  clib_memset(path, 0, sizeof(*path));
1435 
1436  fib_node_init(&path->fp_node,
1438  dpo_reset(&path->fp_dpo);
1439 
1440  path->fp_pl_index = pl_index;
1441  path->fp_weight = 1;
1442  path->fp_preference = 0;
1443  path->fp_nh_proto = nh_proto;
1445  path->fp_cfg_flags = flags;
1446 
1447  if (FIB_PATH_CFG_FLAG_DROP & flags)
1448  {
1450  }
1451  else if (FIB_PATH_CFG_FLAG_LOCAL & flags)
1452  {
1454  path->attached.fp_interface = FIB_NODE_INDEX_INVALID;
1455  }
1456  else
1457  {
1459  ASSERT(NULL != dpo);
1460  dpo_copy(&path->exclusive.fp_ex_dpo, dpo);
1461  }
1462 
1463  return (fib_path_get_index(path));
1464 }
1465 
1466 /*
1467  * fib_path_copy
1468  *
1469  * Copy a path. return index of new path.
1470  */
1473  fib_node_index_t path_list_index)
1474 {
1475  fib_path_t *path, *orig_path;
1476 
1477  pool_get(fib_path_pool, path);
1478 
1479  orig_path = fib_path_get(path_index);
1480  ASSERT(NULL != orig_path);
1481 
1482  clib_memcpy(path, orig_path, sizeof(*path));
1483 
1484  FIB_PATH_DBG(path, "create-copy:%d", path_index);
1485 
1486  /*
1487  * reset the dynamic section
1488  */
1491  path->fp_pl_index = path_list_index;
1493  clib_memset(&path->fp_dpo, 0, sizeof(path->fp_dpo));
1494  dpo_reset(&path->fp_dpo);
1495 
1496  return (fib_path_get_index(path));
1497 }
1498 
1499 /*
1500  * fib_path_destroy
1501  *
1502  * destroy a path that is no longer required
1503  */
1504 void
1506 {
1507  fib_path_t *path;
1508 
1509  path = fib_path_get(path_index);
1510 
1511  ASSERT(NULL != path);
1512  FIB_PATH_DBG(path, "destroy");
1513 
1514  fib_path_unresolve(path);
1515 
1516  fib_node_deinit(&path->fp_node);
1517  pool_put(fib_path_pool, path);
1518 }
1519 
1520 /*
1521  * fib_path_destroy
1522  *
1523  * destroy a path that is no longer required
1524  */
1525 uword
1527 {
1528  fib_path_t *path;
1529 
1530  path = fib_path_get(path_index);
1531 
1532  return (hash_memory(STRUCT_MARK_PTR(path, path_hash_start),
1533  (STRUCT_OFFSET_OF(fib_path_t, path_hash_end) -
1534  STRUCT_OFFSET_OF(fib_path_t, path_hash_start)),
1535  0));
1536 }
1537 
1538 /*
1539  * fib_path_cmp_i
1540  *
1541  * Compare two paths for equivalence.
1542  */
1543 static int
1545  const fib_path_t *path2)
1546 {
1547  int res;
1548 
1549  res = 1;
1550 
1551  /*
1552  * paths of different types and protocol are not equal.
1553  * different weights and/or preference only are the same path.
1554  */
1555  if (path1->fp_type != path2->fp_type)
1556  {
1557  res = (path1->fp_type - path2->fp_type);
1558  }
1559  else if (path1->fp_nh_proto != path2->fp_nh_proto)
1560  {
1561  res = (path1->fp_nh_proto - path2->fp_nh_proto);
1562  }
1563  else
1564  {
1565  /*
1566  * both paths are of the same type.
1567  * consider each type and its attributes in turn.
1568  */
1569  switch (path1->fp_type)
1570  {
1572  res = ip46_address_cmp(&path1->attached_next_hop.fp_nh,
1573  &path2->attached_next_hop.fp_nh);
1574  if (0 == res) {
1575  res = (path1->attached_next_hop.fp_interface -
1576  path2->attached_next_hop.fp_interface);
1577  }
1578  break;
1580  res = (path1->attached.fp_interface -
1581  path2->attached.fp_interface);
1582  break;
1584  res = ip46_address_cmp(&path1->recursive.fp_nh.fp_ip,
1585  &path2->recursive.fp_nh.fp_ip);
1586 
1587  if (0 == res)
1588  {
1589  res = (path1->recursive.fp_tbl_id - path2->recursive.fp_tbl_id);
1590  }
1591  break;
1593  res = (path1->bier_fmask.fp_bier_fmask -
1594  path2->bier_fmask.fp_bier_fmask);
1595  break;
1597  res = (path1->bier_imp.fp_bier_imp -
1598  path2->bier_imp.fp_bier_imp);
1599  break;
1601  res = bier_table_id_cmp(&path1->bier_table.fp_bier_tbl,
1602  &path2->bier_table.fp_bier_tbl);
1603  break;
1604  case FIB_PATH_TYPE_DEAG:
1605  res = (path1->deag.fp_tbl_id - path2->deag.fp_tbl_id);
1606  if (0 == res)
1607  {
1608  res = (path1->deag.fp_rpf_id - path2->deag.fp_rpf_id);
1609  }
1610  break;
1611  case FIB_PATH_TYPE_INTF_RX:
1612  res = (path1->intf_rx.fp_interface - path2->intf_rx.fp_interface);
1613  break;
1615  res = (path1->udp_encap.fp_udp_encap_id - path2->udp_encap.fp_udp_encap_id);
1616  break;
1617  case FIB_PATH_TYPE_DVR:
1618  res = (path1->dvr.fp_interface - path2->dvr.fp_interface);
1619  break;
1621  res = dpo_cmp(&path1->exclusive.fp_ex_dpo, &path2->exclusive.fp_ex_dpo);
1622  break;
1623  case FIB_PATH_TYPE_SPECIAL:
1624  case FIB_PATH_TYPE_RECEIVE:
1625  res = 0;
1626  break;
1627  }
1628  }
1629  return (res);
1630 }
1631 
1632 /*
1633  * fib_path_cmp_for_sort
1634  *
1635  * Compare two paths for equivalence. Used during path sorting.
1636  * As usual 0 means equal.
1637  */
1638 int
1640  void * v2)
1641 {
1642  fib_node_index_t *pi1 = v1, *pi2 = v2;
1643  fib_path_t *path1, *path2;
1644 
1645  path1 = fib_path_get(*pi1);
1646  path2 = fib_path_get(*pi2);
1647 
1648  /*
1649  * when sorting paths we want the highest preference paths
1650  * first, so that the choices set built is in prefernce order
1651  */
1652  if (path1->fp_preference != path2->fp_preference)
1653  {
1654  return (path1->fp_preference - path2->fp_preference);
1655  }
1656 
1657  return (fib_path_cmp_i(path1, path2));
1658 }
1659 
1660 /*
1661  * fib_path_cmp
1662  *
1663  * Compare two paths for equivalence.
1664  */
1665 int
1667  fib_node_index_t pi2)
1668 {
1669  fib_path_t *path1, *path2;
1670 
1671  path1 = fib_path_get(pi1);
1672  path2 = fib_path_get(pi2);
1673 
1674  return (fib_path_cmp_i(path1, path2));
1675 }
1676 
1677 int
1679  const fib_route_path_t *rpath)
1680 {
1681  fib_path_t *path;
1682  int res;
1683 
1684  path = fib_path_get(path_index);
1685 
1686  res = 1;
1687 
1688  if (path->fp_weight != rpath->frp_weight)
1689  {
1690  res = (path->fp_weight - rpath->frp_weight);
1691  }
1692  else
1693  {
1694  /*
1695  * both paths are of the same type.
1696  * consider each type and its attributes in turn.
1697  */
1698  switch (path->fp_type)
1699  {
1701  res = ip46_address_cmp(&path->attached_next_hop.fp_nh,
1702  &rpath->frp_addr);
1703  if (0 == res)
1704  {
1705  res = (path->attached_next_hop.fp_interface -
1706  rpath->frp_sw_if_index);
1707  }
1708  break;
1710  res = (path->attached.fp_interface - rpath->frp_sw_if_index);
1711  break;
1713  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1714  {
1715  res = path->recursive.fp_nh.fp_local_label - rpath->frp_local_label;
1716 
1717  if (res == 0)
1718  {
1719  res = path->recursive.fp_nh.fp_eos - rpath->frp_eos;
1720  }
1721  }
1722  else
1723  {
1724  res = ip46_address_cmp(&path->recursive.fp_nh.fp_ip,
1725  &rpath->frp_addr);
1726  }
1727 
1728  if (0 == res)
1729  {
1730  res = (path->recursive.fp_tbl_id - rpath->frp_fib_index);
1731  }
1732  break;
1734  res = (path->bier_fmask.fp_bier_fmask - rpath->frp_bier_fmask);
1735  break;
1737  res = (path->bier_imp.fp_bier_imp - rpath->frp_bier_imp);
1738  break;
1740  res = bier_table_id_cmp(&path->bier_table.fp_bier_tbl,
1741  &rpath->frp_bier_tbl);
1742  break;
1743  case FIB_PATH_TYPE_INTF_RX:
1744  res = (path->intf_rx.fp_interface - rpath->frp_sw_if_index);
1745  break;
1747  res = (path->udp_encap.fp_udp_encap_id - rpath->frp_udp_encap_id);
1748  break;
1749  case FIB_PATH_TYPE_DEAG:
1750  res = (path->deag.fp_tbl_id - rpath->frp_fib_index);
1751  if (0 == res)
1752  {
1753  res = (path->deag.fp_rpf_id - rpath->frp_rpf_id);
1754  }
1755  break;
1756  case FIB_PATH_TYPE_DVR:
1757  res = (path->dvr.fp_interface - rpath->frp_sw_if_index);
1758  break;
1760  res = dpo_cmp(&path->exclusive.fp_ex_dpo, &rpath->dpo);
1761  break;
1762  case FIB_PATH_TYPE_RECEIVE:
1763  if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
1764  {
1765  res = 0;
1766  }
1767  else
1768  {
1769  res = 1;
1770  }
1771  break;
1772  case FIB_PATH_TYPE_SPECIAL:
1773  res = 0;
1774  break;
1775  }
1776  }
1777  return (res);
1778 }
1779 
1780 /*
1781  * fib_path_recursive_loop_detect
1782  *
1783  * A forward walk of the FIB object graph to detect for a cycle/loop. This
1784  * walk is initiated when an entry is linking to a new path list or from an old.
1785  * The entry vector passed contains all the FIB entrys that are children of this
1786  * path (it is all the entries encountered on the walk so far). If this vector
1787  * contains the entry this path resolve via, then a loop is about to form.
1788  * The loop must be allowed to form, since we need the dependencies in place
1789  * so that we can track when the loop breaks.
1790  * However, we MUST not produce a loop in the forwarding graph (else packets
1791  * would loop around the switch path until the loop breaks), so we mark recursive
1792  * paths as looped so that they do not contribute forwarding information.
1793  * By marking the path as looped, an etry such as;
1794  * X/Y
1795  * via a.a.a.a (looped)
1796  * via b.b.b.b (not looped)
1797  * can still forward using the info provided by b.b.b.b only
1798  */
1799 int
1801  fib_node_index_t **entry_indicies)
1802 {
1803  fib_path_t *path;
1804 
1805  path = fib_path_get(path_index);
1806 
1807  /*
1808  * the forced drop path is never looped, cos it is never resolved.
1809  */
1810  if (fib_path_is_permanent_drop(path))
1811  {
1812  return (0);
1813  }
1814 
1815  switch (path->fp_type)
1816  {
1818  {
1819  fib_node_index_t *entry_index, *entries;
1820  int looped = 0;
1821  entries = *entry_indicies;
1822 
1823  vec_foreach(entry_index, entries) {
1824  if (*entry_index == path->fp_via_fib)
1825  {
1826  /*
1827  * the entry that is about to link to this path-list (or
1828  * one of this path-list's children) is the same entry that
1829  * this recursive path resolves through. this is a cycle.
1830  * abort the walk.
1831  */
1832  looped = 1;
1833  break;
1834  }
1835  }
1836 
1837  if (looped)
1838  {
1839  FIB_PATH_DBG(path, "recursive loop formed");
1841 
1842  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
1843  }
1844  else
1845  {
1846  /*
1847  * no loop here yet. keep forward walking the graph.
1848  */
1849  if (fib_entry_recursive_loop_detect(path->fp_via_fib, entry_indicies))
1850  {
1851  FIB_PATH_DBG(path, "recursive loop formed");
1853  }
1854  else
1855  {
1856  FIB_PATH_DBG(path, "recursive loop cleared");
1858  }
1859  }
1860  break;
1861  }
1864  if (dpo_is_adj(&path->fp_dpo) &&
1866  entry_indicies))
1867  {
1868  FIB_PATH_DBG(path, "recursive loop formed");
1870  }
1871  else
1872  {
1873  FIB_PATH_DBG(path, "recursive loop cleared");
1875  }
1876  break;
1877  case FIB_PATH_TYPE_SPECIAL:
1878  case FIB_PATH_TYPE_DEAG:
1879  case FIB_PATH_TYPE_DVR:
1880  case FIB_PATH_TYPE_RECEIVE:
1881  case FIB_PATH_TYPE_INTF_RX:
1887  /*
1888  * these path types cannot be part of a loop, since they are the leaves
1889  * of the graph.
1890  */
1891  break;
1892  }
1893 
1894  return (fib_path_is_looped(path_index));
1895 }
1896 
1897 int
1899 {
1900  fib_path_t *path;
1901 
1902  path = fib_path_get(path_index);
1903 
1904  /*
1905  * hope for the best.
1906  */
1908 
1909  /*
1910  * the forced drop path resolves via the drop adj
1911  */
1912  if (fib_path_is_permanent_drop(path))
1913  {
1914  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
1916  return (fib_path_is_resolved(path_index));
1917  }
1918 
1919  switch (path->fp_type)
1920  {
1923  break;
1925  {
1926  dpo_id_t tmp = DPO_INVALID;
1927 
1928  /*
1929  * path->attached.fp_interface
1930  */
1932  path->attached.fp_interface))
1933  {
1935  }
1938  &tmp);
1939 
1940  /*
1941  * re-fetch after possible mem realloc
1942  */
1943  path = fib_path_get(path_index);
1944  dpo_copy(&path->fp_dpo, &tmp);
1945 
1946  /*
1947  * become a child of the adjacency so we receive updates
1948  * when the interface state changes
1949  */
1950  if (dpo_is_adj(&path->fp_dpo))
1951  {
1952  path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
1954  fib_path_get_index(path));
1955  }
1956  dpo_reset(&tmp);
1957  break;
1958  }
1960  {
1961  /*
1962  * Create a RR source entry in the table for the address
1963  * that this path recurses through.
1964  * This resolve action is recursive, hence we may create
1965  * more paths in the process. more creates mean maybe realloc
1966  * of this path.
1967  */
1968  fib_node_index_t fei;
1969  fib_prefix_t pfx;
1970 
1972 
1973  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1974  {
1975  fib_prefix_from_mpls_label(path->recursive.fp_nh.fp_local_label,
1976  path->recursive.fp_nh.fp_eos,
1977  &pfx);
1978  }
1979  else
1980  {
1981  fib_prefix_from_ip46_addr(&path->recursive.fp_nh.fp_ip, &pfx);
1982  }
1983 
1984  fib_table_lock(path->recursive.fp_tbl_id,
1986  FIB_SOURCE_RR);
1987  fei = fib_table_entry_special_add(path->recursive.fp_tbl_id,
1988  &pfx,
1989  FIB_SOURCE_RR,
1991 
1992  path = fib_path_get(path_index);
1993  path->fp_via_fib = fei;
1994 
1995  /*
1996  * become a dependent child of the entry so the path is
1997  * informed when the forwarding for the entry changes.
1998  */
2001  fib_path_get_index(path));
2002 
2003  /*
2004  * create and configure the IP DPO
2005  */
2007  path,
2008  fib_path_to_chain_type(path),
2009  &path->fp_dpo);
2010 
2011  break;
2012  }
2014  {
2015  /*
2016  * become a dependent child of the entry so the path is
2017  * informed when the forwarding for the entry changes.
2018  */
2019  path->fp_sibling = bier_fmask_child_add(path->bier_fmask.fp_bier_fmask,
2021  fib_path_get_index(path));
2022 
2023  path->fp_via_bier_fmask = path->bier_fmask.fp_bier_fmask;
2024  fib_path_bier_fmask_update(path, &path->fp_dpo);
2025 
2026  break;
2027  }
2029  bier_imp_lock(path->bier_imp.fp_bier_imp);
2030  bier_imp_contribute_forwarding(path->bier_imp.fp_bier_imp,
2031  DPO_PROTO_IP4,
2032  &path->fp_dpo);
2033  break;
2035  {
2036  /*
2037  * Find/create the BIER table to link to
2038  */
2040 
2041  path->fp_via_bier_tbl =
2042  bier_table_ecmp_create_and_lock(&path->bier_table.fp_bier_tbl);
2043 
2045  &path->fp_dpo);
2046  break;
2047  }
2048  case FIB_PATH_TYPE_SPECIAL:
2050  {
2053  &path->fp_dpo);
2054  }
2056  {
2059  &path->fp_dpo);
2060  }
2061  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY)
2062  {
2063  dpo_set (&path->fp_dpo, DPO_CLASSIFY,
2064  path->fp_nh_proto,
2066  path->classify.fp_classify_table_id));
2067  }
2068  else
2069  {
2070  /*
2071  * Resolve via the drop
2072  */
2073  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
2074  }
2075  break;
2076  case FIB_PATH_TYPE_DEAG:
2077  {
2078  if (DPO_PROTO_BIER == path->fp_nh_proto)
2079  {
2081  &path->fp_dpo);
2082  }
2083  else
2084  {
2085  /*
2086  * Resolve via a lookup DPO.
2087  * FIXME. control plane should add routes with a table ID
2088  */
2089  lookup_input_t input;
2090  lookup_cast_t cast;
2091 
2092  cast = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ?
2094  LOOKUP_UNICAST);
2095  input = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DEAG_SRC ?
2098 
2099  lookup_dpo_add_or_lock_w_fib_index(path->deag.fp_tbl_id,
2100  path->fp_nh_proto,
2101  cast,
2102  input,
2104  &path->fp_dpo);
2105  }
2106  break;
2107  }
2108  case FIB_PATH_TYPE_DVR:
2109  dvr_dpo_add_or_lock(path->dvr.fp_interface,
2110  path->fp_nh_proto,
2111  &path->fp_dpo);
2112  break;
2113  case FIB_PATH_TYPE_RECEIVE:
2114  /*
2115  * Resolve via a receive DPO.
2116  */
2118  path->receive.fp_interface,
2119  &path->receive.fp_addr,
2120  &path->fp_dpo);
2121  break;
2123  udp_encap_lock(path->udp_encap.fp_udp_encap_id);
2124  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
2125  path->fp_nh_proto,
2126  &path->fp_dpo);
2127  break;
2128  case FIB_PATH_TYPE_INTF_RX: {
2129  /*
2130  * Resolve via a receive DPO.
2131  */
2133  path->intf_rx.fp_interface,
2134  &path->fp_dpo);
2135  break;
2136  }
2138  /*
2139  * Resolve via the user provided DPO
2140  */
2141  dpo_copy(&path->fp_dpo, &path->exclusive.fp_ex_dpo);
2142  break;
2143  }
2144 
2145  return (fib_path_is_resolved(path_index));
2146 }
2147 
2148 u32
2150 {
2151  fib_path_t *path;
2152 
2153  path = fib_path_get(path_index);
2154 
2155  switch (path->fp_type)
2156  {
2158  return (path->attached_next_hop.fp_interface);
2160  return (path->attached.fp_interface);
2161  case FIB_PATH_TYPE_RECEIVE:
2162  return (path->receive.fp_interface);
2164  if (fib_path_is_resolved(path_index))
2165  {
2167  }
2168  break;
2169  case FIB_PATH_TYPE_DVR:
2170  return (path->dvr.fp_interface);
2171  case FIB_PATH_TYPE_INTF_RX:
2173  case FIB_PATH_TYPE_SPECIAL:
2174  case FIB_PATH_TYPE_DEAG:
2179  break;
2180  }
2181  return (dpo_get_urpf(&path->fp_dpo));
2182 }
2183 
2184 index_t
2186 {
2187  fib_path_t *path;
2188 
2189  path = fib_path_get(path_index);
2190 
2191  switch (path->fp_type)
2192  {
2195  case FIB_PATH_TYPE_RECEIVE:
2196  case FIB_PATH_TYPE_INTF_RX:
2197  case FIB_PATH_TYPE_SPECIAL:
2198  case FIB_PATH_TYPE_DEAG:
2199  case FIB_PATH_TYPE_DVR:
2201  break;
2203  return (path->udp_encap.fp_udp_encap_id);
2205  return (path->fp_via_fib);
2207  return (path->bier_fmask.fp_bier_fmask);
2209  return (path->fp_via_bier_tbl);
2211  return (path->bier_imp.fp_bier_imp);
2212  }
2213  return (~0);
2214 }
2215 
2218 {
2219  fib_path_t *path;
2220 
2221  path = fib_path_get(path_index);
2222 
2223  if (dpo_is_adj(&path->fp_dpo))
2224  {
2225  return (path->fp_dpo.dpoi_index);
2226  }
2227  return (ADJ_INDEX_INVALID);
2228 }
2229 
2230 u16
2232 {
2233  fib_path_t *path;
2234 
2235  path = fib_path_get(path_index);
2236 
2237  ASSERT(path);
2238 
2239  return (path->fp_weight);
2240 }
2241 
2242 u16
2244 {
2245  fib_path_t *path;
2246 
2247  path = fib_path_get(path_index);
2248 
2249  ASSERT(path);
2250 
2251  return (path->fp_preference);
2252 }
2253 
2254 u32
2256 {
2257  fib_path_t *path;
2258 
2259  path = fib_path_get(path_index);
2260 
2261  ASSERT(path);
2262 
2264  {
2265  return (path->deag.fp_rpf_id);
2266  }
2267 
2268  return (~0);
2269 }
2270 
2271 /**
2272  * @brief Contribute the path's adjacency to the list passed.
2273  * By calling this function over all paths, recursively, a child
2274  * can construct its full set of forwarding adjacencies, and hence its
2275  * uRPF list.
2276  */
2277 void
2279  index_t urpf)
2280 {
2281  fib_path_t *path;
2282 
2283  path = fib_path_get(path_index);
2284 
2285  /*
2286  * resolved and unresolved paths contribute to the RPF list.
2287  */
2288  switch (path->fp_type)
2289  {
2291  fib_urpf_list_append(urpf, path->attached_next_hop.fp_interface);
2292  break;
2293 
2295  fib_urpf_list_append(urpf, path->attached.fp_interface);
2296  break;
2297 
2299  if (FIB_NODE_INDEX_INVALID != path->fp_via_fib &&
2300  !fib_path_is_looped(path_index))
2301  {
2302  /*
2303  * there's unresolved due to constraints, and there's unresolved
2304  * due to ain't got no via. can't do nowt w'out via.
2305  */
2307  }
2308  break;
2309 
2311  case FIB_PATH_TYPE_SPECIAL:
2312  {
2313  /*
2314  * these path types may link to an adj, if that's what
2315  * the clinet gave
2316  */
2317  u32 rpf_sw_if_index;
2318 
2319  rpf_sw_if_index = dpo_get_urpf(&path->fp_dpo);
2320 
2321  if (~0 != rpf_sw_if_index)
2322  {
2323  fib_urpf_list_append(urpf, rpf_sw_if_index);
2324  }
2325  break;
2326  }
2327  case FIB_PATH_TYPE_DVR:
2328  fib_urpf_list_append(urpf, path->dvr.fp_interface);
2329  break;
2330  case FIB_PATH_TYPE_DEAG:
2331  case FIB_PATH_TYPE_RECEIVE:
2332  case FIB_PATH_TYPE_INTF_RX:
2337  /*
2338  * these path types don't link to an adj
2339  */
2340  break;
2341  }
2342 }
2343 
2344 void
2346  dpo_proto_t payload_proto,
2348  dpo_id_t *dpo)
2349 {
2350  fib_path_t *path;
2351 
2352  path = fib_path_get(path_index);
2353 
2354  ASSERT(path);
2355 
2356  switch (path->fp_type)
2357  {
2359  {
2360  dpo_id_t tmp = DPO_INVALID;
2361 
2362  dpo_copy(&tmp, dpo);
2363 
2364  mpls_disp_dpo_create(payload_proto, ~0, mode, &tmp, dpo);
2365  dpo_reset(&tmp);
2366  break;
2367  }
2368  case FIB_PATH_TYPE_DEAG:
2369  {
2370  dpo_id_t tmp = DPO_INVALID;
2371 
2372  dpo_copy(&tmp, dpo);
2373 
2374  mpls_disp_dpo_create(payload_proto,
2375  path->deag.fp_rpf_id,
2376  mode, &tmp, dpo);
2377  dpo_reset(&tmp);
2378  break;
2379  }
2380  case FIB_PATH_TYPE_RECEIVE:
2383  case FIB_PATH_TYPE_INTF_RX:
2386  case FIB_PATH_TYPE_SPECIAL:
2390  case FIB_PATH_TYPE_DVR:
2391  break;
2392  }
2393 
2395  {
2396  dpo_id_t tmp = DPO_INVALID;
2397 
2398  dpo_copy(&tmp, dpo);
2399 
2400  pw_cw_dpo_create(&tmp, dpo);
2401  dpo_reset(&tmp);
2402  }
2403 }
2404 
2405 void
2408  dpo_id_t *dpo)
2409 {
2410  fib_path_t *path;
2411 
2412  path = fib_path_get(path_index);
2413 
2414  ASSERT(path);
2416 
2417  /*
2418  * The DPO stored in the path was created when the path was resolved.
2419  * This then represents the path's 'native' protocol; IP.
2420  * For all others will need to go find something else.
2421  */
2422  if (fib_path_to_chain_type(path) == fct)
2423  {
2424  dpo_copy(dpo, &path->fp_dpo);
2425  }
2426  else
2427  {
2428  switch (path->fp_type)
2429  {
2431  switch (fct)
2432  {
2442  path,
2444  dpo);
2445  break;
2447  break;
2448  }
2449  break;
2451  switch (fct)
2452  {
2460  fib_path_recursive_adj_update(path, fct, dpo);
2461  break;
2464  ASSERT(0);
2465  break;
2466  }
2467  break;
2469  switch (fct)
2470  {
2473  break;
2482  ASSERT(0);
2483  break;
2484  }
2485  break;
2487  switch (fct)
2488  {
2490  fib_path_bier_fmask_update(path, dpo);
2491  break;
2500  ASSERT(0);
2501  break;
2502  }
2503  break;
2505  bier_imp_contribute_forwarding(path->bier_imp.fp_bier_imp,
2507  dpo);
2508  break;
2509  case FIB_PATH_TYPE_DEAG:
2510  switch (fct)
2511  {
2518  dpo);
2519  break;
2525  dpo_copy(dpo, &path->fp_dpo);
2526  break;
2528  break;
2531  ASSERT(0);
2532  break;
2533  }
2534  break;
2536  dpo_copy(dpo, &path->exclusive.fp_ex_dpo);
2537  break;
2539  switch (fct)
2540  {
2550  dpo);
2551  break;
2554  {
2555  adj_index_t ai;
2556 
2557  /*
2558  * Create the adj needed for sending IP multicast traffic
2559  */
2561  path->attached.fp_interface))
2562  {
2563  /*
2564  * point-2-point interfaces do not require a glean, since
2565  * there is nothing to ARP. Install a rewrite/nbr adj instead
2566  */
2569  &zero_addr,
2570  path->attached.fp_interface);
2571  }
2572  else
2573  {
2576  path->attached.fp_interface);
2577  }
2578  dpo_set(dpo, DPO_ADJACENCY,
2580  ai);
2581  adj_unlock(ai);
2582  }
2583  break;
2584  }
2585  break;
2586  case FIB_PATH_TYPE_INTF_RX:
2587  /*
2588  * Create the adj needed for sending IP multicast traffic
2589  */
2591  path->attached.fp_interface,
2592  dpo);
2593  break;
2595  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
2596  path->fp_nh_proto,
2597  dpo);
2598  break;
2599  case FIB_PATH_TYPE_RECEIVE:
2600  case FIB_PATH_TYPE_SPECIAL:
2601  case FIB_PATH_TYPE_DVR:
2602  dpo_copy(dpo, &path->fp_dpo);
2603  break;
2604  }
2605  }
2606 }
2607 
2611  load_balance_path_t *hash_key)
2612 {
2613  load_balance_path_t *mnh;
2614  fib_path_t *path;
2615 
2616  path = fib_path_get(path_index);
2617 
2618  ASSERT(path);
2619 
2620  vec_add2(hash_key, mnh, 1);
2621 
2622  mnh->path_weight = path->fp_weight;
2623  mnh->path_index = path_index;
2624 
2625  if (fib_path_is_resolved(path_index))
2626  {
2627  fib_path_contribute_forwarding(path_index, fct, &mnh->path_dpo);
2628  }
2629  else
2630  {
2631  dpo_copy(&mnh->path_dpo,
2633  }
2634  return (hash_key);
2635 }
2636 
2637 int
2639 {
2640  fib_path_t *path;
2641 
2642  path = fib_path_get(path_index);
2643 
2644  return ((FIB_PATH_TYPE_RECURSIVE == path->fp_type) &&
2647 }
2648 
2649 int
2651 {
2652  fib_path_t *path;
2653 
2654  path = fib_path_get(path_index);
2655 
2656  return (FIB_PATH_TYPE_EXCLUSIVE == path->fp_type);
2657 }
2658 
2659 int
2661 {
2662  fib_path_t *path;
2663 
2664  path = fib_path_get(path_index);
2665 
2666  return (FIB_PATH_TYPE_DEAG == path->fp_type);
2667 }
2668 
2669 int
2671 {
2672  fib_path_t *path;
2673 
2674  path = fib_path_get(path_index);
2675 
2676  return (dpo_id_is_valid(&path->fp_dpo) &&
2678  !fib_path_is_looped(path_index) &&
2680 }
2681 
2682 int
2684 {
2685  fib_path_t *path;
2686 
2687  path = fib_path_get(path_index);
2688 
2690 }
2691 
2694  fib_node_index_t path_index,
2695  const fib_path_ext_t *path_ext,
2696  void *args)
2697 {
2698  fib_path_encode_ctx_t *ctx = args;
2699  fib_route_path_t *rpath;
2700  fib_path_t *path;
2701 
2702  path = fib_path_get(path_index);
2703  if (!path)
2704  return (FIB_PATH_LIST_WALK_CONTINUE);
2705 
2706  vec_add2(ctx->rpaths, rpath, 1);
2707  rpath->frp_weight = path->fp_weight;
2708  rpath->frp_preference = path->fp_preference;
2709  rpath->frp_proto = path->fp_nh_proto;
2710  rpath->frp_sw_if_index = ~0;
2711  rpath->frp_fib_index = 0;
2712 
2713  switch (path->fp_type)
2714  {
2715  case FIB_PATH_TYPE_RECEIVE:
2716  rpath->frp_addr = path->receive.fp_addr;
2717  rpath->frp_sw_if_index = path->receive.fp_interface;
2718  rpath->frp_flags |= FIB_ROUTE_PATH_LOCAL;
2719  break;
2721  rpath->frp_sw_if_index = path->attached.fp_interface;
2722  break;
2724  rpath->frp_sw_if_index = path->attached_next_hop.fp_interface;
2725  rpath->frp_addr = path->attached_next_hop.fp_nh;
2726  break;
2728  rpath->frp_bier_fmask = path->bier_fmask.fp_bier_fmask;
2729  break;
2730  case FIB_PATH_TYPE_SPECIAL:
2731  break;
2732  case FIB_PATH_TYPE_DEAG:
2733  rpath->frp_fib_index = path->deag.fp_tbl_id;
2735  {
2736  rpath->frp_flags |= FIB_ROUTE_PATH_RPF_ID;
2737  }
2738  break;
2740  rpath->frp_addr = path->recursive.fp_nh.fp_ip;
2741  rpath->frp_fib_index = path->recursive.fp_tbl_id;
2742  break;
2743  case FIB_PATH_TYPE_DVR:
2744  rpath->frp_sw_if_index = path->dvr.fp_interface;
2745  rpath->frp_flags |= FIB_ROUTE_PATH_DVR;
2746  break;
2748  rpath->frp_udp_encap_id = path->udp_encap.fp_udp_encap_id;
2750  break;
2751  case FIB_PATH_TYPE_INTF_RX:
2752  rpath->frp_sw_if_index = path->receive.fp_interface;
2754  break;
2757  default:
2758  break;
2759  }
2760 
2761  if (path_ext && path_ext->fpe_type == FIB_PATH_EXT_MPLS)
2762  {
2763  rpath->frp_label_stack = path_ext->fpe_path.frp_label_stack;
2764  }
2765 
2767  rpath->frp_flags |= FIB_ROUTE_PATH_DROP;
2772 
2773  return (FIB_PATH_LIST_WALK_CONTINUE);
2774 }
2775 
2778 {
2779  fib_path_t *path;
2780 
2781  path = fib_path_get(path_index);
2782 
2783  return (path->fp_nh_proto);
2784 }
2785 
2786 void
2788 {
2789  fib_node_register_type (FIB_NODE_TYPE_PATH, &fib_path_vft);
2790  fib_path_logger = vlib_log_register_class ("fib", "path");
2791 }
2792 
2793 static clib_error_t *
2795  unformat_input_t * input,
2796  vlib_cli_command_t * cmd)
2797 {
2798  fib_node_index_t pi;
2799  fib_path_t *path;
2800 
2801  if (unformat (input, "%d", &pi))
2802  {
2803  /*
2804  * show one in detail
2805  */
2806  if (!pool_is_free_index(fib_path_pool, pi))
2807  {
2808  path = fib_path_get(pi);
2809  u8 *s = format(NULL, "%U", format_fib_path, pi, 1,
2811  s = format(s, "\n children:");
2813  vlib_cli_output (vm, "%v", s);
2814  vec_free(s);
2815  }
2816  else
2817  {
2818  vlib_cli_output (vm, "path %d invalid", pi);
2819  }
2820  }
2821  else
2822  {
2823  vlib_cli_output (vm, "FIB Paths");
2824  pool_foreach_index (pi, fib_path_pool)
2825  {
2826  vlib_cli_output (vm, "%U", format_fib_path, pi, 0,
2828  }
2829  }
2830 
2831  return (NULL);
2832 }
2833 
2834 VLIB_CLI_COMMAND (show_fib_path, static) = {
2835  .path = "show fib paths",
2836  .function = show_fib_path_command,
2837  .short_help = "show fib paths",
2838 };
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:338
int fib_path_is_resolved(fib_node_index_t path_index)
Definition: fib_path.c:2670
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:121
int fib_path_resolve(fib_node_index_t path_index)
Definition: fib_path.c:1898
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
struct fib_path_t_::@310::@317 bier_fmask
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:136
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:516
fib_path_ext_type_t fpe_type
The type of path extension.
Definition: fib_path_ext.h:126
struct fib_path_t_::@310::@318 bier_table
A path that resolves via a DVR DPO.
Definition: fib_types.h:393
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:112
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:67
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:436
void bier_imp_contribute_forwarding(index_t bii, dpo_proto_t proto, dpo_id_t *dpo)
Definition: bier_imp.c:174
#define pool_foreach_index(i, v)
Definition: pool.h:569
uword fib_path_hash(fib_node_index_t path_index)
Definition: fib_path.c:1526
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:2406
enum fib_path_format_flags_t_ fib_format_path_flags_t
index_t fp_bier_fmask
BIER FMask ID.
Definition: fib_path.c:279
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:163
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:527
fib_path_oper_attribute_t_
Enurmeration of path operational (i.e.
Definition: fib_path.c:130
u32 fp_classify_table_id
The UDP Encap object this path resolves through.
Definition: fib_path.c:339
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
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:1514
index_t fib_path_get_resolving_index(fib_node_index_t path_index)
Definition: fib_path.c:2185
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:2278
A representation of a path as described by a route producer.
Definition: fib_types.h:500
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 vnet_sw_interface_is_nbma(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1286
int dpo_is_adj(const dpo_id_t *dpo)
Return TRUE is the DPO is any type of adjacency.
Definition: dpo.c:280
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:158
#define STRUCT_MARK_PTR(v, f)
Definition: clib.h:76
enum mpls_eos_bit_t_ mpls_eos_bit_t
int fib_path_cmp(fib_node_index_t pi1, fib_node_index_t pi2)
Definition: fib_path.c:1666
A Drop path - resolve the path on the drop DPO.
Definition: fib_types.h:352
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:293
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:214
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
A path that resolves via a BIER impostion object.
Definition: fib_types.h:385
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:2787
int fib_path_is_exclusive(fib_node_index_t path_index)
Definition: fib_path.c:2650
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:843
index_t frp_bier_imp
A path via a BIER imposition object.
Definition: fib_types.h:533
void bier_table_ecmp_unlock(index_t bti)
Definition: bier_table.c:462
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:516
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:273
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:387
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:630
A path that resolves via a BIER [ECMP] Table.
Definition: fib_types.h:381
The path is resolved.
Definition: fib_path.c:142
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:108
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:70
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)
vlib_main_t * vm
Definition: in2out_ed.c:1580
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1712
struct fib_path_t_::@310::@326 classify
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:505
struct fib_path_t_::@310::@316 recursive
vl_api_fib_path_t path
Definition: mfib_types.api:44
bier_table_id_t frp_bier_tbl
A path that resolves via a BIER Table.
Definition: fib_types.h:574
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:361
dpo_id_t fp_ex_dpo
The user provided &#39;exclusive&#39; DPO.
Definition: fib_path.c:311
int fib_path_is_looped(fib_node_index_t path_index)
Definition: fib_path.c:2683
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:383
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:251
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:26
The path has become a permanent drop.
Definition: fib_path.c:146
int fib_path_cmp_for_sort(void *v1, void *v2)
Definition: fib_path.c:1639
unsigned char u8
Definition: types.h:56
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:139
ip46_address_t fp_ip
The next-hop.
Definition: fib_path.c:258
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:2609
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
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:550
A local path with a RPF-ID => multicast traffic.
Definition: fib_types.h:365
#define FIB_PATH_TYPES
Definition: fib_path.c:111
u32 vlib_log_class_t
Definition: vlib.h:51
fib_path_type_t fp_type
The type of the path.
Definition: fib_path.c:207
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:545
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:267
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
fib_prefix_t fp_connected
The Connected local address.
Definition: fib_path.c:246
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:336
description fragment has unexpected format
Definition: map.api:433
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:1472
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:202
fib_path_cfg_flags_t fp_cfg_flags
Configuration Flags.
Definition: fib_path.c:202
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:186
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:347
A path via a UDP encap object.
Definition: fib_types.h:373
dpo_id_t fp_dpo
The Data-path objects through which this path resolves for IP.
Definition: fib_path.c:380
unsigned int u32
Definition: types.h:88
#define FIB_PATH_CFG_ATTRIBUTES
Definition: fib_path.h:117
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:140
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:359
int load_balance_is_drop(const dpo_id_t *dpo)
Definition: load_balance.c:297
u16 fib_path_get_weight(fib_node_index_t path_index)
Definition: fib_path.c:2231
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.
struct fib_path_t_::@310::@324 intf_rx
static void fib_path_attached_next_hop_set(fib_path_t *path)
Definition: fib_path.c:665
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:1426
Definition: fib_entry.h:112
fib_rpf_id_t fp_rpf_id
The RPF-ID to tag the packets with.
Definition: fib_path.c:303
void bier_disp_table_contribute_forwarding(index_t bdti, dpo_id_t *dpo)
struct fib_path_t_::@310::@320 deag
index_t frp_bier_fmask
Resolving via a BIER Fmask.
Definition: fib_types.h:589
u8 * format_fib_path(u8 *s, va_list *args)
Definition: fib_path.c:443
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:385
Contribute an object that is to be used to forward end-of-stack MPLS packets.
Definition: fib_types.h:128
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:546
int adj_is_up(adj_index_t ai)
Return true if the adjacency is &#39;UP&#39;, i.e.
Definition: adj.c:533
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:214
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:48
dpo_type_t dpoi_type
the type
Definition: dpo.h:176
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:2217
enum fib_mpls_lsp_mode_t_ fib_mpls_lsp_mode_t
MPLS LSP mode - only valid at the head and tail.
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
struct fib_path_t_::@310::@322 exclusive
index_t fp_via_bier_tbl
the resolving bier-table
Definition: fib_path.c:370
fib_mpls_label_t * frp_label_stack
The outgoing MPLS label Stack.
Definition: fib_types.h:560
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:340
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:137
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:2345
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:564
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:1300
static fib_path_t * fib_path_pool
Definition: fib_path.c:398
Pop a Psuedo Wire Control Word.
Definition: fib_types.h:402
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:418
ip46_address_t fp_nh
The next-hop.
Definition: fib_path.c:236
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:172
struct fib_path_t_::@310::@325 udp_encap
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:164
#define MPLS_FIB_DEFAULT_TABLE_ID
Definition: mpls_fib.h:28
The path forms part of a recursive loop.
Definition: fib_path.c:138
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:465
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:584
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:224
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:146
#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:333
static void fib_path_last_lock_gone(fib_node_t *node)
Definition: fib_path.c:622
static fib_node_index_t fib_path_get_index(fib_path_t *path)
Definition: fib_path.c:424
A FIB path.
Definition: fib_path.c:182
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:374
u32 fib_path_get_rpf_id(fib_node_index_t path_index)
Definition: fib_path.c:2255
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
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:298
Don&#39;t resolve the path, use the DPO the client provides.
Definition: fib_types.h:356
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
__clib_export uword hash_memory(void *p, word n_bytes, uword state)
Definition: hash.c:275
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:1211
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
struct fib_path_t_::@310::@319 bier_imp
void fib_prefix_from_mpls_label(mpls_label_t label, mpls_eos_bit_t eos, fib_prefix_t *prf)
Definition: fib_types.c:158
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:976
Path resolves via a UDP encap object.
Definition: fib_path.c:88
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1580
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:1319
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:421
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
u32 fp_pl_index
The index of the path-list to which this path belongs.
Definition: fib_path.c:191
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:738
A path that resolves via a glean adjacency.
Definition: fib_types.h:406
#define ASSERT(truth)
int fib_path_is_deag(fib_node_index_t path_index)
Definition: fib_path.c:2660
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
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:366
static int fib_path_is_permanent_drop(fib_path_t *path)
Definition: fib_path.c:868
struct fib_path_t_::@310::@323 receive
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:321
static fib_forward_chain_type_t fib_path_to_chain_type(const fib_path_t *path)
Definition: fib_path.c:950
u8 frp_preference
A path preference.
Definition: fib_types.h:605
bier_table_id_t fp_bier_tbl
The BIER table&#39;s ID.
Definition: fib_path.c:285
Path encode context to use when walking a path-list to encode paths.
Definition: fib_path.h:219
A deag path using the packet&#39;s source not destination address.
Definition: fib_types.h:369
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:609
static void fib_path_attached_get_adj(fib_path_t *path, vnet_link_t link, dpo_id_t *dpo)
Definition: fib_path.c:694
u32 fp_interface
The interface.
Definition: fib_path.c:240
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:2794
vlib_log_class_t fib_path_logger
the logger
Definition: fib_path.c:403
int dpo_cmp(const dpo_id_t *dpo1, const dpo_id_t *dpo2)
Compare two Data-path objects.
Definition: dpo.c:249
A path that resolves via a BIER F-Mask.
Definition: fib_types.h:377
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:389
u32 entries
format_function_t format_mpls_unicast_label
Definition: mpls.h:71
static void fib_path_unresolve(fib_path_t *path)
Definition: fib_path.c:880
fib_route_path_t * rpaths
Definition: fib_path.h:221
mpls_label_t frp_local_label
The MPLS local Label to reursively resolve through.
Definition: fib_types.h:523
dpo_proto_t fib_path_get_proto(fib_node_index_t path_index)
Definition: fib_path.c:2777
fib_path_oper_flags_t fp_oper_flags
Members in this last section represent information that is dervied during resolution.
Definition: fib_path.c:359
int fib_path_is_recursive_constrained(fib_node_index_t path_index)
Definition: fib_path.c:2638
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
adj_index_t adj_glean_add_or_lock(fib_protocol_t proto, vnet_link_t linkt, u32 sw_if_index, const fib_prefix_t *conn)
Glean Adjacency.
Definition: adj_glean.c:112
fib_prefix_t frp_connected
Glean prefix on a glean path.
Definition: fib_types.h:538
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:2149
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:188
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
A for-us/local path.
Definition: fib_types.h:344
u32 path_weight
weight for the path.
Definition: load_balance.h:76
struct fib_path_t_::@310::@327 dvr
struct fib_path_t_::@310::@321 special
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:366
u16 fib_path_get_preference(fib_node_index_t path_index)
Definition: fib_path.c:2243
u64 uword
Definition: types.h:112
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:202
#define FIB_PATH_DBG(_p, _fmt, _args...)
Definition: fib_path.c:408
u32 index
Definition: flow_types.api:221
fib_node_index_t fib_path_create(fib_node_index_t pl_index, const fib_route_path_t *rpath)
Definition: fib_path.c:1271
u8 fp_weight
UCMP [unnormalised] weigth.
Definition: fib_path.c:219
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:1800
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:1230
struct fib_path_t_::@310::@315 attached
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:236
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:263
#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:117
Attached path.
Definition: fib_types.h:348
void udp_encap_unlock(index_t uei)
Definition: udp_encap.c:162
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:226
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:599
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:628
fib_source_t fib_entry_get_best_source(fib_node_index_t entry_index)
Definition: fib_entry.c:1489
u32 frp_udp_encap_id
UDP encap ID.
Definition: fib_types.h:579
enum fib_path_oper_attribute_t_ fib_path_oper_attribute_t
Enurmeration of path operational (i.e.
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:132
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:556
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:427
struct fib_path_t_::@310::@314 attached_next_hop
void fib_path_destroy(fib_node_index_t path_index)
Definition: fib_path.c:1505
#define FOR_EACH_FIB_PATH_CFG_ATTRIBUTE(_item)
Definition: fib_path.h:134
static int fib_path_cmp_i(const fib_path_t *path1, const fib_path_t *path2)
Definition: fib_path.c:1544
int vnet_sw_interface_is_p2p(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1271
const ip46_address_t zero_addr
#include <vnet/feature/feature.h>
Definition: lookup.c:180
int fib_path_cmp_w_route_path(fib_node_index_t path_index, const fib_route_path_t *rpath)
Definition: fib_path.c:1678
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:2693
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:430
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:127