FD.io VPP  v21.10.1-2-g0a485f517
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  */
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;
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 {
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 {
438  ASSERT(FIB_NODE_TYPE_PATH == node->fn_type);
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();
451  fib_path_t *path;
452  const char *eol;
453 
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,
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  }
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);
497  if (path->fp_oper_flags & FIB_PATH_OPER_FLAG_DROP)
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;
528  if (path->fp_oper_flags & FIB_PATH_OPER_FLAG_DROP)
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]",
563  format_dpo_type, path->fp_dpo.dpoi_type,
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]",
575  format_dpo_type, path->fp_dpo.dpoi_type,
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]",
581  format_dpo_type, path->fp_dpo.dpoi_type,
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 {
668 
669  /*
670  * resolve directly via the adjacency discribed by the
671  * interface and next-hop
672  */
673  dpo_copy (&tmp, &path->fp_dpo);
675  dpo_proto_to_link(path->fp_nh_proto),
676  &tmp);
677  dpo_copy(&path->fp_dpo, &tmp);
678  dpo_reset(&tmp);
679  ASSERT(dpo_is_adj(&path->fp_dpo));
680 
681  /*
682  * become a child of the adjacency so we receive updates
683  * when its rewrite changes
684  */
685  path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
688 
690  path->attached_next_hop.fp_interface) ||
691  !adj_is_up(path->fp_dpo.dpoi_index))
692  {
693  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
694  }
695 }
696 
697 static void
699  vnet_link_t link,
700  dpo_id_t *dpo)
701 {
702  fib_protocol_t nh_proto;
703 
704  nh_proto = dpo_proto_to_fib(path->fp_nh_proto);
705 
707  path->attached.fp_interface))
708  {
709  /*
710  * point-2-point interfaces do not require a glean, since
711  * there is nothing to ARP. Install a rewrite/nbr adj instead
712  */
713  adj_index_t ai;
714 
715  ai = adj_nbr_add_or_lock(nh_proto, link, &zero_addr,
716  path->attached.fp_interface);
717 
719  adj_unlock(ai);
720  }
722  path->attached.fp_interface))
723  {
724  dpo_copy(dpo, drop_dpo_get(path->fp_nh_proto));
725  }
726  else
727  {
728  adj_index_t ai;
729 
730  ai = adj_glean_add_or_lock(nh_proto, link,
731  path->attached.fp_interface,
732  &path->attached.fp_connected);
734  adj_unlock(ai);
735  }
736 }
737 
738 /*
739  * create of update the paths recursive adj
740  */
741 static void
744  dpo_id_t *dpo)
745 {
746  dpo_id_t via_dpo = DPO_INVALID;
747 
748  /*
749  * get the DPO to resolve through from the via-entry
750  */
752  fct,
753  &via_dpo);
754 
755 
756  /*
757  * hope for the best - clear if restrictions apply.
758  */
759  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
760 
761  /*
762  * Validate any recursion constraints and over-ride the via
763  * adj if not met
764  */
765  if (path->fp_oper_flags & FIB_PATH_OPER_FLAG_RECURSIVE_LOOP)
766  {
767  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
768  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
769  }
770  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RESOLVE_HOST)
771  {
772  /*
773  * the via FIB must be a host route.
774  * note the via FIB just added will always be a host route
775  * since it is an RR source added host route. So what we need to
776  * check is whether the route has other sources. If it does then
777  * some other source has added it as a host route. If it doesn't
778  * then it was added only here and inherits forwarding from a cover.
779  * the cover is not a host route.
780  * The RR source is the lowest priority source, so we check if it
781  * is the best. if it is there are no other sources.
782  */
783  if (fib_entry_get_best_source(path->fp_via_fib) >= FIB_SOURCE_RR)
784  {
785  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
786  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
787 
788  /*
789  * PIC edge trigger. let the load-balance maps know
790  */
792  }
793  }
794  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED)
795  {
796  /*
797  * RR source entries inherit the flags from the cover, so
798  * we can check the via directly
799  */
800  if (!(FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(path->fp_via_fib)))
801  {
802  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
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  }
811  /*
812  * check for over-riding factors on the FIB entry itself
813  */
814  if (!fib_entry_is_resolved(path->fp_via_fib))
815  {
816  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
817  dpo_copy(&via_dpo, drop_dpo_get(path->fp_nh_proto));
818 
819  /*
820  * PIC edge trigger. let the load-balance maps know
821  */
823  }
824 
825  /*
826  * If this path is contributing a drop, then it's not resolved
827  */
828  if (dpo_is_drop(&via_dpo) || load_balance_is_drop(&via_dpo))
829  {
830  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
831  }
832 
833  /*
834  * update the path's contributed DPO
835  */
836  dpo_copy(dpo, &via_dpo);
837 
838  FIB_PATH_DBG(path, "recursive update:");
839 
840  dpo_reset(&via_dpo);
841 }
842 
843 /*
844  * re-evaulate the forwarding state for a via fmask path
845  */
846 static void
848  dpo_id_t *dpo)
849 {
850  bier_fmask_contribute_forwarding(path->bier_fmask.fp_bier_fmask, dpo);
851 
852  /*
853  * if we are stakcing on the drop, then the path is not resolved
854  */
855  if (dpo_is_drop(dpo))
856  {
857  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
858  }
859  else
860  {
861  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
862  }
863 }
864 
865 /*
866  * fib_path_is_permanent_drop
867  *
868  * Return !0 if the path is configured to permanently drop,
869  * despite other attributes.
870  */
871 static int
873 {
874  return ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DROP) ||
875  (path->fp_oper_flags & FIB_PATH_OPER_FLAG_DROP));
876 }
877 
878 /*
879  * fib_path_unresolve
880  *
881  * Remove our dependency on the resolution target
882  */
883 static void
885 {
886  /*
887  * the forced drop path does not need unresolving
888  */
890  {
891  return;
892  }
893 
894  switch (path->fp_type)
895  {
897  if (FIB_NODE_INDEX_INVALID != path->fp_via_fib)
898  {
899  fib_entry_child_remove(path->fp_via_fib,
900  path->fp_sibling);
901  fib_table_entry_special_remove(path->recursive.fp_tbl_id,
902  fib_entry_get_prefix(path->fp_via_fib),
903  FIB_SOURCE_RR);
904  fib_table_unlock(path->recursive.fp_tbl_id,
905  dpo_proto_to_fib(path->fp_nh_proto),
906  FIB_SOURCE_RR);
907  path->fp_via_fib = FIB_NODE_INDEX_INVALID;
908  }
909  break;
911  bier_fmask_child_remove(path->fp_via_bier_fmask,
912  path->fp_sibling);
913  break;
915  bier_imp_unlock(path->fp_dpo.dpoi_index);
916  break;
918  bier_table_ecmp_unlock(path->fp_via_bier_tbl);
919  break;
922  if (dpo_is_adj(&path->fp_dpo))
923  adj_child_remove(path->fp_dpo.dpoi_index,
924  path->fp_sibling);
925  break;
927  udp_encap_unlock(path->fp_dpo.dpoi_index);
928  break;
930  dpo_reset(&path->exclusive.fp_ex_dpo);
931  break;
935  case FIB_PATH_TYPE_DEAG:
936  case FIB_PATH_TYPE_DVR:
937  /*
938  * these hold only the path's DPO, which is reset below.
939  */
940  break;
941  }
942 
943  /*
944  * release the adj we were holding and pick up the
945  * drop just in case.
946  */
947  dpo_reset(&path->fp_dpo);
948  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
949 
950  return;
951 }
952 
955 {
956  if (DPO_PROTO_MPLS == path->fp_nh_proto)
957  {
958  if (FIB_PATH_TYPE_RECURSIVE == path->fp_type &&
959  MPLS_EOS == path->recursive.fp_nh.fp_eos)
960  {
962  }
963  else
964  {
966  }
967  }
968  else
969  {
970  return (fib_forw_chain_type_from_dpo_proto(path->fp_nh_proto));
971  }
972 }
973 
974 /*
975  * fib_path_back_walk_notify
976  *
977  * A back walk has reach this path.
978  */
982 {
983  fib_path_t *path;
984 
986 
987  FIB_PATH_DBG(path, "bw:%U",
988  format_fib_node_bw_reason, ctx->fnbw_reason);
989 
990  switch (path->fp_type)
991  {
993  if (FIB_NODE_BW_REASON_FLAG_EVALUATE & ctx->fnbw_reason)
994  {
995  /*
996  * modify the recursive adjacency to use the new forwarding
997  * of the via-fib.
998  * this update is visible to packets in flight in the DP.
999  */
1001  path,
1003  &path->fp_dpo);
1004  }
1005  if ((FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE & ctx->fnbw_reason) ||
1006  (FIB_NODE_BW_REASON_FLAG_ADJ_MTU & ctx->fnbw_reason) ||
1007  (FIB_NODE_BW_REASON_FLAG_ADJ_DOWN & ctx->fnbw_reason))
1008  {
1009  /*
1010  * ADJ updates (complete<->incomplete) do not need to propagate to
1011  * recursive entries.
1012  * The only reason its needed as far back as here, is that the adj
1013  * and the incomplete adj are a different DPO type, so the LBs need
1014  * to re-stack.
1015  * If this walk was quashed in the fib_entry, then any non-fib_path
1016  * children (like tunnels that collapse out the LB when they stack)
1017  * would not see the update.
1018  */
1019  return (FIB_NODE_BACK_WALK_CONTINUE);
1020  }
1021  break;
1023  if (FIB_NODE_BW_REASON_FLAG_EVALUATE & ctx->fnbw_reason)
1024  {
1025  /*
1026  * update to use the BIER fmask's new forwading
1027  */
1029  }
1030  if ((FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE & ctx->fnbw_reason) ||
1031  (FIB_NODE_BW_REASON_FLAG_ADJ_DOWN & ctx->fnbw_reason))
1032  {
1033  /*
1034  * ADJ updates (complete<->incomplete) do not need to propagate to
1035  * recursive entries.
1036  * The only reason its needed as far back as here, is that the adj
1037  * and the incomplete adj are a different DPO type, so the LBs need
1038  * to re-stack.
1039  * If this walk was quashed in the fib_entry, then any non-fib_path
1040  * children (like tunnels that collapse out the LB when they stack)
1041  * would not see the update.
1042  */
1043  return (FIB_NODE_BACK_WALK_CONTINUE);
1044  }
1045  break;
1047  /*
1048 FIXME comment
1049  * ADJ_UPDATE backwalk pass silently through here and up to
1050  * the path-list when the multipath adj collapse occurs.
1051  * The reason we do this is that the assumtption is that VPP
1052  * runs in an environment where the Control-Plane is remote
1053  * and hence reacts slowly to link up down. In order to remove
1054  * this down link from the ECMP set quickly, we back-walk.
1055  * VPP also has dedicated CPUs, so we are not stealing resources
1056  * from the CP to do so.
1057  */
1058  if (FIB_NODE_BW_REASON_FLAG_INTERFACE_UP & ctx->fnbw_reason)
1059  {
1060  if (path->fp_oper_flags & FIB_PATH_OPER_FLAG_RESOLVED)
1061  {
1062  /*
1063  * alreday resolved. no need to walk back again
1064  */
1065  return (FIB_NODE_BACK_WALK_CONTINUE);
1066  }
1067  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
1068  }
1069  if (FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN & ctx->fnbw_reason)
1070  {
1071  if (!(path->fp_oper_flags & FIB_PATH_OPER_FLAG_RESOLVED))
1072  {
1073  /*
1074  * alreday unresolved. no need to walk back again
1075  */
1076  return (FIB_NODE_BACK_WALK_CONTINUE);
1077  }
1078  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
1079  }
1080  if (FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE & ctx->fnbw_reason)
1081  {
1082  /*
1083  * The interface this path resolves through has been deleted.
1084  * This will leave the path in a permanent drop state. The route
1085  * needs to be removed and readded (and hence the path-list deleted)
1086  * before it can forward again.
1087  */
1089  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_DROP;
1090  }
1091  if (FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE & ctx->fnbw_reason)
1092  {
1093  /*
1094  * restack the DPO to pick up the correct DPO sub-type
1095  */
1097  uword if_is_up;
1098 
1099  if_is_up = vnet_sw_interface_is_up(
1100  vnet_get_main(),
1101  path->attached_next_hop.fp_interface);
1102 
1103  dpo_copy (&tmp, &path->fp_dpo);
1105  path,
1106  dpo_proto_to_link(path->fp_nh_proto),
1107  &tmp);
1108  dpo_copy(&path->fp_dpo, &tmp);
1109  dpo_reset(&tmp);
1110 
1111  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
1112  if (if_is_up && adj_is_up(path->fp_dpo.dpoi_index))
1113  {
1114  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
1115  }
1116 
1117  if (!if_is_up)
1118  {
1119  /*
1120  * If the interface is not up there is no reason to walk
1121  * back to children. if we did they would only evalute
1122  * that this path is unresolved and hence it would
1123  * not contribute the adjacency - so it would be wasted
1124  * CPU time.
1125  */
1126  return (FIB_NODE_BACK_WALK_CONTINUE);
1127  }
1128  }
1129  if (FIB_NODE_BW_REASON_FLAG_ADJ_DOWN & ctx->fnbw_reason)
1130  {
1131  if (!(path->fp_oper_flags & FIB_PATH_OPER_FLAG_RESOLVED))
1132  {
1133  /*
1134  * alreday unresolved. no need to walk back again
1135  */
1136  return (FIB_NODE_BACK_WALK_CONTINUE);
1137  }
1138  /*
1139  * the adj has gone down. the path is no longer resolved.
1140  */
1141  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
1142  }
1143  break;
1145  case FIB_PATH_TYPE_DVR:
1146  /*
1147  * FIXME; this could schedule a lower priority walk, since attached
1148  * routes are not usually in ECMP configurations so the backwalk to
1149  * the FIB entry does not need to be high priority
1150  */
1151  if (FIB_NODE_BW_REASON_FLAG_INTERFACE_UP & ctx->fnbw_reason)
1152  {
1153  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
1154  }
1155  if (FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN & ctx->fnbw_reason)
1156  {
1157  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
1158  }
1159  if (FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE & ctx->fnbw_reason)
1160  {
1162  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_DROP;
1163  }
1164  break;
1166  {
1167  dpo_id_t via_dpo = DPO_INVALID;
1168 
1169  /*
1170  * hope for the best - clear if restrictions apply.
1171  */
1172  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
1173 
1174  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
1175  path->fp_nh_proto,
1176  &via_dpo);
1177  /*
1178  * If this path is contributing a drop, then it's not resolved
1179  */
1180  if (dpo_is_drop(&via_dpo) || load_balance_is_drop(&via_dpo))
1181  {
1182  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
1183  }
1184 
1185  /*
1186  * update the path's contributed DPO
1187  */
1188  dpo_copy(&path->fp_dpo, &via_dpo);
1189  dpo_reset(&via_dpo);
1190  break;
1191  }
1192  case FIB_PATH_TYPE_INTF_RX:
1193  ASSERT(0);
1194  case FIB_PATH_TYPE_DEAG:
1195  /*
1196  * FIXME When VRF delete is allowed this will need a poke.
1197  */
1198  case FIB_PATH_TYPE_SPECIAL:
1199  case FIB_PATH_TYPE_RECEIVE:
1203  /*
1204  * these path types have no parents. so to be
1205  * walked from one is unexpected.
1206  */
1207  ASSERT(0);
1208  break;
1209  }
1210 
1211  /*
1212  * propagate the backwalk further to the path-list
1213  */
1214  fib_path_list_back_walk(path->fp_pl_index, ctx);
1215 
1216  return (FIB_NODE_BACK_WALK_CONTINUE);
1217 }
1218 
1219 static void
1221 {
1222  fib_show_memory_usage("Path",
1225  sizeof(fib_path_t));
1226 }
1227 
1228 /*
1229  * The FIB path's graph node virtual function table
1230  */
1233  .fnv_last_lock = fib_path_last_lock_gone,
1234  .fnv_back_walk = fib_path_back_walk_notify,
1235  .fnv_mem_show = fib_path_memory_show,
1236 };
1237 
1238 static fib_path_cfg_flags_t
1240 {
1242 
1243  if (rpath->frp_flags & FIB_ROUTE_PATH_POP_PW_CW)
1244  cfg_flags |= FIB_PATH_CFG_FLAG_POP_PW_CW;
1246  cfg_flags |= FIB_PATH_CFG_FLAG_RESOLVE_HOST;
1249  if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
1250  cfg_flags |= FIB_PATH_CFG_FLAG_LOCAL;
1251  if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED)
1252  cfg_flags |= FIB_PATH_CFG_FLAG_ATTACHED;
1253  if (rpath->frp_flags & FIB_ROUTE_PATH_INTF_RX)
1254  cfg_flags |= FIB_PATH_CFG_FLAG_INTF_RX;
1255  if (rpath->frp_flags & FIB_ROUTE_PATH_RPF_ID)
1256  cfg_flags |= FIB_PATH_CFG_FLAG_RPF_ID;
1257  if (rpath->frp_flags & FIB_ROUTE_PATH_EXCLUSIVE)
1258  cfg_flags |= FIB_PATH_CFG_FLAG_EXCLUSIVE;
1259  if (rpath->frp_flags & FIB_ROUTE_PATH_DROP)
1260  cfg_flags |= FIB_PATH_CFG_FLAG_DROP;
1262  cfg_flags |= FIB_PATH_CFG_FLAG_DEAG_SRC;
1264  cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_UNREACH;
1266  cfg_flags |= FIB_PATH_CFG_FLAG_ICMP_PROHIBIT;
1267  if (rpath->frp_flags & FIB_ROUTE_PATH_GLEAN)
1268  cfg_flags |= FIB_PATH_CFG_FLAG_GLEAN;
1269 
1270  return (cfg_flags);
1271 }
1272 
1273 /*
1274  * fib_path_create
1275  *
1276  * Create and initialise a new path object.
1277  * return the index of the path.
1278  */
1281  const fib_route_path_t *rpath)
1282 {
1283  fib_path_t *path;
1284 
1286  clib_memset(path, 0, sizeof(*path));
1287 
1288  fib_node_init(&path->fp_node,
1290 
1291  dpo_reset(&path->fp_dpo);
1292  path->fp_pl_index = pl_index;
1293  path->fp_nh_proto = rpath->frp_proto;
1294  path->fp_via_fib = FIB_NODE_INDEX_INVALID;
1295  path->fp_weight = rpath->frp_weight;
1296  if (0 == path->fp_weight)
1297  {
1298  /*
1299  * a weight of 0 is a meaningless value. We could either reject it, and thus force
1300  * clients to always use 1, or we can accept it and fixup approrpiately.
1301  */
1302  path->fp_weight = 1;
1303  }
1304  path->fp_preference = rpath->frp_preference;
1305  path->fp_cfg_flags = fib_path_route_flags_to_cfg_flags(rpath);
1306 
1307  /*
1308  * deduce the path's tpye from the parementers and save what is needed.
1309  */
1310  if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_LOCAL)
1311  {
1312  path->fp_type = FIB_PATH_TYPE_RECEIVE;
1313  path->receive.fp_interface = rpath->frp_sw_if_index;
1314  path->receive.fp_addr = rpath->frp_addr;
1315  }
1316  else if (rpath->frp_flags & FIB_ROUTE_PATH_UDP_ENCAP)
1317  {
1318  path->fp_type = FIB_PATH_TYPE_UDP_ENCAP;
1319  path->udp_encap.fp_udp_encap_id = rpath->frp_udp_encap_id;
1320  }
1321  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_INTF_RX)
1322  {
1323  path->fp_type = FIB_PATH_TYPE_INTF_RX;
1324  path->intf_rx.fp_interface = rpath->frp_sw_if_index;
1325  }
1326  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID)
1327  {
1328  path->fp_type = FIB_PATH_TYPE_DEAG;
1329  path->deag.fp_tbl_id = rpath->frp_fib_index;
1330  path->deag.fp_rpf_id = rpath->frp_rpf_id;
1331  }
1332  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_FMASK)
1333  {
1334  path->fp_type = FIB_PATH_TYPE_BIER_FMASK;
1335  path->bier_fmask.fp_bier_fmask = rpath->frp_bier_fmask;
1336  }
1337  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_IMP)
1338  {
1339  path->fp_type = FIB_PATH_TYPE_BIER_IMP;
1340  path->bier_imp.fp_bier_imp = rpath->frp_bier_imp;
1341  }
1342  else if (rpath->frp_flags & FIB_ROUTE_PATH_BIER_TABLE)
1343  {
1344  path->fp_type = FIB_PATH_TYPE_BIER_TABLE;
1345  path->bier_table.fp_bier_tbl = rpath->frp_bier_tbl;
1346  }
1347  else if (rpath->frp_flags & FIB_ROUTE_PATH_DEAG)
1348  {
1349  path->fp_type = FIB_PATH_TYPE_DEAG;
1350  path->deag.fp_tbl_id = rpath->frp_fib_index;
1351  }
1352  else if (rpath->frp_flags & FIB_ROUTE_PATH_DVR)
1353  {
1354  path->fp_type = FIB_PATH_TYPE_DVR;
1355  path->dvr.fp_interface = rpath->frp_sw_if_index;
1356  }
1357  else if (rpath->frp_flags & FIB_ROUTE_PATH_EXCLUSIVE)
1358  {
1359  path->fp_type = FIB_PATH_TYPE_EXCLUSIVE;
1360  dpo_copy(&path->exclusive.fp_ex_dpo, &rpath->dpo);
1361  }
1362  else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT) ||
1363  (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH))
1364  {
1365  path->fp_type = FIB_PATH_TYPE_SPECIAL;
1366  }
1367  else if ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY))
1368  {
1369  path->fp_type = FIB_PATH_TYPE_SPECIAL;
1370  path->classify.fp_classify_table_id = rpath->frp_classify_table_id;
1371  }
1372  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_GLEAN)
1373  {
1374  path->fp_type = FIB_PATH_TYPE_ATTACHED;
1375  path->attached.fp_interface = rpath->frp_sw_if_index;
1376  path->attached.fp_connected = rpath->frp_connected;
1377  }
1378  else if (~0 != rpath->frp_sw_if_index)
1379  {
1380  if (ip46_address_is_zero(&rpath->frp_addr))
1381  {
1382  path->fp_type = FIB_PATH_TYPE_ATTACHED;
1383  path->attached.fp_interface = rpath->frp_sw_if_index;
1384  }
1385  else
1386  {
1388  path->attached_next_hop.fp_interface = rpath->frp_sw_if_index;
1389  path->attached_next_hop.fp_nh = rpath->frp_addr;
1390  }
1391  }
1392  else
1393  {
1394  if (ip46_address_is_zero(&rpath->frp_addr))
1395  {
1396  if (~0 == rpath->frp_fib_index)
1397  {
1398  path->fp_type = FIB_PATH_TYPE_SPECIAL;
1399  }
1400  else
1401  {
1402  path->fp_type = FIB_PATH_TYPE_DEAG;
1403  path->deag.fp_tbl_id = rpath->frp_fib_index;
1404  path->deag.fp_rpf_id = ~0;
1405  }
1406  }
1407  else
1408  {
1409  path->fp_type = FIB_PATH_TYPE_RECURSIVE;
1410  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1411  {
1412  path->recursive.fp_nh.fp_local_label = rpath->frp_local_label;
1413  path->recursive.fp_nh.fp_eos = rpath->frp_eos;
1414  }
1415  else
1416  {
1417  path->recursive.fp_nh.fp_ip = rpath->frp_addr;
1418  }
1419  path->recursive.fp_tbl_id = rpath->frp_fib_index;
1420  }
1421  }
1422 
1423  FIB_PATH_DBG(path, "create");
1424 
1425  return (fib_path_get_index(path));
1426 }
1427 
1428 /*
1429  * fib_path_create_special
1430  *
1431  * Create and initialise a new path object.
1432  * return the index of the path.
1433  */
1436  dpo_proto_t nh_proto,
1438  const dpo_id_t *dpo)
1439 {
1440  fib_path_t *path;
1441 
1443  clib_memset(path, 0, sizeof(*path));
1444 
1445  fib_node_init(&path->fp_node,
1447  dpo_reset(&path->fp_dpo);
1448 
1449  path->fp_pl_index = pl_index;
1450  path->fp_weight = 1;
1451  path->fp_preference = 0;
1452  path->fp_nh_proto = nh_proto;
1453  path->fp_via_fib = FIB_NODE_INDEX_INVALID;
1454  path->fp_cfg_flags = flags;
1455 
1457  {
1458  path->fp_type = FIB_PATH_TYPE_SPECIAL;
1459  }
1460  else if (FIB_PATH_CFG_FLAG_LOCAL & flags)
1461  {
1462  path->fp_type = FIB_PATH_TYPE_RECEIVE;
1463  path->attached.fp_interface = FIB_NODE_INDEX_INVALID;
1464  }
1465  else
1466  {
1467  path->fp_type = FIB_PATH_TYPE_EXCLUSIVE;
1468  ASSERT(NULL != dpo);
1469  dpo_copy(&path->exclusive.fp_ex_dpo, dpo);
1470  }
1471 
1472  return (fib_path_get_index(path));
1473 }
1474 
1475 /*
1476  * fib_path_copy
1477  *
1478  * Copy a path. return index of new path.
1479  */
1482  fib_node_index_t path_list_index)
1483 {
1484  fib_path_t *path, *orig_path;
1485 
1487 
1488  orig_path = fib_path_get(path_index);
1489  ASSERT(NULL != orig_path);
1490 
1491  clib_memcpy(path, orig_path, sizeof(*path));
1492 
1493  FIB_PATH_DBG(path, "create-copy:%d", path_index);
1494 
1495  /*
1496  * reset the dynamic section
1497  */
1499  path->fp_oper_flags = FIB_PATH_OPER_FLAG_NONE;
1500  path->fp_pl_index = path_list_index;
1501  path->fp_via_fib = FIB_NODE_INDEX_INVALID;
1502  clib_memset(&path->fp_dpo, 0, sizeof(path->fp_dpo));
1503  dpo_reset(&path->fp_dpo);
1504 
1505  return (fib_path_get_index(path));
1506 }
1507 
1508 /*
1509  * fib_path_destroy
1510  *
1511  * destroy a path that is no longer required
1512  */
1513 void
1515 {
1516  fib_path_t *path;
1517 
1518  path = fib_path_get(path_index);
1519 
1520  ASSERT(NULL != path);
1521  FIB_PATH_DBG(path, "destroy");
1522 
1524 
1525  fib_node_deinit(&path->fp_node);
1527 }
1528 
1529 /*
1530  * fib_path_destroy
1531  *
1532  * destroy a path that is no longer required
1533  */
1534 uword
1536 {
1537  fib_path_t *path;
1538 
1539  path = fib_path_get(path_index);
1540 
1541  return (hash_memory(STRUCT_MARK_PTR(path, path_hash_start),
1542  (STRUCT_OFFSET_OF(fib_path_t, path_hash_end) -
1543  STRUCT_OFFSET_OF(fib_path_t, path_hash_start)),
1544  0));
1545 }
1546 
1547 /*
1548  * fib_path_cmp_i
1549  *
1550  * Compare two paths for equivalence.
1551  */
1552 static int
1554  const fib_path_t *path2)
1555 {
1556  int res;
1557 
1558  res = 1;
1559 
1560  /*
1561  * paths of different types and protocol are not equal.
1562  * different weights and/or preference only are the same path.
1563  */
1564  if (path1->fp_type != path2->fp_type)
1565  {
1566  res = (path1->fp_type - path2->fp_type);
1567  }
1568  else if (path1->fp_nh_proto != path2->fp_nh_proto)
1569  {
1570  res = (path1->fp_nh_proto - path2->fp_nh_proto);
1571  }
1572  else
1573  {
1574  /*
1575  * both paths are of the same type.
1576  * consider each type and its attributes in turn.
1577  */
1578  switch (path1->fp_type)
1579  {
1581  res = ip46_address_cmp(&path1->attached_next_hop.fp_nh,
1582  &path2->attached_next_hop.fp_nh);
1583  if (0 == res) {
1584  res = (path1->attached_next_hop.fp_interface -
1585  path2->attached_next_hop.fp_interface);
1586  }
1587  break;
1589  res = (path1->attached.fp_interface -
1590  path2->attached.fp_interface);
1591  break;
1593  res = ip46_address_cmp(&path1->recursive.fp_nh.fp_ip,
1594  &path2->recursive.fp_nh.fp_ip);
1595 
1596  if (0 == res)
1597  {
1598  res = (path1->recursive.fp_tbl_id - path2->recursive.fp_tbl_id);
1599  }
1600  break;
1602  res = (path1->bier_fmask.fp_bier_fmask -
1603  path2->bier_fmask.fp_bier_fmask);
1604  break;
1606  res = (path1->bier_imp.fp_bier_imp -
1607  path2->bier_imp.fp_bier_imp);
1608  break;
1610  res = bier_table_id_cmp(&path1->bier_table.fp_bier_tbl,
1611  &path2->bier_table.fp_bier_tbl);
1612  break;
1613  case FIB_PATH_TYPE_DEAG:
1614  res = (path1->deag.fp_tbl_id - path2->deag.fp_tbl_id);
1615  if (0 == res)
1616  {
1617  res = (path1->deag.fp_rpf_id - path2->deag.fp_rpf_id);
1618  }
1619  break;
1620  case FIB_PATH_TYPE_INTF_RX:
1621  res = (path1->intf_rx.fp_interface - path2->intf_rx.fp_interface);
1622  break;
1624  res = (path1->udp_encap.fp_udp_encap_id - path2->udp_encap.fp_udp_encap_id);
1625  break;
1626  case FIB_PATH_TYPE_DVR:
1627  res = (path1->dvr.fp_interface - path2->dvr.fp_interface);
1628  break;
1630  res = dpo_cmp(&path1->exclusive.fp_ex_dpo, &path2->exclusive.fp_ex_dpo);
1631  break;
1632  case FIB_PATH_TYPE_SPECIAL:
1633  case FIB_PATH_TYPE_RECEIVE:
1634  res = 0;
1635  break;
1636  }
1637  }
1638  return (res);
1639 }
1640 
1641 /*
1642  * fib_path_cmp_for_sort
1643  *
1644  * Compare two paths for equivalence. Used during path sorting.
1645  * As usual 0 means equal.
1646  */
1647 int
1649  void * v2)
1650 {
1651  fib_node_index_t *pi1 = v1, *pi2 = v2;
1652  fib_path_t *path1, *path2;
1653 
1654  path1 = fib_path_get(*pi1);
1655  path2 = fib_path_get(*pi2);
1656 
1657  /*
1658  * when sorting paths we want the highest preference paths
1659  * first, so that the choices set built is in prefernce order
1660  */
1661  if (path1->fp_preference != path2->fp_preference)
1662  {
1663  return (path1->fp_preference - path2->fp_preference);
1664  }
1665 
1666  return (fib_path_cmp_i(path1, path2));
1667 }
1668 
1669 /*
1670  * fib_path_cmp
1671  *
1672  * Compare two paths for equivalence.
1673  */
1674 int
1676  fib_node_index_t pi2)
1677 {
1678  fib_path_t *path1, *path2;
1679 
1680  path1 = fib_path_get(pi1);
1681  path2 = fib_path_get(pi2);
1682 
1683  return (fib_path_cmp_i(path1, path2));
1684 }
1685 
1686 int
1688  const fib_route_path_t *rpath)
1689 {
1690  fib_path_t *path;
1691  int res;
1692 
1693  path = fib_path_get(path_index);
1694 
1695  res = 1;
1696 
1697  if (path->fp_weight != rpath->frp_weight)
1698  {
1699  res = (path->fp_weight - rpath->frp_weight);
1700  }
1701  else
1702  {
1703  /*
1704  * both paths are of the same type.
1705  * consider each type and its attributes in turn.
1706  */
1707  switch (path->fp_type)
1708  {
1710  res = ip46_address_cmp(&path->attached_next_hop.fp_nh,
1711  &rpath->frp_addr);
1712  if (0 == res)
1713  {
1714  res = (path->attached_next_hop.fp_interface -
1715  rpath->frp_sw_if_index);
1716  }
1717  break;
1719  res = (path->attached.fp_interface - rpath->frp_sw_if_index);
1720  break;
1722  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1723  {
1724  res = path->recursive.fp_nh.fp_local_label - rpath->frp_local_label;
1725 
1726  if (res == 0)
1727  {
1728  res = path->recursive.fp_nh.fp_eos - rpath->frp_eos;
1729  }
1730  }
1731  else
1732  {
1733  res = ip46_address_cmp(&path->recursive.fp_nh.fp_ip,
1734  &rpath->frp_addr);
1735  }
1736 
1737  if (0 == res)
1738  {
1739  res = (path->recursive.fp_tbl_id - rpath->frp_fib_index);
1740  }
1741  break;
1743  res = (path->bier_fmask.fp_bier_fmask - rpath->frp_bier_fmask);
1744  break;
1746  res = (path->bier_imp.fp_bier_imp - rpath->frp_bier_imp);
1747  break;
1749  res = bier_table_id_cmp(&path->bier_table.fp_bier_tbl,
1750  &rpath->frp_bier_tbl);
1751  break;
1752  case FIB_PATH_TYPE_INTF_RX:
1753  res = (path->intf_rx.fp_interface - rpath->frp_sw_if_index);
1754  break;
1756  res = (path->udp_encap.fp_udp_encap_id - rpath->frp_udp_encap_id);
1757  break;
1758  case FIB_PATH_TYPE_DEAG:
1759  res = (path->deag.fp_tbl_id - rpath->frp_fib_index);
1760  if (0 == res)
1761  {
1762  res = (path->deag.fp_rpf_id - rpath->frp_rpf_id);
1763  }
1764  break;
1765  case FIB_PATH_TYPE_DVR:
1766  res = (path->dvr.fp_interface - rpath->frp_sw_if_index);
1767  break;
1769  res = dpo_cmp(&path->exclusive.fp_ex_dpo, &rpath->dpo);
1770  break;
1771  case FIB_PATH_TYPE_RECEIVE:
1772  if (rpath->frp_flags & FIB_ROUTE_PATH_LOCAL)
1773  {
1774  res = 0;
1775  }
1776  else
1777  {
1778  res = 1;
1779  }
1780  break;
1781  case FIB_PATH_TYPE_SPECIAL:
1782  res = 0;
1783  break;
1784  }
1785  }
1786  return (res);
1787 }
1788 
1789 /*
1790  * fib_path_recursive_loop_detect
1791  *
1792  * A forward walk of the FIB object graph to detect for a cycle/loop. This
1793  * walk is initiated when an entry is linking to a new path list or from an old.
1794  * The entry vector passed contains all the FIB entrys that are children of this
1795  * path (it is all the entries encountered on the walk so far). If this vector
1796  * contains the entry this path resolve via, then a loop is about to form.
1797  * The loop must be allowed to form, since we need the dependencies in place
1798  * so that we can track when the loop breaks.
1799  * However, we MUST not produce a loop in the forwarding graph (else packets
1800  * would loop around the switch path until the loop breaks), so we mark recursive
1801  * paths as looped so that they do not contribute forwarding information.
1802  * By marking the path as looped, an etry such as;
1803  * X/Y
1804  * via a.a.a.a (looped)
1805  * via b.b.b.b (not looped)
1806  * can still forward using the info provided by b.b.b.b only
1807  */
1808 int
1810  fib_node_index_t **entry_indicies)
1811 {
1812  fib_path_t *path;
1813 
1814  path = fib_path_get(path_index);
1815 
1816  /*
1817  * the forced drop path is never looped, cos it is never resolved.
1818  */
1820  {
1821  return (0);
1822  }
1823 
1824  switch (path->fp_type)
1825  {
1827  {
1828  fib_node_index_t *entry_index, *entries;
1829  int looped = 0;
1830  entries = *entry_indicies;
1831 
1832  vec_foreach(entry_index, entries) {
1833  if (*entry_index == path->fp_via_fib)
1834  {
1835  /*
1836  * the entry that is about to link to this path-list (or
1837  * one of this path-list's children) is the same entry that
1838  * this recursive path resolves through. this is a cycle.
1839  * abort the walk.
1840  */
1841  looped = 1;
1842  break;
1843  }
1844  }
1845 
1846  if (looped)
1847  {
1848  FIB_PATH_DBG(path, "recursive loop formed");
1849  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RECURSIVE_LOOP;
1850 
1851  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
1852  }
1853  else
1854  {
1855  /*
1856  * no loop here yet. keep forward walking the graph.
1857  */
1858  if (fib_entry_recursive_loop_detect(path->fp_via_fib, entry_indicies))
1859  {
1860  FIB_PATH_DBG(path, "recursive loop formed");
1861  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RECURSIVE_LOOP;
1862  }
1863  else
1864  {
1865  FIB_PATH_DBG(path, "recursive loop cleared");
1866  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RECURSIVE_LOOP;
1867  }
1868  }
1869  break;
1870  }
1873  if (dpo_is_adj(&path->fp_dpo) &&
1874  adj_recursive_loop_detect(path->fp_dpo.dpoi_index,
1875  entry_indicies))
1876  {
1877  FIB_PATH_DBG(path, "recursive loop formed");
1878  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RECURSIVE_LOOP;
1879  }
1880  else
1881  {
1882  FIB_PATH_DBG(path, "recursive loop cleared");
1883  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RECURSIVE_LOOP;
1884  }
1885  break;
1886  case FIB_PATH_TYPE_SPECIAL:
1887  case FIB_PATH_TYPE_DEAG:
1888  case FIB_PATH_TYPE_DVR:
1889  case FIB_PATH_TYPE_RECEIVE:
1890  case FIB_PATH_TYPE_INTF_RX:
1896  /*
1897  * these path types cannot be part of a loop, since they are the leaves
1898  * of the graph.
1899  */
1900  break;
1901  }
1902 
1903  return (fib_path_is_looped(path_index));
1904 }
1905 
1906 int
1908 {
1909  fib_path_t *path;
1910 
1911  path = fib_path_get(path_index);
1912 
1913  /*
1914  * hope for the best.
1915  */
1916  path->fp_oper_flags |= FIB_PATH_OPER_FLAG_RESOLVED;
1917 
1918  /*
1919  * the forced drop path resolves via the drop adj
1920  */
1922  {
1923  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
1924  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
1925  return (fib_path_is_resolved(path_index));
1926  }
1927 
1928  switch (path->fp_type)
1929  {
1932  break;
1934  {
1936 
1937  /*
1938  * path->attached.fp_interface
1939  */
1941  path->attached.fp_interface))
1942  {
1943  path->fp_oper_flags &= ~FIB_PATH_OPER_FLAG_RESOLVED;
1944  }
1946  dpo_proto_to_link(path->fp_nh_proto),
1947  &tmp);
1948 
1949  /*
1950  * re-fetch after possible mem realloc
1951  */
1952  path = fib_path_get(path_index);
1953  dpo_copy(&path->fp_dpo, &tmp);
1954 
1955  /*
1956  * become a child of the adjacency so we receive updates
1957  * when the interface state changes
1958  */
1959  if (dpo_is_adj(&path->fp_dpo))
1960  {
1961  path->fp_sibling = adj_child_add(path->fp_dpo.dpoi_index,
1964  }
1965  dpo_reset(&tmp);
1966  break;
1967  }
1969  {
1970  /*
1971  * Create a RR source entry in the table for the address
1972  * that this path recurses through.
1973  * This resolve action is recursive, hence we may create
1974  * more paths in the process. more creates mean maybe realloc
1975  * of this path.
1976  */
1977  fib_node_index_t fei;
1978  fib_prefix_t pfx;
1979 
1980  ASSERT(FIB_NODE_INDEX_INVALID == path->fp_via_fib);
1981 
1982  if (DPO_PROTO_MPLS == path->fp_nh_proto)
1983  {
1984  fib_prefix_from_mpls_label(path->recursive.fp_nh.fp_local_label,
1985  path->recursive.fp_nh.fp_eos,
1986  &pfx);
1987  }
1988  else
1989  {
1990  fib_prefix_from_ip46_addr(&path->recursive.fp_nh.fp_ip, &pfx);
1991  }
1992 
1993  fib_table_lock(path->recursive.fp_tbl_id,
1994  dpo_proto_to_fib(path->fp_nh_proto),
1995  FIB_SOURCE_RR);
1996  fei = fib_table_entry_special_add(path->recursive.fp_tbl_id,
1997  &pfx,
1998  FIB_SOURCE_RR,
2000 
2001  path = fib_path_get(path_index);
2002  path->fp_via_fib = fei;
2003 
2004  /*
2005  * become a dependent child of the entry so the path is
2006  * informed when the forwarding for the entry changes.
2007  */
2008  path->fp_sibling = fib_entry_child_add(path->fp_via_fib,
2011 
2012  /*
2013  * create and configure the IP DPO
2014  */
2016  path,
2018  &path->fp_dpo);
2019 
2020  break;
2021  }
2023  {
2024  /*
2025  * become a dependent child of the entry so the path is
2026  * informed when the forwarding for the entry changes.
2027  */
2028  path->fp_sibling = bier_fmask_child_add(path->bier_fmask.fp_bier_fmask,
2031 
2032  path->fp_via_bier_fmask = path->bier_fmask.fp_bier_fmask;
2034 
2035  break;
2036  }
2038  bier_imp_lock(path->bier_imp.fp_bier_imp);
2039  bier_imp_contribute_forwarding(path->bier_imp.fp_bier_imp,
2040  DPO_PROTO_IP4,
2041  &path->fp_dpo);
2042  break;
2044  {
2045  /*
2046  * Find/create the BIER table to link to
2047  */
2048  ASSERT(FIB_NODE_INDEX_INVALID == path->fp_via_bier_tbl);
2049 
2050  path->fp_via_bier_tbl =
2051  bier_table_ecmp_create_and_lock(&path->bier_table.fp_bier_tbl);
2052 
2053  bier_table_contribute_forwarding(path->fp_via_bier_tbl,
2054  &path->fp_dpo);
2055  break;
2056  }
2057  case FIB_PATH_TYPE_SPECIAL:
2058  if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT)
2059  {
2060  ip_null_dpo_add_and_lock (path->fp_nh_proto,
2062  &path->fp_dpo);
2063  }
2064  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH)
2065  {
2066  ip_null_dpo_add_and_lock (path->fp_nh_proto,
2068  &path->fp_dpo);
2069  }
2070  else if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_CLASSIFY)
2071  {
2072  dpo_set (&path->fp_dpo, DPO_CLASSIFY,
2073  path->fp_nh_proto,
2074  classify_dpo_create (path->fp_nh_proto,
2075  path->classify.fp_classify_table_id));
2076  }
2077  else
2078  {
2079  /*
2080  * Resolve via the drop
2081  */
2082  dpo_copy(&path->fp_dpo, drop_dpo_get(path->fp_nh_proto));
2083  }
2084  break;
2085  case FIB_PATH_TYPE_DEAG:
2086  {
2087  if (DPO_PROTO_BIER == path->fp_nh_proto)
2088  {
2090  &path->fp_dpo);
2091  }
2092  else
2093  {
2094  /*
2095  * Resolve via a lookup DPO.
2096  * FIXME. control plane should add routes with a table ID
2097  */
2098  lookup_input_t input;
2099  lookup_cast_t cast;
2100 
2101  cast = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID ?
2103  LOOKUP_UNICAST);
2104  input = (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DEAG_SRC ?
2107 
2108  lookup_dpo_add_or_lock_w_fib_index(path->deag.fp_tbl_id,
2109  path->fp_nh_proto,
2110  cast,
2111  input,
2113  &path->fp_dpo);
2114  }
2115  break;
2116  }
2117  case FIB_PATH_TYPE_DVR:
2118  dvr_dpo_add_or_lock(path->dvr.fp_interface,
2119  path->fp_nh_proto,
2120  &path->fp_dpo);
2121  break;
2122  case FIB_PATH_TYPE_RECEIVE:
2123  /*
2124  * Resolve via a receive DPO.
2125  */
2126  receive_dpo_add_or_lock(path->fp_nh_proto,
2127  path->receive.fp_interface,
2128  &path->receive.fp_addr,
2129  &path->fp_dpo);
2130  break;
2132  udp_encap_lock(path->udp_encap.fp_udp_encap_id);
2133  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
2134  path->fp_nh_proto,
2135  &path->fp_dpo);
2136  break;
2137  case FIB_PATH_TYPE_INTF_RX: {
2138  /*
2139  * Resolve via a receive DPO.
2140  */
2141  interface_rx_dpo_add_or_lock(path->fp_nh_proto,
2142  path->intf_rx.fp_interface,
2143  &path->fp_dpo);
2144  break;
2145  }
2147  /*
2148  * Resolve via the user provided DPO
2149  */
2150  dpo_copy(&path->fp_dpo, &path->exclusive.fp_ex_dpo);
2151  break;
2152  }
2153 
2154  return (fib_path_is_resolved(path_index));
2155 }
2156 
2157 u32
2159 {
2160  fib_path_t *path;
2161 
2162  path = fib_path_get(path_index);
2163 
2164  switch (path->fp_type)
2165  {
2167  return (path->attached_next_hop.fp_interface);
2169  return (path->attached.fp_interface);
2170  case FIB_PATH_TYPE_RECEIVE:
2171  return (path->receive.fp_interface);
2173  if (fib_path_is_resolved(path_index))
2174  {
2175  return (fib_entry_get_resolving_interface(path->fp_via_fib));
2176  }
2177  break;
2178  case FIB_PATH_TYPE_DVR:
2179  return (path->dvr.fp_interface);
2180  case FIB_PATH_TYPE_INTF_RX:
2182  case FIB_PATH_TYPE_SPECIAL:
2183  case FIB_PATH_TYPE_DEAG:
2188  break;
2189  }
2190  return (dpo_get_urpf(&path->fp_dpo));
2191 }
2192 
2193 index_t
2195 {
2196  fib_path_t *path;
2197 
2198  path = fib_path_get(path_index);
2199 
2200  switch (path->fp_type)
2201  {
2204  case FIB_PATH_TYPE_RECEIVE:
2205  case FIB_PATH_TYPE_INTF_RX:
2206  case FIB_PATH_TYPE_SPECIAL:
2207  case FIB_PATH_TYPE_DEAG:
2208  case FIB_PATH_TYPE_DVR:
2210  break;
2212  return (path->udp_encap.fp_udp_encap_id);
2214  return (path->fp_via_fib);
2216  return (path->bier_fmask.fp_bier_fmask);
2218  return (path->fp_via_bier_tbl);
2220  return (path->bier_imp.fp_bier_imp);
2221  }
2222  return (~0);
2223 }
2224 
2227 {
2228  fib_path_t *path;
2229 
2230  path = fib_path_get(path_index);
2231 
2232  if (dpo_is_adj(&path->fp_dpo))
2233  {
2234  return (path->fp_dpo.dpoi_index);
2235  }
2236  return (ADJ_INDEX_INVALID);
2237 }
2238 
2239 u16
2241 {
2242  fib_path_t *path;
2243 
2244  path = fib_path_get(path_index);
2245 
2246  ASSERT(path);
2247 
2248  return (path->fp_weight);
2249 }
2250 
2251 u16
2253 {
2254  fib_path_t *path;
2255 
2256  path = fib_path_get(path_index);
2257 
2258  ASSERT(path);
2259 
2260  return (path->fp_preference);
2261 }
2262 
2263 u32
2265 {
2266  fib_path_t *path;
2267 
2268  path = fib_path_get(path_index);
2269 
2270  ASSERT(path);
2271 
2272  if (FIB_PATH_CFG_FLAG_RPF_ID & path->fp_cfg_flags)
2273  {
2274  return (path->deag.fp_rpf_id);
2275  }
2276 
2277  return (~0);
2278 }
2279 
2280 /**
2281  * @brief Contribute the path's adjacency to the list passed.
2282  * By calling this function over all paths, recursively, a child
2283  * can construct its full set of forwarding adjacencies, and hence its
2284  * uRPF list.
2285  */
2286 void
2288  index_t urpf)
2289 {
2290  fib_path_t *path;
2291 
2292  path = fib_path_get(path_index);
2293 
2294  /*
2295  * resolved and unresolved paths contribute to the RPF list.
2296  */
2297  switch (path->fp_type)
2298  {
2300  fib_urpf_list_append(urpf, path->attached_next_hop.fp_interface);
2301  break;
2302 
2304  fib_urpf_list_append(urpf, path->attached.fp_interface);
2305  break;
2306 
2308  if (FIB_NODE_INDEX_INVALID != path->fp_via_fib &&
2309  !fib_path_is_looped(path_index))
2310  {
2311  /*
2312  * there's unresolved due to constraints, and there's unresolved
2313  * due to ain't got no via. can't do nowt w'out via.
2314  */
2315  fib_entry_contribute_urpf(path->fp_via_fib, urpf);
2316  }
2317  break;
2318 
2320  case FIB_PATH_TYPE_SPECIAL:
2321  {
2322  /*
2323  * these path types may link to an adj, if that's what
2324  * the clinet gave
2325  */
2326  u32 rpf_sw_if_index;
2327 
2328  rpf_sw_if_index = dpo_get_urpf(&path->fp_dpo);
2329 
2330  if (~0 != rpf_sw_if_index)
2331  {
2332  fib_urpf_list_append(urpf, rpf_sw_if_index);
2333  }
2334  break;
2335  }
2336  case FIB_PATH_TYPE_DVR:
2337  fib_urpf_list_append(urpf, path->dvr.fp_interface);
2338  break;
2340  fib_urpf_list_append(urpf, path->udp_encap.fp_udp_encap_id);
2341  break;
2342  case FIB_PATH_TYPE_DEAG:
2343  case FIB_PATH_TYPE_RECEIVE:
2344  case FIB_PATH_TYPE_INTF_RX:
2348  /*
2349  * these path types don't link to an adj
2350  */
2351  break;
2352  }
2353 }
2354 
2355 void
2357  dpo_proto_t payload_proto,
2359  dpo_id_t *dpo)
2360 {
2361  fib_path_t *path;
2362 
2363  path = fib_path_get(path_index);
2364 
2365  ASSERT(path);
2366 
2367  switch (path->fp_type)
2368  {
2370  {
2372 
2373  dpo_copy(&tmp, dpo);
2374 
2375  mpls_disp_dpo_create(payload_proto, ~0, mode, &tmp, dpo);
2376  dpo_reset(&tmp);
2377  break;
2378  }
2379  case FIB_PATH_TYPE_DEAG:
2380  {
2382 
2383  dpo_copy(&tmp, dpo);
2384 
2385  mpls_disp_dpo_create(payload_proto,
2386  path->deag.fp_rpf_id,
2387  mode, &tmp, dpo);
2388  dpo_reset(&tmp);
2389  break;
2390  }
2391  case FIB_PATH_TYPE_RECEIVE:
2394  case FIB_PATH_TYPE_INTF_RX:
2397  case FIB_PATH_TYPE_SPECIAL:
2401  case FIB_PATH_TYPE_DVR:
2402  break;
2403  }
2404 
2405  if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_POP_PW_CW)
2406  {
2408 
2409  dpo_copy(&tmp, dpo);
2410 
2411  pw_cw_dpo_create(&tmp, dpo);
2412  dpo_reset(&tmp);
2413  }
2414 }
2415 
2416 void
2419  dpo_id_t *dpo)
2420 {
2421  fib_path_t *path;
2422 
2423  path = fib_path_get(path_index);
2424 
2425  ASSERT(path);
2427 
2428  /*
2429  * The DPO stored in the path was created when the path was resolved.
2430  * This then represents the path's 'native' protocol; IP.
2431  * For all others will need to go find something else.
2432  */
2433  if (fib_path_to_chain_type(path) == fct)
2434  {
2435  dpo_copy(dpo, &path->fp_dpo);
2436  }
2437  else
2438  {
2439  switch (path->fp_type)
2440  {
2442  switch (fct)
2443  {
2452  {
2454  dpo_copy (&tmp, dpo);
2456  path,
2458  &tmp);
2459  dpo_copy (dpo, &tmp);
2460  dpo_reset(&tmp);
2461  break;
2462  }
2464  break;
2465  }
2466  break;
2468  switch (fct)
2469  {
2478  break;
2481  ASSERT(0);
2482  break;
2483  }
2484  break;
2486  switch (fct)
2487  {
2489  bier_table_contribute_forwarding(path->fp_via_bier_tbl, dpo);
2490  break;
2499  ASSERT(0);
2500  break;
2501  }
2502  break;
2504  switch (fct)
2505  {
2508  break;
2517  ASSERT(0);
2518  break;
2519  }
2520  break;
2522  bier_imp_contribute_forwarding(path->bier_imp.fp_bier_imp,
2524  dpo);
2525  break;
2526  case FIB_PATH_TYPE_DEAG:
2527  switch (fct)
2528  {
2535  dpo);
2536  break;
2542  dpo_copy(dpo, &path->fp_dpo);
2543  break;
2545  break;
2548  ASSERT(0);
2549  break;
2550  }
2551  break;
2553  dpo_copy(dpo, &path->exclusive.fp_ex_dpo);
2554  break;
2556  switch (fct)
2557  {
2567  dpo);
2568  break;
2571  {
2572  adj_index_t ai;
2573 
2574  /*
2575  * Create the adj needed for sending IP multicast traffic
2576  */
2578  path->attached.fp_interface))
2579  {
2580  /*
2581  * point-2-point interfaces do not require a glean, since
2582  * there is nothing to ARP. Install a rewrite/nbr adj instead
2583  */
2584  ai = adj_nbr_add_or_lock(dpo_proto_to_fib(path->fp_nh_proto),
2586  &zero_addr,
2587  path->attached.fp_interface);
2588  }
2589  else
2590  {
2591  ai = adj_mcast_add_or_lock(dpo_proto_to_fib(path->fp_nh_proto),
2593  path->attached.fp_interface);
2594  }
2595  dpo_set(dpo, DPO_ADJACENCY,
2597  ai);
2598  adj_unlock(ai);
2599  }
2600  break;
2601  }
2602  break;
2603  case FIB_PATH_TYPE_INTF_RX:
2604  /*
2605  * Create the adj needed for sending IP multicast traffic
2606  */
2608  path->attached.fp_interface,
2609  dpo);
2610  break;
2612  udp_encap_contribute_forwarding(path->udp_encap.fp_udp_encap_id,
2613  path->fp_nh_proto,
2614  dpo);
2615  break;
2616  case FIB_PATH_TYPE_RECEIVE:
2617  case FIB_PATH_TYPE_SPECIAL:
2618  case FIB_PATH_TYPE_DVR:
2619  dpo_copy(dpo, &path->fp_dpo);
2620  break;
2621  }
2622  }
2623 }
2624 
2628  load_balance_path_t *hash_key)
2629 {
2630  load_balance_path_t *mnh;
2631  fib_path_t *path;
2632 
2633  path = fib_path_get(path_index);
2634 
2635  ASSERT(path);
2636 
2637  vec_add2(hash_key, mnh, 1);
2638 
2639  mnh->path_weight = path->fp_weight;
2640  mnh->path_index = path_index;
2641 
2642  if (fib_path_is_resolved(path_index))
2643  {
2644  fib_path_contribute_forwarding(path_index, fct, &mnh->path_dpo);
2645  }
2646  else
2647  {
2648  dpo_copy(&mnh->path_dpo,
2650  }
2651  return (hash_key);
2652 }
2653 
2654 int
2656 {
2657  fib_path_t *path;
2658 
2659  path = fib_path_get(path_index);
2660 
2661  return ((FIB_PATH_TYPE_RECURSIVE == path->fp_type) &&
2662  ((path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED) ||
2663  (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RESOLVE_HOST)));
2664 }
2665 
2666 int
2668 {
2669  fib_path_t *path;
2670 
2671  path = fib_path_get(path_index);
2672 
2673  return (FIB_PATH_TYPE_EXCLUSIVE == path->fp_type);
2674 }
2675 
2676 int
2678 {
2679  fib_path_t *path;
2680 
2681  path = fib_path_get(path_index);
2682 
2683  return (FIB_PATH_TYPE_DEAG == path->fp_type);
2684 }
2685 
2686 int
2688 {
2689  fib_path_t *path;
2690 
2691  path = fib_path_get(path_index);
2692 
2693  return (dpo_id_is_valid(&path->fp_dpo) &&
2694  (path->fp_oper_flags & FIB_PATH_OPER_FLAG_RESOLVED) &&
2695  !fib_path_is_looped(path_index) &&
2697 }
2698 
2699 int
2701 {
2702  fib_path_t *path;
2703 
2704  path = fib_path_get(path_index);
2705 
2706  return (path->fp_oper_flags & FIB_PATH_OPER_FLAG_RECURSIVE_LOOP);
2707 }
2708 
2711  fib_node_index_t path_index,
2712  const fib_path_ext_t *path_ext,
2713  void *args)
2714 {
2715  fib_path_encode_ctx_t *ctx = args;
2716  fib_route_path_t *rpath;
2717  fib_path_t *path;
2718 
2719  path = fib_path_get(path_index);
2720  if (!path)
2721  return (FIB_PATH_LIST_WALK_CONTINUE);
2722 
2723  vec_add2(ctx->rpaths, rpath, 1);
2724  rpath->frp_weight = path->fp_weight;
2725  rpath->frp_preference = path->fp_preference;
2726  rpath->frp_proto = path->fp_nh_proto;
2727  rpath->frp_sw_if_index = ~0;
2728  rpath->frp_fib_index = 0;
2729 
2730  switch (path->fp_type)
2731  {
2732  case FIB_PATH_TYPE_RECEIVE:
2733  rpath->frp_addr = path->receive.fp_addr;
2734  rpath->frp_sw_if_index = path->receive.fp_interface;
2735  rpath->frp_flags |= FIB_ROUTE_PATH_LOCAL;
2736  break;
2738  rpath->frp_sw_if_index = path->attached.fp_interface;
2739  break;
2741  rpath->frp_sw_if_index = path->attached_next_hop.fp_interface;
2742  rpath->frp_addr = path->attached_next_hop.fp_nh;
2743  break;
2745  rpath->frp_bier_fmask = path->bier_fmask.fp_bier_fmask;
2746  break;
2747  case FIB_PATH_TYPE_SPECIAL:
2748  break;
2749  case FIB_PATH_TYPE_DEAG:
2750  rpath->frp_fib_index = path->deag.fp_tbl_id;
2751  if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_RPF_ID)
2752  {
2753  rpath->frp_flags |= FIB_ROUTE_PATH_RPF_ID;
2754  }
2755  break;
2757  rpath->frp_addr = path->recursive.fp_nh.fp_ip;
2758  rpath->frp_fib_index = path->recursive.fp_tbl_id;
2759  break;
2760  case FIB_PATH_TYPE_DVR:
2761  rpath->frp_sw_if_index = path->dvr.fp_interface;
2762  rpath->frp_flags |= FIB_ROUTE_PATH_DVR;
2763  break;
2765  rpath->frp_udp_encap_id = path->udp_encap.fp_udp_encap_id;
2767  break;
2768  case FIB_PATH_TYPE_INTF_RX:
2769  rpath->frp_sw_if_index = path->receive.fp_interface;
2771  break;
2774  default:
2775  break;
2776  }
2777 
2778  if (path_ext && path_ext->fpe_type == FIB_PATH_EXT_MPLS)
2779  {
2780  rpath->frp_label_stack = path_ext->fpe_path.frp_label_stack;
2781  }
2782 
2783  if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_DROP)
2784  rpath->frp_flags |= FIB_ROUTE_PATH_DROP;
2785  if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_UNREACH)
2787  if (path->fp_cfg_flags & FIB_PATH_CFG_FLAG_ICMP_PROHIBIT)
2789 
2790  return (FIB_PATH_LIST_WALK_CONTINUE);
2791 }
2792 
2795 {
2796  fib_path_t *path;
2797 
2798  path = fib_path_get(path_index);
2799 
2800  return (path->fp_nh_proto);
2801 }
2802 
2803 void
2805 {
2807  fib_path_logger = vlib_log_register_class ("fib", "path");
2808 }
2809 
2810 static clib_error_t *
2812  unformat_input_t * input,
2813  vlib_cli_command_t * cmd)
2814 {
2815  fib_node_index_t pi;
2816  fib_path_t *path;
2817 
2818  if (unformat (input, "%d", &pi))
2819  {
2820  /*
2821  * show one in detail
2822  */
2824  {
2825  path = fib_path_get(pi);
2826  u8 *s = format(NULL, "%U", format_fib_path, pi, 1,
2828  s = format(s, "\n children:");
2829  s = fib_node_children_format(path->fp_node.fn_children, s);
2830  vlib_cli_output (vm, "%v", s);
2831  vec_free(s);
2832  }
2833  else
2834  {
2835  vlib_cli_output (vm, "path %d invalid", pi);
2836  }
2837  }
2838  else
2839  {
2840  vlib_cli_output (vm, "FIB Paths");
2842  {
2843  vlib_cli_output (vm, "%U", format_fib_path, pi, 0,
2845  }
2846  }
2847 
2848  return (NULL);
2849 }
2850 
2852  .path = "show fib paths",
2853  .function = show_fib_path_command,
2854  .short_help = "show fib paths",
2855 };
vlib.h
fib_path_to_chain_type
static fib_forward_chain_type_t fib_path_to_chain_type(const fib_path_t *path)
Definition: fib_path.c:954
dpo_is_drop
int dpo_is_drop(const dpo_id_t *dpo)
The Drop DPO will drop all packets, no questions asked.
Definition: drop_dpo.c:33
FIB_NODE_BW_REASON_FLAG_ADJ_DOWN
@ FIB_NODE_BW_REASON_FLAG_ADJ_DOWN
Definition: fib_node.h:163
tmp
u32 * tmp
Definition: interface_output.c:1096
fib_path_logger
vlib_log_class_t fib_path_logger
the logger
Definition: fib_path.c:403
fib_path_copy
fib_node_index_t fib_path_copy(fib_node_index_t path_index, fib_node_index_t path_list_index)
Definition: fib_path.c:1481
fib_path_t_::exclusive
struct fib_path_t_::@301::@313 exclusive
fib_path_t_::fp_sibling
u32 fp_sibling
the index of this path in the parent's child list.
Definition: fib_path.c:385
FIB_PATH_CFG_FLAG_RESOLVE_HOST
@ FIB_PATH_CFG_FLAG_RESOLVE_HOST
Definition: fib_path.h:146
fib_route_path_t_::frp_fib_index
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:556
bier_table_id_cmp
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
fib_entry.h
FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED
@ FIB_PATH_CFG_FLAG_RESOLVE_ATTACHED
Definition: fib_path.h:147
mpls_disposition.h
adj.h
FIB_PATH_CFG_FLAG_DROP
@ FIB_PATH_CFG_FLAG_DROP
Definition: fib_path.h:144
FIB_PATH_CFG_FLAG_POP_PW_CW
@ FIB_PATH_CFG_FLAG_POP_PW_CW
Definition: fib_path.h:156
dpo_cmp
int dpo_cmp(const dpo_id_t *dpo1, const dpo_id_t *dpo2)
Compare two Data-path objects.
Definition: dpo.c:251
DPO_INVALID
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:204
fib_path_type_t_
fib_path_type_t_
Enurmeration of path types.
Definition: fib_path.c:52
bier_table_contribute_forwarding
void bier_table_contribute_forwarding(index_t bti, dpo_id_t *dpo)
Definition: bier_table.c:728
fib_path_oper_flags_t_
fib_path_oper_flags_t_
Path flags from the attributes.
Definition: fib_path.c:172
FIB_PATH_TYPE_RECEIVE
@ FIB_PATH_TYPE_RECEIVE
receive.
Definition: fib_path.c:92
FIB_PATH_OPER_FLAG_DROP
@ FIB_PATH_OPER_FLAG_DROP
Definition: fib_path.c:175
FIB_NODE_BW_REASON_FLAG_INTERFACE_UP
@ FIB_NODE_BW_REASON_FLAG_INTERFACE_UP
Definition: fib_node.h:158
IP_NULL_ACTION_SEND_ICMP_PROHIBIT
@ IP_NULL_ACTION_SEND_ICMP_PROHIBIT
Definition: ip_null_dpo.h:39
fib_entry_get_prefix
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1728
fib_path_is_permanent_drop
static int fib_path_is_permanent_drop(fib_path_t *path)
Definition: fib_path.c:872
fib_node_back_walk_rc_t
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
FIB_PATH_DBG
#define FIB_PATH_DBG(_p, _fmt, _args...)
Definition: fib_path.c:408
fib_route_path_t_::frp_bier_imp
index_t frp_bier_imp
A path via a BIER imposition object.
Definition: fib_types.h:533
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
zero_addr
const ip46_address_t zero_addr
#include <vnet/feature/feature.h>
Definition: lookup.c:182
fib_entry_contribute_urpf
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
fib_path_bier_fmask_update
static void fib_path_bier_fmask_update(fib_path_t *path, dpo_id_t *dpo)
Definition: fib_path.c:847
adj_nbr_add_or_lock
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:257
fib_path_encode_ctx_t_
Path encode context to use when walking a path-list to encode paths.
Definition: fib_path.h:219
DPO_ADJACENCY_GLEAN
@ DPO_ADJACENCY_GLEAN
Definition: dpo.h:109
FIB_PATH_TYPE_DEAG
@ FIB_PATH_TYPE_DEAG
deag.
Definition: fib_path.c:80
load_balance_map_path_state_change
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).
Definition: load_balance_map.c:513
FIB_NODE_BW_REASON_FLAG_ADJ_MTU
@ FIB_NODE_BW_REASON_FLAG_ADJ_MTU
Definition: fib_node.h:162
fib_route_path_t_::frp_weight
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:599
fib_path_t_::classify
struct fib_path_t_::@301::@317 classify
load_balance_path_t_::path_weight
u32 path_weight
weight for the path.
Definition: load_balance.h:76
dpo_proto_t
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
FIB_NODE_TYPE_PATH
@ FIB_NODE_TYPE_PATH
Definition: fib_node.h:36
fib_path_type_t
enum fib_path_type_t_ fib_path_type_t
Enurmeration of path types.
load_balance_map.h
fib_path_recursive_adj_update
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:742
FIB_ROUTE_PATH_ICMP_PROHIBIT
@ FIB_ROUTE_PATH_ICMP_PROHIBIT
Definition: fib_types.h:396
fib_path_memory_show
static void fib_path_memory_show(void)
Definition: fib_path.c:1220
fib_path_t_::fp_bier_fmask
index_t fp_bier_fmask
BIER FMask ID.
Definition: fib_path.c:279
fib_path_t_::attached_next_hop
struct fib_path_t_::@301::@305 attached_next_hop
udp_encap_contribute_forwarding
void udp_encap_contribute_forwarding(index_t uei, dpo_proto_t proto, dpo_id_t *dpo)
Definition: udp_encap.c:131
fib_path_t_::fp_ip
ip46_address_t fp_ip
The next-hop.
Definition: fib_path.c:258
ADJ_INDEX_INVALID
#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
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
fib_path_oper_attribute_names
static const char * fib_path_oper_attribute_names[]
Definition: fib_path.c:392
vlib_log_class_t
u32 vlib_log_class_t
Definition: vlib.h:52
FIB_PATH_TYPE_UDP_ENCAP
@ FIB_PATH_TYPE_UDP_ENCAP
Path resolves via a UDP encap object.
Definition: fib_path.c:88
fib_route_path_t_::frp_bier_tbl
bier_table_id_t frp_bier_tbl
A path that resolves via a BIER Table.
Definition: fib_types.h:574
format_fib_path
u8 * format_fib_path(u8 *s, va_list *args)
Definition: fib_path.c:443
bier_table_id_t_
The ID of a table.
Definition: bier_types.h:394
fib_path_t_::fp_via_bier_tbl
index_t fp_via_bier_tbl
the resolving bier-table
Definition: fib_path.c:370
FIB_FORW_CHAIN_TYPE_MPLS_EOS
@ FIB_FORW_CHAIN_TYPE_MPLS_EOS
Contribute an object that is to be used to forward end-of-stack MPLS packets.
Definition: fib_types.h:128
FIB_PATH_CFG_FLAG_ICMP_UNREACH
@ FIB_PATH_CFG_FLAG_ICMP_UNREACH
Definition: fib_path.h:149
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
FIB_PATH_OPER_FLAG_NONE
@ FIB_PATH_OPER_FLAG_NONE
Definition: fib_path.c:173
dpo_get_urpf
u32 dpo_get_urpf(const dpo_id_t *dpo)
Get a uRPF interface for the DPO.
Definition: dpo.c:389
adj_mcast_add_or_lock
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
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
path
vl_api_fib_path_t path
Definition: mfib_types.api:44
ip46_address_cmp
static int ip46_address_cmp(const ip46_address_t *ip46_1, const ip46_address_t *ip46_2)
Definition: ip46_address.h:80
fib_node_vft_t_
A FIB graph nodes virtual function table.
Definition: fib_node.h:288
adj_mcast.h
FIB_ENTRY_FLAG_ATTACHED
@ FIB_ENTRY_FLAG_ATTACHED
Definition: fib_entry.h:114
fib_path_t_::fp_ex_dpo
dpo_id_t fp_ex_dpo
The user provided 'exclusive' DPO.
Definition: fib_path.c:311
vlib_cli_command_t::path
char * path
Definition: cli.h:96
dvr_dpo.h
FIB_NODE_INDEX_INVALID
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
adj_unlock
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:358
fib_table.h
bier_table_ecmp_create_and_lock
index_t bier_table_ecmp_create_and_lock(const bier_table_id_t *btid)
Definition: bier_table.c:456
fib_path_list_walk_rc_t
enum fib_path_list_walk_rc_t_ fib_path_list_walk_rc_t
return code to control pat-hlist walk
fib_route_path_t_::frp_addr
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:516
FIB_FORW_CHAIN_TYPE_MCAST_IP4
@ FIB_FORW_CHAIN_TYPE_MCAST_IP4
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:132
fib_route_path_t_::frp_rpf_id
fib_rpf_id_t frp_rpf_id
The RPF-ID.
Definition: fib_types.h:550
u16
unsigned short u16
Definition: types.h:57
mode
vl_api_tunnel_mode_t mode
Definition: gre.api:48
entries
u32 entries
Definition: flowhash_template.h:362
fib_path_last_lock_gone
static void fib_path_last_lock_gone(fib_node_t *node)
Definition: fib_path.c:622
FIB_FORW_CHAIN_TYPE_ETHERNET
@ FIB_FORW_CHAIN_TYPE_ETHERNET
Contribute an object that is to be used to forward Ethernet packets.
Definition: fib_types.h:140
fib_path_destroy
void fib_path_destroy(fib_node_index_t path_index)
Definition: fib_path.c:1514
format_dpo_type
u8 * format_dpo_type(u8 *s, va_list *args)
format a DPO type
Definition: dpo.c:140
fib_format_path_flags_t
enum fib_path_format_flags_t_ fib_format_path_flags_t
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
FIB_PATH_TYPES
#define FIB_PATH_TYPES
Definition: fib_path.c:111
FIB_PATH_CFG_FLAG_INTF_RX
@ FIB_PATH_CFG_FLAG_INTF_RX
Definition: fib_path.h:153
bier_fmask_contribute_forwarding
void bier_fmask_contribute_forwarding(index_t bfmi, dpo_id_t *dpo)
Definition: bier_fmask.c:120
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
fib_route_path_t_::frp_eos
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:527
fib_node_children_format
u8 * fib_node_children_format(fib_node_list_t list, u8 *s)
Definition: fib_node.c:176
FIB_PATH_TYPE_ATTACHED_NEXT_HOP
@ FIB_PATH_TYPE_ATTACHED_NEXT_HOP
Attached-nexthop.
Definition: fib_path.c:60
fib_route_path_t_::frp_sw_if_index
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:545
MPLS_EOS
@ MPLS_EOS
Definition: packet.h:39
adj_child_add
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:377
fib_path_module_init
void fib_path_module_init(void)
Definition: fib_path.c:2804
DPO_PROTO_BIER
@ DPO_PROTO_BIER
Definition: dpo.h:68
vnet_get_sw_interface
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:58
FOR_EACH_FIB_PATH_CFG_ATTRIBUTE
#define FOR_EACH_FIB_PATH_CFG_ATTRIBUTE(_item)
Definition: fib_path.h:134
fib_route_path_t_::frp_bier_fmask
index_t frp_bier_fmask
Resolving via a BIER Fmask.
Definition: fib_types.h:589
fib_prefix_from_ip46_addr
void fib_prefix_from_ip46_addr(const ip46_address_t *addr, fib_prefix_t *pfx)
Host prefix from ip.
Definition: fib_types.c:81
fib_path_t_::fp_classify_table_id
u32 fp_classify_table_id
The UDP Encap object this path resolves through.
Definition: fib_path.c:339
FIB_PATH_CFG_FLAG_ICMP_PROHIBIT
@ FIB_PATH_CFG_FLAG_ICMP_PROHIBIT
Definition: fib_path.h:150
hash_memory
__clib_export uword hash_memory(void *p, word n_bytes, uword state)
Definition: hash.c:275
fib_path_stack_mpls_disp
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:2356
fib_path_route_flags_to_cfg_flags
static fib_path_cfg_flags_t fib_path_route_flags_to_cfg_flags(const fib_route_path_t *rpath)
Definition: fib_path.c:1239
format_mpls_eos_bit
format_function_t format_mpls_eos_bit
Definition: mpls.h:70
bier_imp_unlock
void bier_imp_unlock(index_t bii)
Definition: bier_imp.c:110
unformat_input_t
struct _unformat_input_t unformat_input_t
FIB_PATH_OPER_ATTRIBUTES
#define FIB_PATH_OPER_ATTRIBUTES
Definition: fib_path.c:158
fib_path_get_rpf_id
u32 fib_path_get_rpf_id(fib_node_index_t path_index)
Definition: fib_path.c:2264
classify_dpo_create
index_t classify_dpo_create(dpo_proto_t proto, u32 classify_table_index)
Definition: classify_dpo.c:48
fib_route_path_t_::frp_proto
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:505
fib_node.h
fib_path_oper_flags_t
enum fib_path_oper_flags_t_ fib_path_oper_flags_t
Path flags from the attributes.
drop_dpo.h
LOOKUP_MULTICAST
@ LOOKUP_MULTICAST
Definition: lookup_dpo.h:54
fib_path_t_::fp_udp_encap_id
u32 fp_udp_encap_id
The UDP Encap object this path resolves through.
Definition: fib_path.c:333
LOOKUP_INPUT_SRC_ADDR
@ LOOKUP_INPUT_SRC_ADDR
Definition: lookup_dpo.h:27
BIER_SHOW_BRIEF
@ BIER_SHOW_BRIEF
Definition: bier_types.h:26
FIB_PATH_TYPE_DVR
@ FIB_PATH_TYPE_DVR
via a DVR.
Definition: fib_path.c:108
fib_path_is_recursive_constrained
int fib_path_is_recursive_constrained(fib_node_index_t path_index)
Definition: fib_path.c:2655
fib_path_get_index
static fib_node_index_t fib_path_get_index(fib_path_t *path)
Definition: fib_path.c:424
FIB_ROUTE_PATH_DVR
@ FIB_ROUTE_PATH_DVR
A path that resolves via a DVR DPO.
Definition: fib_types.h:393
FIB_PATH_CFG_FLAG_RPF_ID
@ FIB_PATH_CFG_FLAG_RPF_ID
Definition: fib_path.h:154
adj_child_remove
void adj_child_remove(adj_index_t adj_index, u32 sibling_index)
Remove a child dependent.
Definition: adj.c:394
fib_entry_contribute_forwarding
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
fib_path_t_::fp_tbl_id
fib_node_index_t fp_tbl_id
The FIB table index in which to find the next-hop.
Definition: fib_path.c:273
fib_path_from_fib_node
static fib_path_t * fib_path_from_fib_node(fib_node_t *node)
Definition: fib_path.c:436
load_balance_is_drop
int load_balance_is_drop(const dpo_id_t *dpo)
Definition: load_balance.c:299
fib_route_path_t_::frp_label_stack
fib_mpls_label_t * frp_label_stack
The outgoing MPLS label Stack.
Definition: fib_types.h:560
vnet_link_to_dpo_proto
dpo_proto_t vnet_link_to_dpo_proto(vnet_link_t linkt)
Definition: dpo.c:98
fib_path_resolve
int fib_path_resolve(fib_node_index_t path_index)
Definition: fib_path.c:1907
FIB_FORW_CHAIN_TYPE_NSH
@ FIB_FORW_CHAIN_TYPE_NSH
Contribute an object that is to be used to forward NSH packets.
Definition: fib_types.h:146
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
FIB_PATH_OPER_ATTRIBUTE_LAST
@ FIB_PATH_OPER_ATTRIBUTE_LAST
Marker.
Definition: fib_path.c:150
fib_entry_is_resolved
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:1530
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
FIB_NODE_BW_REASON_FLAG_EVALUATE
@ FIB_NODE_BW_REASON_FLAG_EVALUATE
Definition: fib_node.h:157
mpls_fib.h
FIB_FORW_CHAIN_TYPE_UNICAST_IP4
@ FIB_FORW_CHAIN_TYPE_UNICAST_IP4
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:108
FIB_PATH_FORMAT_FLAGS_NONE
@ FIB_PATH_FORMAT_FLAGS_NONE
Definition: fib_path.h:162
fib_path_get_preference
u16 fib_path_get_preference(fib_node_index_t path_index)
Definition: fib_path.c:2252
STRUCT_OFFSET_OF
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:73
fib_path_cmp_for_sort
int fib_path_cmp_for_sort(void *v1, void *v2)
Definition: fib_path.c:1648
pw_cw.h
fib_table_entry_special_remove
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
Definition: fib_table.c:424
fib_path_vft
static const fib_node_vft_t fib_path_vft
Definition: fib_path.c:1231
fib_path_t_::udp_encap
struct fib_path_t_::@301::@316 udp_encap
bier_table.h
fib_path_get_proto
dpo_proto_t fib_path_get_proto(fib_node_index_t path_index)
Definition: fib_path.c:2794
fib_rpf_id_t
u32 fib_rpf_id_t
An RPF-ID is numerical value that is used RPF validate.
Definition: fib_types.h:421
fib_entry_child_add
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
fib_path_t_::dvr
struct fib_path_t_::@301::@318 dvr
FIB_ROUTE_PATH_INTF_RX
@ FIB_ROUTE_PATH_INTF_RX
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:361
dvr_dpo_add_or_lock
void dvr_dpo_add_or_lock(u32 sw_if_index, dpo_proto_t dproto, dpo_id_t *dpo)
Definition: dvr_dpo.c:91
receive_dpo.h
vnet_sw_interface_is_p2p
int vnet_sw_interface_is_p2p(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1313
dpo_proto_to_link
vnet_link_t dpo_proto_to_link(dpo_proto_t dp)
format a DPO protocol
Definition: dpo.c:120
vec_add2
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:644
udp_encap.h
fib_path_t_::fp_connected
fib_prefix_t fp_connected
The Connected local address.
Definition: fib_path.c:246
fib_forward_chain_type_t
enum fib_forward_chain_type_t_ fib_forward_chain_type_t
FIB output chain type.
load_balance_path_t_::path_index
fib_node_index_t path_index
The index of the FIB path.
Definition: load_balance.h:71
fib_forw_chain_type_to_link_type
vnet_link_t fib_forw_chain_type_to_link_type(fib_forward_chain_type_t fct)
Convert from a chain type to the adjacency's link type.
Definition: fib_types.c:465
fib_path_get_resolving_index
index_t fib_path_get_resolving_index(fib_node_index_t path_index)
Definition: fib_path.c:2194
fib_forw_chain_type_to_dpo_proto
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
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
FIB_PATH_TYPE_BIER_TABLE
@ FIB_PATH_TYPE_BIER_TABLE
bier-fmask.
Definition: fib_path.c:100
FIB_PATH_TYPE_BIER_IMP
@ FIB_PATH_TYPE_BIER_IMP
bier-imp.
Definition: fib_path.c:96
format.h
fib_path_t_::fp_pl_index
u32 fp_pl_index
The index of the path-list to which this path belongs.
Definition: fib_path.c:191
FIB_ROUTE_PATH_BIER_TABLE
@ FIB_ROUTE_PATH_BIER_TABLE
A path that resolves via a BIER [ECMP] Table.
Definition: fib_types.h:381
FIB_PATH_OPER_FLAG_RESOLVED
@ FIB_PATH_OPER_FLAG_RESOLVED
Definition: fib_path.c:176
fib_path_t_::STRUCT_MARK
STRUCT_MARK(path_hash_start)
This marks the start of the memory area used to hash the path.
FIB_ENTRY_FLAG_NONE
@ FIB_ENTRY_FLAG_NONE
Definition: fib_entry.h:112
index_t
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:43
FIB_PATH_OPER_FLAG_RECURSIVE_LOOP
@ FIB_PATH_OPER_FLAG_RECURSIVE_LOOP
Definition: fib_path.c:174
LOOKUP_UNICAST
@ LOOKUP_UNICAST
Definition: lookup_dpo.h:53
FIB_ROUTE_PATH_SOURCE_LOOKUP
@ FIB_ROUTE_PATH_SOURCE_LOOKUP
A deag path using the packet's source not destination address.
Definition: fib_types.h:369
LOOKUP_INPUT_DST_ADDR
@ LOOKUP_INPUT_DST_ADDR
Definition: lookup_dpo.h:28
fib_node_index_t
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
fib_show_memory_usage
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
uword
u64 uword
Definition: types.h:112
fib_path_create_special
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:1435
FIB_PATH_CFG_FLAG_ATTACHED
@ FIB_PATH_CFG_FLAG_ATTACHED
Definition: fib_path.h:152
fib_path_t_::bier_table
struct fib_path_t_::@301::@309 bier_table
FIB_ROUTE_PATH_RESOLVE_VIA_HOST
@ FIB_ROUTE_PATH_RESOLVE_VIA_HOST
Recursion constraint of via a host prefix.
Definition: fib_types.h:336
ip_null_dpo.h
STRUCT_MARK_PTR
#define STRUCT_MARK_PTR(v, f)
Definition: clib.h:79
bier_imp.h
dpo_id_is_valid
static int dpo_id_is_valid(const dpo_id_t *dpoi)
Return true if the DPO object is valid, i.e.
Definition: dpo.h:216
fib_route_path_t_::frp_classify_table_id
u32 frp_classify_table_id
Classify table ID.
Definition: fib_types.h:584
fib_path_t_::fp_bier_tbl
bier_table_id_t fp_bier_tbl
The BIER table's ID.
Definition: fib_path.c:285
fib_path_is_exclusive
int fib_path_is_exclusive(fib_node_index_t path_index)
Definition: fib_path.c:2667
FIB_ROUTE_PATH_DEAG
@ FIB_ROUTE_PATH_DEAG
A path that resolves via another table.
Definition: fib_types.h:389
fib_path_t_::fp_cfg_flags
fib_path_cfg_flags_t fp_cfg_flags
Configuration Flags.
Definition: fib_path.c:202
pw_cw_dpo_create
void pw_cw_dpo_create(const dpo_id_t *parent, dpo_id_t *dpo)
Create an PW CW pop.
Definition: pw_cw.c:43
udp_encap_unlock
void udp_encap_unlock(index_t uei)
Definition: udp_encap.c:162
fib_mpls_lsp_mode_t
enum fib_mpls_lsp_mode_t_ fib_mpls_lsp_mode_t
MPLS LSP mode - only valid at the head and tail.
mpls_disp_dpo_create
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.
Definition: mpls_disposition.c:47
fib_path_is_looped
int fib_path_is_looped(fib_node_index_t path_index)
Definition: fib_path.c:2700
FIB_ROUTE_PATH_UDP_ENCAP
@ FIB_ROUTE_PATH_UDP_ENCAP
A path via a UDP encap object.
Definition: fib_types.h:373
bier_table_ecmp_unlock
void bier_table_ecmp_unlock(index_t bti)
Definition: bier_table.c:462
DPO_ADJACENCY
@ DPO_ADJACENCY
Definition: dpo.h:106
pool_get
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:255
fib_path_t_::fp_via_bier_fmask
index_t fp_via_bier_fmask
the resolving bier-fmask
Definition: fib_path.c:374
fib_path_t_::fp_bier_imp
index_t fp_bier_imp
The BIER imposition object this is part of the path's key, since the index_t of an imposition object ...
Definition: fib_path.c:293
FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE
@ FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE
Definition: fib_node.h:161
bier_disp_table.h
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
FIB_ROUTE_PATH_RPF_ID
@ FIB_ROUTE_PATH_RPF_ID
A local path with a RPF-ID => multicast traffic.
Definition: fib_types.h:365
fib_path_contribute_forwarding
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:2417
fib_protocol_t
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
fib_path_get_resolving_interface
u32 fib_path_get_resolving_interface(fib_node_index_t path_index)
Definition: fib_path.c:2158
bier_imp_contribute_forwarding
void bier_imp_contribute_forwarding(index_t bii, dpo_proto_t proto, dpo_id_t *dpo)
Definition: bier_imp.c:174
LOOKUP_TABLE_FROM_CONFIG
@ LOOKUP_TABLE_FROM_CONFIG
Definition: lookup_dpo.h:41
fib_entry_get_resolving_interface
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1474
fib_node_register_type
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
fib_path_t_::fp_dpo
dpo_id_t fp_dpo
The Data-path objects through which this path resolves for IP.
Definition: fib_path.c:380
FIB_PATH_FORMAT_FLAGS_ONE_LINE
@ FIB_PATH_FORMAT_FLAGS_ONE_LINE
Definition: fib_path.h:163
interface_rx_dpo.h
fib_path_is_deag
int fib_path_is_deag(fib_node_index_t path_index)
Definition: fib_path.c:2677
FIB_PATH_TYPE_SPECIAL
@ FIB_PATH_TYPE_SPECIAL
special.
Definition: fib_path.c:72
fib_path_oper_attribute_t_
fib_path_oper_attribute_t_
Enurmeration of path operational (i.e.
Definition: fib_path.c:130
fib_path_t_::fp_interface
u32 fp_interface
The interface.
Definition: fib_path.c:240
FIB_NODE_BACK_WALK_CONTINUE
@ FIB_NODE_BACK_WALK_CONTINUE
Definition: fib_node.h:259
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
format_dpo_id
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject.
Definition: dpo.c:150
fib_path_create
fib_node_index_t fib_path_create(fib_node_index_t pl_index, const fib_route_path_t *rpath)
Definition: fib_path.c:1280
FIB_PATH_CFG_FLAG_LOCAL
@ FIB_PATH_CFG_FLAG_LOCAL
Definition: fib_path.h:148
FIB_PATH_CFG_FLAG_EXCLUSIVE
@ FIB_PATH_CFG_FLAG_EXCLUSIVE
Definition: fib_path.h:145
FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN
@ FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN
Definition: fib_node.h:159
adj_is_up
int adj_is_up(adj_index_t ai)
Return true if the adjacency is 'UP', i.e.
Definition: adj.c:557
FIB_PATH_LIST_WALK_CONTINUE
@ FIB_PATH_LIST_WALK_CONTINUE
Definition: fib_types.h:638
ip46_address_is_zero
static u8 ip46_address_is_zero(const ip46_address_t *ip46)
Definition: ip46_address.h:87
fib_path_t_::receive
struct fib_path_t_::@301::@314 receive
FIB_PATH_TYPE_RECURSIVE
@ FIB_PATH_TYPE_RECURSIVE
recursive.
Definition: fib_path.c:68
bier_imp_lock
void bier_imp_lock(index_t bii)
Definition: bier_imp.c:48
fib_entry_recursive_loop_detect
int fib_entry_recursive_loop_detect(fib_node_index_t entry_index, fib_node_index_t **entry_indicies)
Definition: fib_entry.c:1423
adj_glean_add_or_lock
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_path_t_::fp_rpf_id
fib_rpf_id_t fp_rpf_id
The RPF-ID to tag the packets with.
Definition: fib_path.c:303
fib_path_t_::intf_rx
struct fib_path_t_::@301::@315 intf_rx
IP_NULL_ACTION_SEND_ICMP_UNREACH
@ IP_NULL_ACTION_SEND_ICMP_UNREACH
Definition: ip_null_dpo.h:38
fib_path_t_::recursive
struct fib_path_t_::@301::@307 recursive
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
fib_path_unresolve
static void fib_path_unresolve(fib_path_t *path)
Definition: fib_path.c:884
fib_path_attached_get_adj
static void fib_path_attached_get_adj(fib_path_t *path, vnet_link_t link, dpo_id_t *dpo)
Definition: fib_path.c:698
pool_len
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:139
FIB_PATH_EXT_MPLS
@ FIB_PATH_EXT_MPLS
An MPLS extension that maintains the path's outgoing labels,.
Definition: fib_path_ext.h:31
index
u32 index
Definition: flow_types.api:221
show_fib_path_command
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:2811
FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED
@ FIB_ROUTE_PATH_RESOLVE_VIA_ATTACHED
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:340
dpo_copy
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:264
FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS
@ FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS
Contribute an object that is to be used to forward non-end-of-stack MPLS packets.
Definition: fib_types.h:117
FIB_PATH_TYPE_EXCLUSIVE
@ FIB_PATH_TYPE_EXCLUSIVE
exclusive.
Definition: fib_path.c:76
FIB_PATH_OPER_ATTRIBUTE_RESOLVED
@ FIB_PATH_OPER_ATTRIBUTE_RESOLVED
The path is resolved.
Definition: fib_path.c:142
fib_path_t_::fp_nh
ip46_address_t fp_nh
The next-hop.
Definition: fib_path.c:236
fib_path_attached_next_hop_get_adj
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_path_list.h
fib_route_path_t_::frp_flags
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:609
pool_foreach_index
#define pool_foreach_index(i, v)
Definition: pool.h:572
fib_path_ext_t_::fpe_type
fib_path_ext_type_t fpe_type
The type of path extension.
Definition: fib_path_ext.h:126
dpo_proto_to_fib
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:359
fib_path_t_::bier_imp
struct fib_path_t_::@301::@310 bier_imp
fib_path_cfg_attribute_t
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>
vnet_sw_interface_is_nbma
int vnet_sw_interface_is_nbma(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface.c:1328
FIB_ROUTE_PATH_POP_PW_CW
@ FIB_ROUTE_PATH_POP_PW_CW
Pop a Psuedo Wire Control Word.
Definition: fib_types.h:402
FIB_PATH_OPER_ATTRIBUTE_DROP
@ FIB_PATH_OPER_ATTRIBUTE_DROP
The path has become a permanent drop.
Definition: fib_path.c:146
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
FIB_PATH_CFG_FLAG_DEAG_SRC
@ FIB_PATH_CFG_FLAG_DEAG_SRC
Definition: fib_path.h:155
fib_route_path_t_::dpo
dpo_id_t dpo
Exclusive DPO.
Definition: fib_types.h:564
format_ip46_address
format_function_t format_ip46_address
Definition: ip46_address.h:50
fib_urpf_list_append
void fib_urpf_list_append(index_t ui, u32 sw_if_index)
Append another interface to the list.
Definition: fib_urpf_list.c:100
fib_path_get
static fib_path_t * fib_path_get(fib_node_index_t index)
Definition: fib_path.c:418
FIB_PATH_CFG_FLAG_CLASSIFY
@ FIB_PATH_CFG_FLAG_CLASSIFY
Definition: fib_path.h:151
fib_table_lock
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:1361
fib_path_t_::fp_oper_flags
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
DPO_PROTO_MPLS
@ DPO_PROTO_MPLS
Definition: dpo.h:66
MPLS_FIB_DEFAULT_TABLE_ID
#define MPLS_FIB_DEFAULT_TABLE_ID
Definition: mpls_fib.h:28
ip.h
fib_forw_chain_type_from_dpo_proto
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
u32
unsigned int u32
Definition: types.h:88
fib_path_cfg_attribute_names
static const char * fib_path_cfg_attribute_names[]
Definition: fib_path.c:393
fib_path_ext_t_::fpe_path
fib_route_path_t fpe_path
A description of the path that is being extended.
Definition: fib_path_ext.h:105
fib_urpf_list.h
lookup_dpo.h
fib_route_path_t_
A representation of a path as described by a route producer.
Definition: fib_types.h:500
fib_path_append_nh_for_multipath_hash
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:2626
fib_path_encode
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:2710
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
fib_path_t_::deag
struct fib_path_t_::@301::@311 deag
fib_path_t_::fp_preference
u8 fp_preference
A path preference.
Definition: fib_path.c:226
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE
@ FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE
Definition: fib_node.h:160
FIB_PATH_TYPE_INTF_RX
@ FIB_PATH_TYPE_INTF_RX
interface receive.
Definition: fib_path.c:84
fib_path_is_resolved
int fib_path_is_resolved(fib_node_index_t path_index)
Definition: fib_path.c:2687
FIB_ROUTE_PATH_ICMP_UNREACH
@ FIB_ROUTE_PATH_ICMP_UNREACH
Definition: fib_types.h:395
lookup_input_t
enum lookup_input_t_ lookup_input_t
Switch to use the packet's source or destination address for lookup.
fib_entry_get_flags
fib_entry_flag_t fib_entry_get_flags(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:291
interface_rx_dpo_add_or_lock
void interface_rx_dpo_add_or_lock(dpo_proto_t proto, u32 sw_if_index, dpo_id_t *dpo)
Definition: interface_rx_dpo.c:86
pool_elts
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127
fib_path_t
struct fib_path_t_ fib_path_t
A FIB path.
FIB_PATH_CFG_ATTRIBUTES
#define FIB_PATH_CFG_ATTRIBUTES
Definition: fib_path.h:117
fib_path_cmp
int fib_path_cmp(fib_node_index_t pi1, fib_node_index_t pi2)
Definition: fib_path.c:1675
lookup_cast_t
enum lookup_cast_t_ lookup_cast_t
Switch to use the packet's source or destination address for lookup.
FIB_ROUTE_PATH_ATTACHED
@ FIB_ROUTE_PATH_ATTACHED
Attached path.
Definition: fib_types.h:348
FIB_FORW_CHAIN_TYPE_BIER
@ FIB_FORW_CHAIN_TYPE_BIER
Contribute an object that is to be used to forward BIER packets.
Definition: fib_types.h:121
format_bier_imp
u8 * format_bier_imp(u8 *s, va_list *args)
Definition: bier_imp.c:137
fib_path_t_
A FIB path.
Definition: fib_path.c:182
FIB_FORW_CHAIN_TYPE_MCAST_IP6
@ FIB_FORW_CHAIN_TYPE_MCAST_IP6
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:136
fib_node_t_
An node in the FIB graph.
Definition: fib_node.h:301
fib_path_t_::bier_fmask
struct fib_path_t_::@301::@308 bier_fmask
adj_index_t
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
fib_path_t_::fp_weight
u8 fp_weight
UCMP [unnormalised] weigth.
Definition: fib_path.c:219
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
fib_path_t_::fp_type
fib_path_type_t fp_type
The type of the path.
Definition: fib_path.c:207
fib_path_contribute_urpf
void fib_path_contribute_urpf(fib_node_index_t path_index, index_t urpf)
Contribute the path's adjacency to the list passed.
Definition: fib_path.c:2287
fib_path_get_adj
adj_index_t fib_path_get_adj(fib_node_index_t path_index)
Definition: fib_path.c:2226
drop_dpo_get
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
vnet_link_t
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
fib_node_init
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:185
receive_dpo_add_or_lock
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
format_dpo_proto
u8 * format_dpo_proto(u8 *s, va_list *args)
format a DPO protocol
Definition: dpo.c:180
fib_prefix_from_mpls_label
void fib_prefix_from_mpls_label(mpls_label_t label, mpls_eos_bit_t eos, fib_prefix_t *prf)
Definition: fib_types.c:158
fib_path_t_::fp_addr
ip46_address_t fp_addr
The next-hop.
Definition: fib_path.c:321
fib_path_cmp_i
static int fib_path_cmp_i(const fib_path_t *path1, const fib_path_t *path2)
Definition: fib_path.c:1553
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
fib_path_t_::special
struct fib_path_t_::@301::@312 special
FIB_ROUTE_PATH_GLEAN
@ FIB_ROUTE_PATH_GLEAN
A path that resolves via a glean adjacency.
Definition: fib_types.h:406
FIB_PATH_OPER_ATTRIBUTE_FIRST
@ FIB_PATH_OPER_ATTRIBUTE_FIRST
Marker.
Definition: fib_path.c:134
lookup_dpo_add_or_lock_w_table_id
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
FIB_PATH_TYPE_FIRST
@ FIB_PATH_TYPE_FIRST
Marker.
Definition: fib_path.c:56
dpo_is_adj
int dpo_is_adj(const dpo_id_t *dpo)
Return TRUE is the DPO is any type of adjacency.
Definition: dpo.c:282
fib_internal.h
bier_fmask_child_add
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
fib_path_ext_t_
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_table_unlock
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:1342
fib_path_t_::fp_node
fib_node_t fp_node
A path is a node in the FIB graph.
Definition: fib_path.c:186
format_bier_table_id
u8 * format_bier_table_id(u8 *s, va_list *ap)
Format a BIER table ID.
Definition: bier_types.c:193
DPO_PROTO_IP4
@ DPO_PROTO_IP4
Definition: dpo.h:64
fib_node_back_walk_ctx_t_
Context passed between object during a back walk.
Definition: fib_node.h:214
FIB_SOURCE_RR
@ FIB_SOURCE_RR
Recursive resolution source.
Definition: fib_source.h:122
fib_node_vft_t_::fnv_get
fib_node_get_t fnv_get
Definition: fib_node.h:289
FIB_ROUTE_PATH_DROP
@ FIB_ROUTE_PATH_DROP
A Drop path - resolve the path on the drop DPO.
Definition: fib_types.h:352
FIB_PATH_CFG_FLAG_GLEAN
@ FIB_PATH_CFG_FLAG_GLEAN
Definition: fib_path.h:157
fib_path.h
vnet_sw_interface_is_up
static uword vnet_sw_interface_is_up(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:339
ip_null_dpo_add_and_lock
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
bier_fmask.h
dpo_id_t_
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:172
fib_path_type_names
static const char * fib_path_type_names[]
Definition: fib_path.c:391
mpls_label_t
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:26
fib_path_get_node
static fib_node_t * fib_path_get_node(fib_node_index_t index)
Definition: fib_path.c:430
fib_route_path_t_::frp_preference
u8 frp_preference
A path preference.
Definition: fib_types.h:605
DPO_CLASSIFY
@ DPO_CLASSIFY
Definition: dpo.h:115
IP46_TYPE_ANY
@ IP46_TYPE_ANY
Definition: ip46_address.h:24
fib_path_cmp_w_route_path
int fib_path_cmp_w_route_path(fib_node_index_t path_index, const fib_route_path_t *rpath)
Definition: fib_path.c:1687
fib_route_path_t_::frp_udp_encap_id
u32 frp_udp_encap_id
UDP encap ID.
Definition: fib_types.h:579
FIB_ROUTE_PATH_EXCLUSIVE
@ FIB_ROUTE_PATH_EXCLUSIVE
Don't resolve the path, use the DPO the client provides.
Definition: fib_types.h:356
fib_node_deinit
void fib_node_deinit(fib_node_t *node)
Definition: fib_node.c:197
load_balance_path_t_::path_dpo
dpo_id_t path_dpo
ID of the Data-path object.
Definition: load_balance.h:66
fib_path_ext.h
FIB_ROUTE_PATH_BIER_IMP
@ FIB_ROUTE_PATH_BIER_IMP
A path that resolves via a BIER impostion object.
Definition: fib_types.h:385
fib_path_t_::attached
struct fib_path_t_::@301::@306 attached
adj_recursive_loop_detect
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:225
vnet.h
FIB_FORW_CHAIN_TYPE_UNICAST_IP6
@ FIB_FORW_CHAIN_TYPE_UNICAST_IP6
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:112
dpo_set
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:188
fib_path_list_back_walk
void fib_path_list_back_walk(fib_node_index_t path_list_index, fib_node_back_walk_ctx_t *ctx)
Definition: fib_path_list.c:465
FIB_ROUTE_PATH_BIER_FMASK
@ FIB_ROUTE_PATH_BIER_FMASK
A path that resolves via a BIER F-Mask.
Definition: fib_types.h:377
fib_path_get_weight
u16 fib_path_get_weight(fib_node_index_t path_index)
Definition: fib_path.c:2240
show_fib_path
static vlib_cli_command_t show_fib_path
(constructor) VLIB_CLI_COMMAND (show_fib_path)
Definition: fib_path.c:2851
fib_table_entry_special_add
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 'special' entry to the FIB.
Definition: fib_table.c:405
mpls_eos_bit_t
enum mpls_eos_bit_t_ mpls_eos_bit_t
fib_path_t_::fp_nh_proto
dpo_proto_t fp_nh_proto
The protocol of the next-hop, i.e.
Definition: fib_path.c:214
fib_path_pool
static fib_path_t * fib_path_pool
Definition: fib_path.c:398
fib_entry_child_remove
void fib_entry_child_remove(fib_node_index_t fib_entry_index, u32 sibling_index)
Definition: fib_entry.c:566
bier_disp_table_contribute_forwarding
void bier_disp_table_contribute_forwarding(index_t bdti, dpo_id_t *dpo)
Definition: bier_disp_table.c:132
vlib_cli_command_t
Definition: cli.h:92
fib_path_attached_next_hop_set
static void fib_path_attached_next_hop_set(fib_path_t *path)
Definition: fib_path.c:665
fib_path_cfg_flags_t
enum fib_path_cfg_flags_t_ fib_path_cfg_flags_t
Path config flags from the attributes.
format_mpls_unicast_label
format_function_t format_mpls_unicast_label
Definition: mpls.h:72
bier_fmask_child_remove
void bier_fmask_child_remove(fib_node_index_t bfmi, u32 sibling_index)
Definition: bier_fmask.c:152
FIB_PATH_OPER_ATTRIBUTE_RECURSIVE_LOOP
@ FIB_PATH_OPER_ATTRIBUTE_RECURSIVE_LOOP
The path forms part of a recursive loop.
Definition: fib_path.c:138
fib_path_back_walk_notify
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:980
load_balance_path_t_
One path from an [EU]CMP set that the client wants to add to a load-balance object.
Definition: load_balance.h:62
lookup_dpo_add_or_lock_w_fib_index
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
fib_route_path_t_::frp_local_label
mpls_label_t frp_local_label
The MPLS local Label to reursively resolve through.
Definition: fib_types.h:523
udp_encap_lock
void udp_encap_lock(index_t uei)
Definition: udp_encap.c:149
FOR_EACH_FIB_PATH_OPER_ATTRIBUTE
#define FOR_EACH_FIB_PATH_OPER_ATTRIBUTE(_item)
Definition: fib_path.c:164
fib_path_recursive_loop_detect
int fib_path_recursive_loop_detect(fib_node_index_t path_index, fib_node_index_t **entry_indicies)
Definition: fib_path.c:1809
fib_path_oper_attribute_t
enum fib_path_oper_attribute_t_ fib_path_oper_attribute_t
Enurmeration of path operational (i.e.
FIB_PATH_CFG_FLAG_NONE
@ FIB_PATH_CFG_FLAG_NONE
Definition: fib_path.h:143
dpo_reset
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:234
fib_route_path_t_::frp_connected
fib_prefix_t frp_connected
Glean prefix on a glean path.
Definition: fib_types.h:538
format_fib_node_bw_reason
u8 * format_fib_node_bw_reason(u8 *s, va_list *args)
Definition: fib_walk.c:973
fib_path_hash
uword fib_path_hash(fib_node_index_t path_index)
Definition: fib_path.c:1535
classify_dpo.h
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
fib_entry_get_best_source
fib_source_t fib_entry_get_best_source(fib_node_index_t entry_index)
Definition: fib_entry.c:1505
FIB_ROUTE_PATH_LOCAL
@ FIB_ROUTE_PATH_LOCAL
A for-us/local path.
Definition: fib_types.h:344
FIB_PATH_TYPE_BIER_FMASK
@ FIB_PATH_TYPE_BIER_FMASK
bier-fmask.
Definition: fib_path.c:104
fib_path_t_::fp_local_label
mpls_label_t fp_local_label
The local label to resolve through.
Definition: fib_path.c:263
format_white_space
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
fib_path_t_::fp_eos
mpls_eos_bit_t fp_eos
The EOS bit of the resolving label.
Definition: fib_path.c:267
format_vnet_sw_interface_name
format_function_t format_vnet_sw_interface_name
Definition: interface_funcs.h:456
FIB_PATH_TYPE_ATTACHED
@ FIB_PATH_TYPE_ATTACHED
attached.
Definition: fib_path.c:64
fib_path_t_::fp_via_fib
fib_node_index_t fp_via_fib
the resolving via fib.
Definition: fib_path.c:366
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105