FD.io VPP  v21.06
Vector Packet Processing
fib_table.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/dpo/drop_dpo.h>
18 
19 #include <vnet/fib/fib_table.h>
21 #include <vnet/fib/fib_internal.h>
22 #include <vnet/fib/ip4_fib.h>
23 #include <vnet/fib/ip6_fib.h>
24 #include <vnet/fib/mpls_fib.h>
25 
27 
31 {
32  switch (proto)
33  {
34  case FIB_PROTOCOL_IP4:
35  return (pool_elt_at_index(ip4_main.fibs, index));
36  case FIB_PROTOCOL_IP6:
37  return (pool_elt_at_index(ip6_main.fibs, index));
38  case FIB_PROTOCOL_MPLS:
39  return (pool_elt_at_index(mpls_main.fibs, index));
40  }
41  ASSERT(0);
42  return (NULL);
43 }
44 
45 static inline fib_node_index_t
47  const fib_prefix_t *prefix)
48 {
49  switch (prefix->fp_proto)
50  {
51  case FIB_PROTOCOL_IP4:
52  return (ip4_fib_table_lookup(ip4_fib_get(fib_table->ft_index),
53  &prefix->fp_addr.ip4,
54  prefix->fp_len));
55  case FIB_PROTOCOL_IP6:
56  return (ip6_fib_table_lookup(fib_table->ft_index,
57  &prefix->fp_addr.ip6,
58  prefix->fp_len));
59  case FIB_PROTOCOL_MPLS:
60  return (mpls_fib_table_lookup(mpls_fib_get(fib_table->ft_index),
61  prefix->fp_label,
62  prefix->fp_eos));
63  }
64  return (FIB_NODE_INDEX_INVALID);
65 }
66 
68 fib_table_lookup (u32 fib_index,
69  const fib_prefix_t *prefix)
70 {
71  return (fib_table_lookup_i(fib_table_get(fib_index, prefix->fp_proto), prefix));
72 }
73 
74 static inline fib_node_index_t
76  const fib_prefix_t *prefix)
77 {
78  switch (prefix->fp_proto)
79  {
80  case FIB_PROTOCOL_IP4:
82  &prefix->fp_addr.ip4,
83  prefix->fp_len));
84  case FIB_PROTOCOL_IP6:
85  return (ip6_fib_table_lookup_exact_match(fib_table->ft_index,
86  &prefix->fp_addr.ip6,
87  prefix->fp_len));
88  case FIB_PROTOCOL_MPLS:
89  return (mpls_fib_table_lookup(mpls_fib_get(fib_table->ft_index),
90  prefix->fp_label,
91  prefix->fp_eos));
92  }
93  return (FIB_NODE_INDEX_INVALID);
94 }
95 
98  const fib_prefix_t *prefix)
99 {
101  prefix->fp_proto),
102  prefix));
103 }
104 
105 static fib_node_index_t
107  const fib_prefix_t *prefix)
108 {
109  fib_prefix_t pfx;
110 
111  pfx = *prefix;
112 
113  if (FIB_PROTOCOL_MPLS == pfx.fp_proto)
114  {
115  return (FIB_NODE_INDEX_INVALID);
116  }
117 
118  /*
119  * in the absence of a tree structure for the table that allows for an O(1)
120  * parent get, a cheeky way to find the cover is to LPM for the prefix with
121  * mask-1.
122  * there should always be a cover, though it may be the default route. the
123  * default route's cover is the default route.
124  */
125  if (pfx.fp_len != 0) {
126  pfx.fp_len -= 1;
127  }
128 
129  return (fib_table_lookup_i(fib_table, &pfx));
130 }
131 
134  const fib_prefix_t *prefix)
135 {
137  prefix->fp_proto),
138  prefix));
139 }
140 
141 static void
143  const fib_prefix_t *prefix,
144  fib_node_index_t fib_entry_index)
145 {
147 
148  fib_table->ft_total_route_counts--;
149 
150  switch (prefix->fp_proto)
151  {
152  case FIB_PROTOCOL_IP4:
154  &prefix->fp_addr.ip4,
155  prefix->fp_len);
156  break;
157  case FIB_PROTOCOL_IP6:
159  &prefix->fp_addr.ip6,
160  prefix->fp_len);
161  break;
162  case FIB_PROTOCOL_MPLS:
164  prefix->fp_label,
165  prefix->fp_eos);
166  break;
167  }
168 
169  fib_entry_unlock(fib_entry_index);
170 }
171 
172 static void
174  const fib_prefix_t *prefix,
175  fib_node_index_t fib_entry_index)
176 {
177  fib_node_index_t fib_entry_cover_index;
178 
179  /*
180  * no cover relationships in the MPLS FIB
181  */
182  if (FIB_PROTOCOL_MPLS == prefix->fp_proto)
183  return;
184 
185  /*
186  * find the covering entry
187  */
188  fib_entry_cover_index = fib_table_get_less_specific_i(fib_table, prefix);
189  /*
190  * the indicies are the same when the default route is first added
191  */
192  if (fib_entry_cover_index != fib_entry_index)
193  {
194  /*
195  * push any inherting sources from the cover onto the covered
196  */
197  fib_entry_inherit(fib_entry_cover_index,
198  fib_entry_index);
199 
200  /*
201  * inform the covering entry that a new more specific
202  * has been inserted beneath it.
203  * If the prefix that has been inserted is a host route
204  * then it is not possible that it will be the cover for any
205  * other entry, so we can elide the walk. This is particularly
206  * beneficial since there are often many host entries sharing the
207  * same cover (i.e. ADJ or RR sourced entries).
208  */
209  if (!fib_entry_is_host(fib_entry_index))
210  {
211  fib_entry_cover_change_notify(fib_entry_cover_index,
212  fib_entry_index);
213  }
214  }
215 }
216 
217 static void
219  const fib_prefix_t *prefix,
220  fib_node_index_t fib_entry_index)
221 {
223 
224  fib_entry_lock(fib_entry_index);
225  fib_table->ft_total_route_counts++;
226 
227  switch (prefix->fp_proto)
228  {
229  case FIB_PROTOCOL_IP4:
231  &prefix->fp_addr.ip4,
232  prefix->fp_len,
233  fib_entry_index);
234  break;
235  case FIB_PROTOCOL_IP6:
237  &prefix->fp_addr.ip6,
238  prefix->fp_len,
239  fib_entry_index);
240  break;
241  case FIB_PROTOCOL_MPLS:
243  prefix->fp_label,
244  prefix->fp_eos,
245  fib_entry_index);
246  break;
247  }
248 
249  fib_table_post_insert_actions(fib_table, prefix, fib_entry_index);
250 }
251 
252 void
254  const fib_prefix_t *prefix,
255  const dpo_id_t *dpo)
256 {
258 
259  switch (prefix->fp_proto)
260  {
261  case FIB_PROTOCOL_IP4:
262  return (ip4_fib_table_fwding_dpo_update(ip4_fib_get(fib_index),
263  &prefix->fp_addr.ip4,
264  prefix->fp_len,
265  dpo));
266  case FIB_PROTOCOL_IP6:
267  return (ip6_fib_table_fwding_dpo_update(fib_index,
268  &prefix->fp_addr.ip6,
269  prefix->fp_len,
270  dpo));
271  case FIB_PROTOCOL_MPLS:
273  prefix->fp_label,
274  prefix->fp_eos,
275  dpo));
276  }
277 }
278 
279 void
281  const fib_prefix_t *prefix,
282  const dpo_id_t *dpo)
283 {
285 
286  switch (prefix->fp_proto)
287  {
288  case FIB_PROTOCOL_IP4:
289  return (ip4_fib_table_fwding_dpo_remove(ip4_fib_get(fib_index),
290  &prefix->fp_addr.ip4,
291  prefix->fp_len,
292  dpo,
293  fib_table_get_less_specific(fib_index,
294  prefix)));
295  case FIB_PROTOCOL_IP6:
296  return (ip6_fib_table_fwding_dpo_remove(fib_index,
297  &prefix->fp_addr.ip6,
298  prefix->fp_len,
299  dpo));
300  case FIB_PROTOCOL_MPLS:
302  prefix->fp_label,
303  prefix->fp_eos));
304  }
305 }
306 
307 static void
309  fib_source_t source)
310 {
311  vec_validate (fib_table->ft_src_route_counts, source);
312  fib_table->ft_src_route_counts[source]++;
313 }
314 
315 static void
317  fib_source_t source)
318 {
319  vec_validate (fib_table->ft_src_route_counts, source);
320  fib_table->ft_src_route_counts[source]--;
321 }
322 
325  const fib_prefix_t *prefix,
326  fib_source_t source,
328  const dpo_id_t *dpo)
329 {
330  fib_node_index_t fib_entry_index;
331  fib_table_t *fib_table;
332 
333  fib_table = fib_table_get(fib_index, prefix->fp_proto);
334  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
335 
336  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
337  {
338  fib_entry_index = fib_entry_create_special(fib_index, prefix,
339  source, flags,
340  dpo);
341 
342  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
343  fib_table_source_count_inc(fib_table, source);
344  }
345  else
346  {
347  int was_sourced;
348 
349  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
350  fib_entry_special_add(fib_entry_index, source, flags, dpo);
351 
352  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
353  {
354  fib_table_source_count_inc(fib_table, source);
355  }
356  }
357 
358 
359  return (fib_entry_index);
360 }
361 
364  const fib_prefix_t *prefix,
365  fib_source_t source,
367  const dpo_id_t *dpo)
368 {
369  fib_node_index_t fib_entry_index;
370  fib_table_t *fib_table;
371 
372  fib_table = fib_table_get(fib_index, prefix->fp_proto);
373  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
374 
375  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
376  {
377  fib_entry_index = fib_entry_create_special(fib_index, prefix,
378  source, flags,
379  dpo);
380 
381  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
382  fib_table_source_count_inc(fib_table, source);
383  }
384  else
385  {
386  int was_sourced;
387 
388  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
389 
390  if (was_sourced)
391  fib_entry_special_update(fib_entry_index, source, flags, dpo);
392  else
393  fib_entry_special_add(fib_entry_index, source, flags, dpo);
394 
395  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
396  {
397  fib_table_source_count_inc(fib_table, source);
398  }
399  }
400 
401  return (fib_entry_index);
402 }
403 
406  const fib_prefix_t *prefix,
407  fib_source_t source,
409 {
410  fib_node_index_t fib_entry_index;
411  dpo_id_t tmp_dpo = DPO_INVALID;
412 
413  dpo_copy(&tmp_dpo, drop_dpo_get(fib_proto_to_dpo(prefix->fp_proto)));
414 
415  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix, source,
416  flags, &tmp_dpo);
417 
418  dpo_unlock(&tmp_dpo);
419 
420  return (fib_entry_index);
421 }
422 
423 void
425  const fib_prefix_t *prefix,
426  fib_source_t source)
427 {
428  /*
429  * 1 is it present
430  * yes => remove source
431  * 2 - is it still sourced?
432  * no => cover walk
433  */
434  fib_node_index_t fib_entry_index;
435  fib_table_t *fib_table;
436 
437  fib_table = fib_table_get(fib_index, prefix->fp_proto);
438  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
439 
440  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
441  {
442  /*
443  * removing an etry that does not exist. i'll allow it.
444  */
445  }
446  else
447  {
448  fib_entry_src_flag_t src_flag;
449  int was_sourced;
450 
451  /*
452  * don't nobody go nowhere
453  */
454  fib_entry_lock(fib_entry_index);
455  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
456 
457  src_flag = fib_entry_special_remove(fib_entry_index, source);
458 
459  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
460  {
461  /*
462  * last source gone. remove from the table
463  */
464  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
465 
466  /*
467  * now the entry is no longer in the table, we can
468  * inform the entries that it covers to re-calculate their cover
469  */
470  fib_entry_cover_change_notify(fib_entry_index,
472  }
473  /*
474  * else
475  * still has sources, leave it be.
476  */
477  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
478  {
479  fib_table_source_count_dec(fib_table, source);
480  }
481 
482  fib_entry_unlock(fib_entry_index);
483  }
484 }
485 
486 /**
487  * fib_table_route_path_fixup
488  *
489  * Convert attached hosts to attached next-hops.
490  *
491  * This special case is required because an attached path will link to a
492  * glean, and the FIB entry will have the interface or API/CLI source. When
493  * the ARP/ND process is completes then that source (which will provide a
494  * complete adjacency) will be lower priority and so the FIB entry will
495  * remain linked to a glean and traffic will never reach the hosts. For
496  * an ATTAHCED_HOST path we can link the path directly to the [incomplete]
497  * adjacency.
498  */
499 static void
501  fib_entry_flag_t *eflags,
503 {
504  /*
505  * not all zeros next hop &&
506  * is recursive path &&
507  * nexthop is same as the route's address
508  */
509  if ((!ip46_address_is_zero(&path->frp_addr)) &&
510  (~0 == path->frp_sw_if_index) &&
511  (0 == ip46_address_cmp(&path->frp_addr, &prefix->fp_addr)))
512  {
513  /* Prefix recurses via itself */
515  }
516  if (!(path->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
517  fib_prefix_is_host(prefix) &&
518  ip46_address_is_zero(&path->frp_addr) &&
519  path->frp_sw_if_index != ~0 &&
520  path->frp_proto != DPO_PROTO_ETHERNET)
521  {
522  path->frp_addr = prefix->fp_addr;
524  }
525  else if ((*eflags & FIB_ENTRY_FLAG_CONNECTED) &&
526  !(*eflags & FIB_ENTRY_FLAG_LOCAL))
527  {
528  if (ip46_address_is_zero(&path->frp_addr))
529  {
531  fib_prefix_normalize(prefix, &path->frp_connected);
532  }
533  }
534  if (*eflags & FIB_ENTRY_FLAG_DROP)
535  {
537  }
538  if (*eflags & FIB_ENTRY_FLAG_LOCAL)
539  {
541  }
542  if (*eflags & FIB_ENTRY_FLAG_EXCLUSIVE)
543  {
545  }
546  if (path->frp_flags & FIB_ROUTE_PATH_LOCAL)
547  {
548  *eflags |= FIB_ENTRY_FLAG_LOCAL;
549 
550  if (path->frp_sw_if_index != ~0)
551  {
552  *eflags |= FIB_ENTRY_FLAG_CONNECTED;
553  }
554  }
555 }
556 
559  const fib_prefix_t *prefix,
560  fib_source_t source,
562  dpo_proto_t next_hop_proto,
563  const ip46_address_t *next_hop,
564  u32 next_hop_sw_if_index,
565  u32 next_hop_fib_index,
566  u32 next_hop_weight,
567  fib_mpls_label_t *next_hop_labels,
568  fib_route_path_flags_t path_flags)
569 {
571  .frp_proto = next_hop_proto,
572  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
573  .frp_sw_if_index = next_hop_sw_if_index,
574  .frp_fib_index = next_hop_fib_index,
575  .frp_weight = next_hop_weight,
576  .frp_flags = path_flags,
577  .frp_rpf_id = INDEX_INVALID,
578  .frp_label_stack = next_hop_labels,
579  };
580  fib_node_index_t fib_entry_index;
581  fib_route_path_t *paths = NULL;
582 
583  vec_add1(paths, path);
584 
585  fib_entry_index = fib_table_entry_path_add2(fib_index, prefix,
586  source, flags, paths);
587 
588  vec_free(paths);
589  return (fib_entry_index);
590 }
591 
592 static int
594  void * v2)
595 {
596  return (fib_route_path_cmp(v1, v2));
597 }
598 
601  const fib_prefix_t *prefix,
602  fib_source_t source,
604  fib_route_path_t *rpaths)
605 {
606  fib_node_index_t fib_entry_index;
607  fib_table_t *fib_table;
608  u32 ii;
609 
610  fib_table = fib_table_get(fib_index, prefix->fp_proto);
611  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
612 
613  for (ii = 0; ii < vec_len(rpaths); ii++)
614  {
615  fib_table_route_path_fixup(prefix, &flags, &rpaths[ii]);
616  }
617  /*
618  * sort the paths provided by the control plane. this means
619  * the paths and the extension on the entry will be sorted.
620  */
622 
623  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
624  {
625  fib_entry_index = fib_entry_create(fib_index, prefix,
626  source, flags,
627  rpaths);
628 
629  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
630  fib_table_source_count_inc(fib_table, source);
631  }
632  else
633  {
634  int was_sourced;
635 
636  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
637  fib_entry_path_add(fib_entry_index, source, flags, rpaths);;
638 
639  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
640  {
641  fib_table_source_count_inc(fib_table, source);
642  }
643  }
644 
645  return (fib_entry_index);
646 }
647 
648 void
650  const fib_prefix_t *prefix,
651  fib_source_t source,
652  fib_route_path_t *rpaths)
653 {
654  /*
655  * 1 is it present
656  * yes => remove source
657  * 2 - is it still sourced?
658  * no => cover walk
659  */
660  fib_node_index_t fib_entry_index;
661  fib_route_path_t *rpath;
662  fib_table_t *fib_table;
663 
664  fib_table = fib_table_get(fib_index, prefix->fp_proto);
665  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
666 
667  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
668  {
669  /*
670  * removing an etry that does not exist. i'll allow it.
671  */
672  }
673  else
674  {
675  fib_entry_src_flag_t src_flag;
676  int was_sourced;
677 
678  /*
679  * if it's not sourced, then there's nowt to remove
680  */
681  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
682  if (!was_sourced)
683  {
684  return;
685  }
686 
687  /*
688  * don't nobody go nowhere
689  */
690  fib_entry_lock(fib_entry_index);
691 
692  vec_foreach(rpath, rpaths)
693  {
694  fib_entry_flag_t eflags;
695 
696  eflags = fib_entry_get_flags_for_source(fib_entry_index,
697  source);
698  fib_table_route_path_fixup(prefix, &eflags, rpath);
699  }
700 
701  src_flag = fib_entry_path_remove(fib_entry_index, source, rpaths);
702 
703  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
704  {
705  /*
706  * last source gone. remove from the table
707  */
708  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
709 
710  /*
711  * now the entry is no longer in the table, we can
712  * inform the entries that it covers to re-calculate their cover
713  */
714  fib_entry_cover_change_notify(fib_entry_index,
716  }
717  /*
718  * else
719  * still has sources, leave it be.
720  */
721  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
722  {
723  fib_table_source_count_dec(fib_table, source);
724  }
725 
726  fib_entry_unlock(fib_entry_index);
727  }
728 }
729 
730 void
732  const fib_prefix_t *prefix,
733  fib_source_t source,
734  dpo_proto_t next_hop_proto,
735  const ip46_address_t *next_hop,
736  u32 next_hop_sw_if_index,
737  u32 next_hop_fib_index,
738  u32 next_hop_weight,
739  fib_route_path_flags_t path_flags)
740 {
741  /*
742  * 1 is it present
743  * yes => remove source
744  * 2 - is it still sourced?
745  * no => cover walk
746  */
748  .frp_proto = next_hop_proto,
749  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
750  .frp_sw_if_index = next_hop_sw_if_index,
751  .frp_fib_index = next_hop_fib_index,
752  .frp_weight = next_hop_weight,
753  .frp_flags = path_flags,
754  };
755  fib_route_path_t *paths = NULL;
756 
757  vec_add1(paths, path);
758 
759  fib_table_entry_path_remove2(fib_index, prefix, source, paths);
760 
761  vec_free(paths);
762 }
763 
766  const fib_prefix_t *prefix,
767  fib_source_t source,
770 {
771  fib_node_index_t fib_entry_index;
772  fib_table_t *fib_table;
773  u32 ii;
774 
775  fib_table = fib_table_get(fib_index, prefix->fp_proto);
776  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
777 
778  for (ii = 0; ii < vec_len(paths); ii++)
779  {
780  fib_table_route_path_fixup(prefix, &flags, &paths[ii]);
781  }
782  /*
783  * sort the paths provided by the control plane. this means
784  * the paths and the extension on the entry will be sorted.
785  */
787 
788  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
789  {
790  fib_entry_index = fib_entry_create(fib_index, prefix,
791  source, flags,
792  paths);
793 
794  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
795  fib_table_source_count_inc(fib_table, source);
796  }
797  else
798  {
799  int was_sourced;
800 
801  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
802  fib_entry_update(fib_entry_index, source, flags, paths);
803 
804  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
805  {
806  fib_table_source_count_inc(fib_table, source);
807  }
808  }
809 
810  return (fib_entry_index);
811 }
812 
815  const fib_prefix_t *prefix,
816  fib_source_t source,
818  dpo_proto_t next_hop_proto,
819  const ip46_address_t *next_hop,
820  u32 next_hop_sw_if_index,
821  u32 next_hop_fib_index,
822  u32 next_hop_weight,
823  fib_mpls_label_t *next_hop_labels,
824  fib_route_path_flags_t path_flags)
825 {
826  fib_node_index_t fib_entry_index;
828  .frp_proto = next_hop_proto,
829  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
830  .frp_sw_if_index = next_hop_sw_if_index,
831  .frp_fib_index = next_hop_fib_index,
832  .frp_weight = next_hop_weight,
833  .frp_flags = path_flags,
834  .frp_label_stack = next_hop_labels,
835  };
836  fib_route_path_t *paths = NULL;
837 
838  vec_add1(paths, path);
839 
840  fib_entry_index =
841  fib_table_entry_update(fib_index, prefix, source, flags, paths);
842 
843  vec_free(paths);
844 
845  return (fib_entry_index);
846 }
847 
848 static void
850  fib_node_index_t fib_entry_index,
851  const fib_prefix_t *prefix,
852  fib_source_t source)
853 {
854  fib_entry_src_flag_t src_flag;
855  fib_table_t *fib_table;
856  int was_sourced;
857 
858  fib_table = fib_table_get(fib_index, prefix->fp_proto);
859  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
860 
861  /*
862  * don't nobody go nowhere
863  */
864  fib_entry_lock(fib_entry_index);
865 
866  src_flag = fib_entry_delete(fib_entry_index, source);
867 
868  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
869  {
870  /*
871  * last source gone. remove from the table
872  */
873  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
874 
875  /*
876  * now the entry is no longer in the table, we can
877  * inform the entries that it covers to re-calculate their cover
878  */
879  fib_entry_cover_change_notify(fib_entry_index,
881  }
882  /*
883  * else
884  * still has sources, leave it be.
885  */
886  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
887  {
888  fib_table_source_count_dec(fib_table, source);
889  }
890 
891  fib_entry_unlock(fib_entry_index);
892 }
893 
894 void
896  const fib_prefix_t *prefix,
897  fib_source_t source)
898 {
899  fib_node_index_t fib_entry_index;
900 
901  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
902 
903  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
904  {
905  /*
906  * removing an etry that does not exist.
907  * i'll allow it, but i won't like it.
908  */
909  if (0)
910  clib_warning("%U not in FIB", format_fib_prefix, prefix);
911  }
912  else
913  {
914  fib_table_entry_delete_i(fib_index, fib_entry_index, prefix, source);
915  }
916 }
917 
918 void
920  fib_source_t source)
921 {
922  const fib_prefix_t *prefix;
923 
924  prefix = fib_entry_get_prefix(fib_entry_index);
925 
927  fib_entry_index, prefix, source);
928 }
929 
930 u32
932  const fib_prefix_t *prefix)
933 {
935  fib_table_lookup_exact_match(fib_index, prefix)));
936 }
937 
940  const fib_prefix_t *prefix,
942 {
943  fib_node_index_t fib_entry_index;
944 
945  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
946 
947  if (FIB_NODE_INDEX_INVALID == fib_entry_index ||
948  !fib_entry_is_sourced(fib_entry_index, FIB_SOURCE_MPLS))
949  {
950  /*
951  * only source the prefix once. this allows the label change
952  * operation to work
953  */
954  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix,
957  NULL);
958  }
959 
960  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &label);
961 
962  return (fib_entry_index);
963 }
964 
965 void
967  const fib_prefix_t *prefix,
969 {
970  fib_node_index_t fib_entry_index;
971  const void *data;
972  mpls_label_t pl;
973 
974  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
975 
976  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
977  return;
978 
979  data = fib_entry_get_source_data(fib_entry_index, FIB_SOURCE_MPLS);
980 
981  if (NULL == data)
982  return;
983 
984  pl = *(mpls_label_t*)data;
985 
986  if (pl != label)
987  return;
988 
989  pl = MPLS_LABEL_INVALID;
990 
991  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &pl);
993  prefix,
995 }
996 
997 u32
1000 {
1001  switch (proto)
1002  {
1003  case FIB_PROTOCOL_IP4:
1004  return (ip4_fib_table_get_index_for_sw_if_index(sw_if_index));
1005  case FIB_PROTOCOL_IP6:
1006  return (ip6_fib_table_get_index_for_sw_if_index(sw_if_index));
1007  case FIB_PROTOCOL_MPLS:
1008  return (mpls_fib_table_get_index_for_sw_if_index(sw_if_index));
1009  }
1010  return (~0);
1011 }
1012 
1016 {
1017  fib_table_t *fib;
1018 
1019  fib = fib_table_get(fib_index, proto);
1020 
1021  return (fib->ft_flow_hash_config);
1022 }
1023 
1026 {
1027  switch (proto)
1028  {
1029  case FIB_PROTOCOL_IP4:
1030  case FIB_PROTOCOL_IP6:
1031  return (IP_FLOW_HASH_DEFAULT);
1032 
1033  case FIB_PROTOCOL_MPLS:
1034  return (MPLS_FLOW_HASH_DEFAULT);
1035  }
1036 
1037  ASSERT(0);
1038  return (IP_FLOW_HASH_DEFAULT);
1039 }
1040 
1041 /**
1042  * @brief Table set flow hash config context.
1043  */
1045 {
1046  /**
1047  * the flow hash config to set
1048  */
1051 
1052 static fib_table_walk_rc_t
1054  void *arg)
1055 {
1057 
1058  fib_entry_set_flow_hash_config(fib_entry_index, ctx->hash_config);
1059 
1060  return (FIB_TABLE_WALK_CONTINUE);
1061 }
1062 
1063 void
1067 {
1069  .hash_config = hash_config,
1070  };
1071  fib_table_t *fib;
1072 
1073  fib = fib_table_get(fib_index, proto);
1075 
1076  fib_table_walk(fib_index, proto,
1078  &ctx);
1079 }
1080 
1081 u32
1083  u32 sw_if_index)
1084 {
1085  fib_table_t *fib_table;
1086 
1088  proto, sw_if_index),
1089  proto);
1090 
1091  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1092 }
1093 
1094 u32
1097 {
1098  fib_table_t *fib_table;
1099 
1100  fib_table = fib_table_get(fib_index, proto);
1101 
1102  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1103 }
1104 
1105 u32
1107  u32 table_id)
1108 {
1109  switch (proto)
1110  {
1111  case FIB_PROTOCOL_IP4:
1112  return (ip4_fib_index_from_table_id(table_id));
1113  case FIB_PROTOCOL_IP6:
1114  return (ip6_fib_index_from_table_id(table_id));
1115  case FIB_PROTOCOL_MPLS:
1116  return (mpls_fib_index_from_table_id(table_id));
1117  }
1118  return (~0);
1119 }
1120 
1121 static u32
1123  u32 table_id,
1124  fib_source_t src,
1125  const u8 *name)
1126 {
1127  fib_table_t *fib_table;
1128  fib_node_index_t fi;
1129 
1130  switch (proto)
1131  {
1132  case FIB_PROTOCOL_IP4:
1133  fi = ip4_fib_table_find_or_create_and_lock(table_id, src);
1134  break;
1135  case FIB_PROTOCOL_IP6:
1136  fi = ip6_fib_table_find_or_create_and_lock(table_id, src);
1137  break;
1138  case FIB_PROTOCOL_MPLS:
1139  fi = mpls_fib_table_find_or_create_and_lock(table_id, src);
1140  break;
1141  default:
1142  return (~0);
1143  }
1144 
1145  fib_table = fib_table_get(fi, proto);
1146 
1147  if (NULL == fib_table->ft_desc)
1148  {
1149  if (name && name[0])
1150  {
1151  fib_table->ft_desc = format(NULL, "%s", name);
1152  }
1153  else
1154  {
1155  fib_table->ft_desc = format(NULL, "%U-VRF:%d",
1156  format_fib_protocol, proto,
1157  table_id);
1158  }
1159  }
1160 
1161  return (fi);
1162 }
1163 
1164 u32
1166  u32 table_id,
1167  fib_source_t src)
1168 {
1169  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1170  src, NULL));
1171 }
1172 
1173 u32
1175  u32 table_id,
1176  fib_source_t src,
1177  const u8 *name)
1178 {
1179  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1180  src, name));
1181 }
1182 
1183 u32
1185  fib_source_t src,
1186  const char *const fmt,
1187  ...)
1188 {
1189  fib_table_t *fib_table;
1190  fib_node_index_t fi;
1191  va_list ap;
1192 
1193 
1194  switch (proto)
1195  {
1196  case FIB_PROTOCOL_IP4:
1198  break;
1199  case FIB_PROTOCOL_IP6:
1201  break;
1202  case FIB_PROTOCOL_MPLS:
1204  break;
1205  default:
1206  return (~0);
1207  }
1208 
1209  fib_table = fib_table_get(fi, proto);
1210 
1211  va_start(ap, fmt);
1212 
1213  fib_table->ft_desc = va_format(fib_table->ft_desc, fmt, &ap);
1214 
1215  va_end(ap);
1216  return (fi);
1217 }
1218 
1219 static void
1221 {
1222  vec_free(fib_table->ft_desc);
1223 
1224  switch (fib_table->ft_proto)
1225  {
1226  case FIB_PROTOCOL_IP4:
1227  ip4_fib_table_destroy(fib_table->ft_index);
1228  break;
1229  case FIB_PROTOCOL_IP6:
1230  ip6_fib_table_destroy(fib_table->ft_index);
1231  break;
1232  case FIB_PROTOCOL_MPLS:
1233  mpls_fib_table_destroy(fib_table->ft_index);
1234  break;
1235  }
1236 }
1237 
1238 void
1239 fib_table_walk (u32 fib_index,
1242  void *ctx)
1243 {
1244  switch (proto)
1245  {
1246  case FIB_PROTOCOL_IP4:
1247  ip4_fib_table_walk(ip4_fib_get(fib_index), fn, ctx);
1248  break;
1249  case FIB_PROTOCOL_IP6:
1250  ip6_fib_table_walk(fib_index, fn, ctx);
1251  break;
1252  case FIB_PROTOCOL_MPLS:
1253  mpls_fib_table_walk(mpls_fib_get(fib_index), fn, ctx);
1254  break;
1255  }
1256 }
1257 
1259 {
1261  void *data;
1264 
1265 static fib_table_walk_rc_t
1267  void *arg)
1268 {
1270 
1271  if (ctx->src == fib_entry_get_best_source(fei))
1272  {
1273  return (ctx->fn(fei, ctx->data));
1274  }
1275  return (FIB_TABLE_WALK_CONTINUE);
1276 }
1277 
1278 void
1281  fib_source_t src,
1283  void *data)
1284 {
1286  .fn = fn,
1287  .src = src,
1288  .data = data,
1289  };
1290 
1291  fib_table_walk(fib_index, proto, fib_table_walk_w_src_cb, &ctx);
1292 }
1293 
1294 void
1297  const fib_prefix_t *root,
1299  void *ctx)
1300 {
1301  switch (proto)
1302  {
1303  case FIB_PROTOCOL_IP4:
1304  ip4_fib_table_sub_tree_walk(ip4_fib_get(fib_index), root, fn, ctx);
1305  break;
1306  case FIB_PROTOCOL_IP6:
1307  ip6_fib_table_sub_tree_walk(fib_index, root, fn, ctx);
1308  break;
1309  case FIB_PROTOCOL_MPLS:
1310  break;
1311  }
1312 }
1313 
1314 static void
1316  fib_source_t source)
1317 {
1318  vec_validate(fib_table->ft_locks, source);
1319 
1320  fib_table->ft_locks[source]--;
1321  fib_table->ft_total_locks--;
1322 }
1323 
1324 static void
1326  fib_source_t source)
1327 {
1328  vec_validate(fib_table->ft_locks, source);
1329 
1330  ASSERT(fib_table->ft_total_locks < (0xffffffff - 1));
1331  fib_table->ft_locks[source]++;
1332  fib_table->ft_total_locks++;
1333 }
1334 
1335 void
1338  fib_source_t source)
1339 {
1340  fib_table_t *fib_table;
1341 
1342  fib_table = fib_table_get(fib_index, proto);
1343  fib_table_lock_dec(fib_table, source);
1344 
1345  if (0 == fib_table->ft_total_locks)
1346  {
1347  /*
1348  * no more locak from any source - kill it
1349  */
1350  fib_table_destroy(fib_table);
1351  }
1352 }
1353 
1354 void
1355 fib_table_lock (u32 fib_index,
1357  fib_source_t source)
1358 {
1359  fib_table_t *fib_table;
1360 
1361  fib_table = fib_table_get(fib_index, proto);
1362 
1363  fib_table_lock_inc(fib_table, source);
1364 }
1365 
1366 u32
1369  fib_source_t source)
1370 {
1371  fib_table_t *fib_table;
1372 
1373  fib_table = fib_table_get(fib_index, proto);
1374 
1375  return (fib_table->ft_src_route_counts[source]);
1376 }
1377 
1378 u8*
1379 format_fib_table_name (u8* s, va_list* ap)
1380 {
1381  fib_node_index_t fib_index = va_arg(*ap, fib_node_index_t);
1382  fib_protocol_t proto = va_arg(*ap, int); // int promotion
1383  fib_table_t *fib_table;
1384 
1385  fib_table = fib_table_get(fib_index, proto);
1386 
1387  s = format(s, "%v", fib_table->ft_desc);
1388 
1389  return (s);
1390 }
1391 
1392 u8*
1393 format_fib_table_flags (u8 *s, va_list *args)
1394 {
1395  fib_table_flags_t flags = va_arg(*args, int);
1396  fib_table_attribute_t attr;
1397 
1398  if (!flags)
1399  {
1400  return format(s, "none");
1401  }
1402 
1404  if (1 << attr & flags) {
1405  s = format(s, "%s", fib_table_flags_strings[attr]);
1406  }
1407  }
1408 
1409  return (s);
1410 }
1411 
1412 /**
1413  * @brief Table flush context. Store the indicies of matching FIB entries
1414  * that need to be removed.
1415  */
1417 {
1418  /**
1419  * The list of entries to flush
1420  */
1422 
1423  /**
1424  * The source we are flushing
1425  */
1428 
1429 static fib_table_walk_rc_t
1431  void *arg)
1432 {
1433  fib_table_flush_ctx_t *ctx = arg;
1434 
1435  if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
1436  {
1437  vec_add1(ctx->ftf_entries, fib_entry_index);
1438  }
1439  return (FIB_TABLE_WALK_CONTINUE);
1440 }
1441 
1442 void
1445  fib_source_t source)
1446 {
1447  fib_node_index_t *fib_entry_index;
1449  .ftf_entries = NULL,
1450  .ftf_source = source,
1451  };
1452 
1453  fib_table_walk(fib_index, proto,
1455  &ctx);
1456 
1457  vec_foreach(fib_entry_index, ctx.ftf_entries)
1458  {
1459  fib_table_entry_delete_index(*fib_entry_index, source);
1460  }
1461 
1462  vec_free(ctx.ftf_entries);
1463 }
1464 
1465 static fib_table_walk_rc_t
1467  void *arg)
1468 {
1469  fib_table_flush_ctx_t *ctx = arg;
1470 
1471  if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
1472  {
1473  fib_entry_mark(fib_entry_index, ctx->ftf_source);
1474  }
1475  return (FIB_TABLE_WALK_CONTINUE);
1476 }
1477 
1478 void
1479 fib_table_mark (u32 fib_index,
1481  fib_source_t source)
1482 {
1484  .ftf_source = source,
1485  };
1486  fib_table_t *fib_table;
1487 
1488  fib_table = fib_table_get(fib_index, proto);
1489 
1490  fib_table->ft_epoch++;
1491  fib_table->ft_flags |= FIB_TABLE_FLAG_RESYNC;
1492 
1493  fib_table_walk(fib_index, proto,
1495  &ctx);
1496 }
1497 
1498 static fib_table_walk_rc_t
1500  void *arg)
1501 {
1502  fib_table_flush_ctx_t *ctx = arg;
1503 
1504  if (fib_entry_is_marked(fib_entry_index, ctx->ftf_source))
1505  {
1506  vec_add1(ctx->ftf_entries, fib_entry_index);
1507  }
1508  return (FIB_TABLE_WALK_CONTINUE);
1509 }
1510 
1511 void
1514  fib_source_t source)
1515 {
1517  .ftf_source = source,
1518  };
1519  fib_node_index_t *fib_entry_index;
1520  fib_table_t *fib_table;
1521 
1522  fib_table = fib_table_get(fib_index, proto);
1523 
1524  fib_table->ft_flags &= ~FIB_TABLE_FLAG_RESYNC;
1525 
1526  fib_table_walk(fib_index, proto,
1528  &ctx);
1529 
1530  vec_foreach(fib_entry_index, ctx.ftf_entries)
1531  {
1532  fib_table_entry_delete_index(*fib_entry_index, source);
1533  }
1534 
1535  vec_free(ctx.ftf_entries);
1536 }
1537 
1538 u8 *
1539 format_fib_table_memory (u8 *s, va_list *args)
1540 {
1541  s = format(s, "%U", format_ip4_fib_table_memory);
1542  s = format(s, "%U", format_ip6_fib_table_memory);
1543  s = format(s, "%U", format_mpls_fib_table_memory);
1544 
1545  return (s);
1546 }
#define FIB_TABLE_ATTRIBUTES
Definition: fib_table.h:49
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:380
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
__clib_export u8 * va_format(u8 *s, const char *fmt, va_list *va)
Definition: format.c:391
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:211
enum fib_source_t_ fib_source_t
The different sources that can create a route.
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1738
fib_node_index_t fib_table_entry_path_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Add one path to an entry (aka route) in the FIB.
Definition: fib_table.c:558
void mpls_fib_table_entry_remove(mpls_fib_t *mf, mpls_label_t label, mpls_eos_bit_t eos)
Definition: mpls_fib.c:308
void fib_table_sweep(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Signal that the table has converged, i.e.
Definition: fib_table.c:1512
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:516
Continue on to the next entry.
Definition: fib_table.h:916
void fib_entry_unlock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1679
#define FOR_EACH_FIB_TABLE_ATTRIBUTE(_item)
Definition: fib_table.h:54
fib_protocol_t ft_proto
Which protocol this table serves.
Definition: fib_table.h:76
void ip4_fib_table_fwding_dpo_remove(ip4_fib_t *fib, const ip4_address_t *addr, u32 len, const dpo_id_t *dpo, u32 cover_index)
Definition: ip4_fib.c:384
fib_node_index_t fib_table_lookup_exact_match(u32 fib_index, const fib_prefix_t *prefix)
Perfom an exact match in the non-forwarding table.
Definition: fib_table.c:97
static void fib_table_lock_dec(fib_table_t *fib_table, fib_source_t source)
Definition: fib_table.c:1315
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
static const char * fib_table_flags_strings[]
Definition: fib_table.c:26
A representation of a path as described by a route producer.
Definition: fib_types.h:500
int fib_route_path_cmp(const fib_route_path_t *rpath1, const fib_route_path_t *rpath2)
Definition: fib_types.c:320
fib_node_index_t mpls_fib_table_lookup(const mpls_fib_t *mf, mpls_label_t label, mpls_eos_bit_t eos)
Definition: mpls_fib.c:284
fib_source_t ftf_source
The source we are flushing.
Definition: fib_table.c:1426
A Drop path - resolve the path on the drop DPO.
Definition: fib_types.h:352
void mpls_fib_table_destroy(u32 fib_index)
Definition: mpls_fib.c:244
void fib_entry_set_flow_hash_config(fib_node_index_t fib_entry_index, flow_hash_config_t hash_config)
Definition: fib_entry.c:1556
u32 fib_table_find_or_create_and_lock_w_name(fib_protocol_t proto, u32 table_id, fib_source_t src, const u8 *name)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1174
fib_node_index_t fib_table_entry_update(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, fib_route_path_t *paths)
Update an entry to have a new set of paths.
Definition: fib_table.c:765
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: fib_table.c:998
u8 * format_ip6_fib_table_memory(u8 *s, va_list *args)
Definition: ip6_fib.c:600
enum fib_table_flags_t_ fib_table_flags_t
fib_node_index_t fib_table_entry_path_add2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, fib_route_path_t *rpaths)
Add n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:600
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:264
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
void ip4_fib_table_destroy(u32 fib_index)
Definition: ip4_fib.c:156
vl_api_address_t src
Definition: gre.api:54
static fib_node_index_t fib_table_get_less_specific_i(fib_table_t *fib_table, const fib_prefix_t *prefix)
Definition: fib_table.c:106
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1728
string name[64]
Definition: fib.api:25
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:505
void fib_table_fwding_dpo_remove(u32 fib_index, const fib_prefix_t *prefix, const dpo_id_t *dpo)
remove an entry in the FIB&#39;s forwarding table
Definition: fib_table.c:280
vl_api_fib_path_t path
Definition: mfib_types.api:44
vl_api_prefix_t prefix
Definition: ip.api:146
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:26
u32 ip4_fib_table_find_or_create_and_lock(u32 table_id, fib_source_t src)
Get or create an IPv4 fib.
Definition: ip4_fib.c:206
void fib_table_entry_local_label_remove(u32 fib_index, const fib_prefix_t *prefix, mpls_label_t label)
remove a MPLS local label for the prefix/route.
Definition: fib_table.c:966
unsigned char u8
Definition: types.h:56
int fib_prefix_is_host(const fib_prefix_t *prefix)
Return true is the prefix is a host prefix.
Definition: fib_types.c:249
static void vlib_smp_unsafe_warning(void)
Definition: threads.h:214
u8 data[128]
Definition: ipsec_types.api:92
u8 * format_fib_protocol(u8 *s, va_list *ap)
Definition: fib_types.c:33
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
void mpls_fib_table_entry_insert(mpls_fib_t *mf, mpls_label_t label, mpls_eos_bit_t eos, fib_node_index_t lfei)
Definition: mpls_fib.c:299
flow_hash_config_t fib_table_get_flow_hash_config(u32 fib_index, fib_protocol_t proto)
Get the flow hash configured used by the table.
Definition: fib_table.c:1014
unsigned int u32
Definition: types.h:88
fib_node_index_t fib_table_entry_update_one_path(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
Definition: fib_table.c:814
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
u32 ip4_fib_table_create_and_lock(fib_source_t src)
Definition: ip4_fib.c:221
flow_hash_config_t fib_table_get_default_flow_hash_config(fib_protocol_t proto)
Get the flow hash configured used by the protocol.
Definition: fib_table.c:1025
fib_node_index_t ip6_fib_table_lookup_exact_match(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:229
static void fib_table_post_insert_actions(fib_table_t *fib_table, const fib_prefix_t *prefix, fib_node_index_t fib_entry_index)
Definition: fib_table.c:173
void fib_entry_special_update(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Definition: fib_entry.c:892
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:545
u32 ft_epoch
Epoch - number of resyncs performed.
Definition: fib_table.h:117
static fib_node_index_t fib_table_lookup_exact_match_i(const fib_table_t *fib_table, const fib_prefix_t *prefix)
Definition: fib_table.c:75
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a &#39;special&#39; entry from the FIB.
Definition: fib_table.c:424
static int ip46_address_cmp(const ip46_address_t *ip46_1, const ip46_address_t *ip46_2)
Definition: ip46_address.h:80
description fragment has unexpected format
Definition: map.api:433
int fib_entry_is_host(fib_node_index_t fib_entry_index)
Return !0 is the entry represents a host prefix.
Definition: fib_entry.c:1520
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:283
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
void fib_table_flush(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Flush all entries from a table for the source.
Definition: fib_table.c:1443
Aggregate type for a prefix.
Definition: fib_types.h:202
void ip4_fib_table_sub_tree_walk(ip4_fib_t *fib, const fib_prefix_t *root, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a sub-tree of the FIB table N.B: This is NOT safe to deletes. ...
Definition: ip4_fib.c:425
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1106
u16 fp_len
The mask length.
Definition: fib_types.h:206
void ip4_fib_table_entry_remove(ip4_fib_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib.c:349
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
Definition: fib_table.c:68
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_fib.c:353
u32 * ft_locks
per-source number of locks on the table
Definition: fib_table.h:86
Definition: fib_entry.h:112
static u32 mpls_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: mpls_fib.h:138
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
Definition: fib_entry.h:117
void fib_prefix_normalize(const fib_prefix_t *p, fib_prefix_t *out)
normalise a prefix (i.e.
Definition: fib_types.c:264
Definition: fib_entry.h:116
static void fib_table_entry_insert(fib_table_t *fib_table, const fib_prefix_t *prefix, fib_node_index_t fib_entry_index)
Definition: fib_table.c:218
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
static void fib_table_source_count_dec(fib_table_t *fib_table, fib_source_t source)
Definition: fib_table.c:316
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
enum flow_hash_config_t_ flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
static void fib_table_lock_inc(fib_table_t *fib_table, fib_source_t source)
Definition: fib_table.c:1325
int fib_entry_is_marked(fib_node_index_t fib_entry_index, fib_source_t source)
static fib_table_walk_rc_t fib_table_mark_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:1466
u32 mpls_fib_table_find_or_create_and_lock(u32 table_id, fib_source_t src)
Definition: mpls_fib.c:224
void ip6_fib_table_fwding_dpo_update(u32 fib_index, const ip6_address_t *addr, u32 len, const dpo_id_t *dpo)
Definition: ip6_fib.c:367
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:225
vl_api_ip_proto_t proto
Definition: acl_types.api:51
void mpls_fib_table_walk(mpls_fib_t *mpls_fib, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: mpls_fib.c:350
u8 * format_fib_table_flags(u8 *s, va_list *args)
Definition: fib_table.c:1393
static u8 ip46_address_is_zero(const ip46_address_t *ip46)
Definition: ip46_address.h:87
long ctx[MAX_CONNS]
Definition: main.c:144
static u32 ip6_fib_index_from_table_id(u32 table_id)
Definition: ip6_fib.h:220
void fib_table_walk_w_src(u32 fib_index, fib_protocol_t proto, fib_source_t src, fib_table_walk_fn_t fn, void *data)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: fib_table.c:1279
#define MPLS_FLOW_HASH_DEFAULT
There are no options for controlling the MPLS flow hash, but since it mostly entails using IP data to...
Definition: mpls_fib.h:40
void ip6_fib_table_fwding_dpo_remove(u32 fib_index, const ip6_address_t *addr, u32 len, const dpo_id_t *dpo)
Definition: ip6_fib.c:398
u32 ft_total_route_counts
Total route counters.
Definition: fib_table.h:112
Configuration for each label value in the output-stack.
Definition: fib_types.h:455
u32 fib_table_get_num_entries(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Return the number of entries in the FIB added by a given source.
Definition: fib_table.c:1367
fib_entry_src_flag_t fib_entry_delete(fib_node_index_t fib_entry_index, fib_source_t source)
fib_entry_delete
Definition: fib_entry.c:1216
ip6_main_t ip6_main
Definition: ip6_forward.c:2787
fib_node_index_t fib_entry_create_special(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Definition: fib_entry.c:757
u32 label
Definition: fib_types.api:25
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple + flowlabel without the "reverse" bit.
Definition: ip_flow_hash.h:22
static fib_table_walk_rc_t fib_table_walk_w_src_cb(fib_node_index_t fei, void *arg)
Definition: fib_table.c:1266
void ip4_fib_table_fwding_dpo_update(ip4_fib_t *fib, const ip4_address_t *addr, u32 len, const dpo_id_t *dpo)
Definition: ip4_fib.c:375
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:1336
void ip6_fib_table_walk(u32 fib_index, fib_table_walk_fn_t fn, void *arg)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: ip6_fib.c:505
int cJSON_bool fmt
Definition: cJSON.h:160
struct fib_table_t_ * fibs
A pool of all the MPLS FIBs.
Definition: mpls.h:47
u32 ip6_fib_table_find_or_create_and_lock(u32 table_id, fib_source_t src)
Get or create an IPv6 fib.
Definition: ip6_fib.c:102
void fib_entry_inherit(fib_node_index_t cover, fib_node_index_t covered)
fib_entry_inherit
Definition: fib_entry.c:1203
void ip6_fib_table_entry_remove(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:283
enum fib_table_attribute_t_ fib_table_attribute_t
Flags for the source data.
struct fib_table_set_flow_hash_config_ctx_t_ fib_table_set_flow_hash_config_ctx_t
Table set flow hash config context.
fib_node_index_t ip4_fib_table_lookup(const ip4_fib_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib.c:294
static void fib_table_entry_delete_i(u32 fib_index, fib_node_index_t fib_entry_index, const fib_prefix_t *prefix, fib_source_t source)
Definition: fib_table.c:849
fib_node_index_t fib_table_entry_special_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags)
Add a &#39;special&#39; entry to the FIB.
Definition: fib_table.c:405
void ip4_fib_table_entry_insert(ip4_fib_t *fib, const ip4_address_t *addr, u32 len, fib_node_index_t fib_entry_index)
Definition: ip4_fib.c:317
fib_node_index_t ft_index
Index into FIB vector.
Definition: fib_table.h:97
static fib_node_index_t fib_table_lookup_i(fib_table_t *fib_table, const fib_prefix_t *prefix)
Definition: fib_table.c:46
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
void fib_table_entry_path_remove2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_route_path_t *rpaths)
Remove n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:649
fib_node_index_t fib_table_entry_special_dpo_update(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Update a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the...
Definition: fib_table.c:363
void ip6_fib_table_destroy(u32 fib_index)
Definition: ip6_fib.c:127
fib_node_index_t fib_table_entry_local_label_add(u32 fib_index, const fib_prefix_t *prefix, mpls_label_t label)
Add a MPLS local label for the prefix/route.
Definition: fib_table.c:939
void fib_table_fwding_dpo_update(u32 fib_index, const fib_prefix_t *prefix, const dpo_id_t *dpo)
Add or update an entry in the FIB&#39;s forwarding table.
Definition: fib_table.c:253
mpls_main_t mpls_main
Definition: mpls.c:25
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:92
fib_table_walk_fn_t fn
Definition: fib_table.c:1260
void fib_table_entry_delete_index(fib_node_index_t fib_entry_index, fib_source_t source)
Delete a FIB entry.
Definition: fib_table.c:919
u32 ft_flow_hash_config
flow hash configuration
Definition: fib_table.h:102
static void fib_table_destroy(fib_table_t *fib_table)
Definition: fib_table.c:1220
enum fib_table_walk_rc_t_ fib_table_walk_rc_t
return code controlling how a table walk proceeds
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:48
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
Definition: fib_table.c:895
u32 ip6_fib_table_create_and_lock(fib_source_t src, fib_table_flags_t flags, u8 *desc)
Definition: ip6_fib.c:119
u32 index
Definition: flow_types.api:221
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:113
void fib_table_set_flow_hash_config(u32 fib_index, fib_protocol_t proto, flow_hash_config_t hash_config)
Set the flow hash configured used by the table.
Definition: fib_table.c:1064
u8 * ft_desc
Table description.
Definition: fib_table.h:122
fib_table_flags_t ft_flags
Table flags.
Definition: fib_table.h:81
static void fib_table_entry_remove(fib_table_t *fib_table, const fib_prefix_t *prefix, fib_node_index_t fib_entry_index)
Definition: fib_table.c:142
#define clib_warning(format, args...)
Definition: error.h:59
Definition: fib_entry.h:115
void fib_entry_cover_change_notify(fib_node_index_t cover_index, fib_node_index_t covered)
void fib_table_mark(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Resync all entries from a table for the source this is the mark part of the mark and sweep algorithm...
Definition: fib_table.c:1479
flow_hash_config_t hash_config
the flow hash config to set
Definition: fib_table.c:1049
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
u8 * format_fib_table_memory(u8 *s, va_list *args)
format (display) the memory used by the FIB tables
Definition: fib_table.c:1539
static int fib_route_path_cmp_for_sort(void *v1, void *v2)
Definition: fib_table.c:593
Don&#39;t resolve the path, use the DPO the client provides.
Definition: fib_types.h:356
static u32 ip4_fib_index_from_table_id(u32 table_id)
Definition: ip4_fib.h:145
u32 mpls_fib_index_from_table_id(u32 table_id)
Definition: mpls_fib.c:73
void ip4_fib_table_walk(ip4_fib_t *fib, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: ip4_fib.c:408
fib_table_walk_rc_t(* fib_table_walk_fn_t)(fib_node_index_t fei, void *ctx)
Call back function when walking entries in a FIB table.
Definition: fib_table.h:930
enum fib_entry_flag_t_ fib_entry_flag_t
void fib_entry_path_add(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *rpaths)
Definition: fib_entry.c:911
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:1355
mpls_label_t fp_label
Definition: fib_types.h:228
void fib_entry_lock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1669
A path that resolves via a glean adjacency.
Definition: fib_types.h:406
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
Definition: fib_table.c:324
u32 fib_table_get_table_id_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the Table-ID of the FIB bound to the interface.
Definition: fib_table.c:1082
#define ASSERT(truth)
const void * fib_entry_get_source_data(fib_node_index_t fib_entry_index, fib_source_t source)
void mpls_fib_forwarding_table_reset(mpls_fib_t *mf, mpls_label_t label, mpls_eos_bit_t eos)
Definition: mpls_fib.c:338
static mpls_fib_t * mpls_fib_get(fib_node_index_t index)
Definition: mpls_fib.h:63
void fib_table_walk(u32 fib_index, fib_protocol_t proto, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: fib_table.c:1239
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1095
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1165
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:609
Definition: fib_entry.h:178
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:343
void mpls_fib_forwarding_table_update(mpls_fib_t *mf, mpls_label_t label, mpls_eos_bit_t eos, const dpo_id_t *dpo)
Definition: mpls_fib.c:316
u8 * format_ip4_fib_table_memory(u8 *s, va_list *args)
Definition: ip4_fib.c:562
enum fib_entry_src_flag_t_ fib_entry_src_flag_t
void fib_table_entry_path_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_route_path_flags_t path_flags)
remove one path to an entry (aka route) in the FIB.
Definition: fib_table.c:731
u32 fib_table_entry_get_stats_index(u32 fib_index, const fib_prefix_t *prefix)
Return the stats index for a FIB entry.
Definition: fib_table.c:931
static void fib_table_route_path_fixup(const fib_prefix_t *prefix, fib_entry_flag_t *eflags, fib_route_path_t *path)
fib_table_route_path_fixup
Definition: fib_table.c:500
static u32 fib_table_find_or_create_and_lock_i(fib_protocol_t proto, u32 table_id, fib_source_t src, const u8 *name)
Definition: fib_table.c:1122
paths
Definition: map.api:460
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
fib_prefix_t frp_connected
Glean prefix on a glean path.
Definition: fib_types.h:538
u32 ft_total_locks
Definition: fib_table.h:87
fib_node_index_t fib_entry_create(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *paths)
Definition: fib_entry.c:717
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
A for-us/local path.
Definition: fib_types.h:344
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:49
Definition: fib_entry.h:113
fib_node_index_t * ftf_entries
The list of entries to flush.
Definition: fib_table.c:1421
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1098
void ip6_fib_table_entry_insert(u32 fib_index, const ip6_address_t *addr, u32 len, fib_node_index_t fib_entry_index)
Definition: ip6_fib.c:314
static fib_table_walk_rc_t fib_table_set_flow_hash_config_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:1053
u32 table_id
Definition: wireguard.api:102
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:204
u32 fib_entry_get_stats_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1585
struct fib_table_walk_w_src_ctx_t_ fib_table_walk_w_src_cxt_t
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:29
u32 * ft_src_route_counts
Per-source route counters.
Definition: fib_table.h:107
static fib_table_walk_rc_t fib_table_sweep_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:1499
void fib_entry_update(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const fib_route_path_t *paths)
fib_entry_update
Definition: fib_entry.c:1228
u8 * format_mpls_fib_table_memory(u8 *s, va_list *args)
Definition: mpls_fib.c:364
u8 * format_fib_table_name(u8 *s, va_list *ap)
Format the description/name of the table.
Definition: fib_table.c:1379
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1105
Table set flow hash config context.
Definition: fib_table.c:1044
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:112
void fib_entry_mark(fib_node_index_t fib_entry_index, fib_source_t source)
#define vec_foreach(var, vec)
Vector iterator.
fib_entry_src_flag_t fib_entry_path_remove(fib_node_index_t fib_entry_index, fib_source_t source, const fib_route_path_t *rpaths)
Definition: fib_entry.c:1007
MPLS label.
Definition: fib_source.h:111
fib_node_index_t ip6_fib_table_lookup(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:183
struct fib_table_flush_ctx_t_ fib_table_flush_ctx_t
Table flush context.
static void fib_table_source_count_inc(fib_table_t *fib_table, fib_source_t source)
Definition: fib_table.c:308
Attached path.
Definition: fib_types.h:348
Table flush context.
Definition: fib_table.c:1416
void fib_table_sub_tree_walk(u32 fib_index, fib_protocol_t proto, const fib_prefix_t *root, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a sub-tree FIB table.
Definition: fib_table.c:1295
u32 mpls_fib_table_create_and_lock(fib_source_t src)
Definition: mpls_fib.c:238
fib_source_t fib_entry_get_best_source(fib_node_index_t entry_index)
Definition: fib_entry.c:1505
fib_node_index_t ip4_fib_table_lookup_exact_match(const ip4_fib_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib.c:246
void ip6_fib_table_sub_tree_walk(u32 fib_index, const fib_prefix_t *root, fib_table_walk_fn_t fn, void *arg)
Walk all entries in a sub-tree of the FIB table N.B: This is NOT safe to deletes. ...
Definition: ip6_fib.c:528
u32 fib_table_create_and_lock(fib_protocol_t proto, fib_source_t src, const char *const fmt,...)
Create a new table with no table ID.
Definition: fib_table.c:1184
struct fib_table_t_ * fibs
Definition: ip6.h:115
void fib_entry_set_source_data(fib_node_index_t fib_entry_index, fib_source_t source, const void *data)
void fib_entry_special_add(fib_node_index_t fib_entry_index, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Definition: fib_entry.c:875
const ip46_address_t zero_addr
#include <vnet/feature/feature.h>
Definition: lookup.c:182
fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry.c:1099
static fib_table_walk_rc_t fib_table_flush_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:1430
A protocol Independent FIB table.
Definition: fib_table.h:71
fib_node_index_t fib_table_get_less_specific(u32 fib_index, const fib_prefix_t *prefix)
Get the less specific (covering) prefix.
Definition: fib_table.c:133
mpls_eos_bit_t fp_eos
Definition: fib_types.h:229