FD.io VPP  v19.08-27-gf4dcae4
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 
29 {
30  switch (proto)
31  {
32  case FIB_PROTOCOL_IP4:
33  return (pool_elt_at_index(ip4_main.fibs, index));
34  case FIB_PROTOCOL_IP6:
35  return (pool_elt_at_index(ip6_main.fibs, index));
36  case FIB_PROTOCOL_MPLS:
37  return (pool_elt_at_index(mpls_main.fibs, index));
38  }
39  ASSERT(0);
40  return (NULL);
41 }
42 
43 static inline fib_node_index_t
45  const fib_prefix_t *prefix)
46 {
47  switch (prefix->fp_proto)
48  {
49  case FIB_PROTOCOL_IP4:
50  return (ip4_fib_table_lookup(ip4_fib_get(fib_table->ft_index),
51  &prefix->fp_addr.ip4,
52  prefix->fp_len));
53  case FIB_PROTOCOL_IP6:
54  return (ip6_fib_table_lookup(fib_table->ft_index,
55  &prefix->fp_addr.ip6,
56  prefix->fp_len));
57  case FIB_PROTOCOL_MPLS:
58  return (mpls_fib_table_lookup(mpls_fib_get(fib_table->ft_index),
59  prefix->fp_label,
60  prefix->fp_eos));
61  }
62  return (FIB_NODE_INDEX_INVALID);
63 }
64 
66 fib_table_lookup (u32 fib_index,
67  const fib_prefix_t *prefix)
68 {
69  return (fib_table_lookup_i(fib_table_get(fib_index, prefix->fp_proto), prefix));
70 }
71 
72 static inline fib_node_index_t
74  const fib_prefix_t *prefix)
75 {
76  switch (prefix->fp_proto)
77  {
78  case FIB_PROTOCOL_IP4:
80  &prefix->fp_addr.ip4,
81  prefix->fp_len));
82  case FIB_PROTOCOL_IP6:
83  return (ip6_fib_table_lookup_exact_match(fib_table->ft_index,
84  &prefix->fp_addr.ip6,
85  prefix->fp_len));
86  case FIB_PROTOCOL_MPLS:
87  return (mpls_fib_table_lookup(mpls_fib_get(fib_table->ft_index),
88  prefix->fp_label,
89  prefix->fp_eos));
90  }
91  return (FIB_NODE_INDEX_INVALID);
92 }
93 
96  const fib_prefix_t *prefix)
97 {
99  prefix->fp_proto),
100  prefix));
101 }
102 
103 static fib_node_index_t
105  const fib_prefix_t *prefix)
106 {
107  fib_prefix_t pfx;
108 
109  pfx = *prefix;
110 
111  if (FIB_PROTOCOL_MPLS == pfx.fp_proto)
112  {
113  return (FIB_NODE_INDEX_INVALID);
114  }
115 
116  /*
117  * in the absence of a tree structure for the table that allows for an O(1)
118  * parent get, a cheeky way to find the cover is to LPM for the prefix with
119  * mask-1.
120  * there should always be a cover, though it may be the default route. the
121  * default route's cover is the default route.
122  */
123  if (pfx.fp_len != 0) {
124  pfx.fp_len -= 1;
125  }
126 
127  return (fib_table_lookup_i(fib_table, &pfx));
128 }
129 
132  const fib_prefix_t *prefix)
133 {
135  prefix->fp_proto),
136  prefix));
137 }
138 
139 static void
141  const fib_prefix_t *prefix,
142  fib_node_index_t fib_entry_index)
143 {
145 
146  fib_table->ft_total_route_counts--;
147 
148  switch (prefix->fp_proto)
149  {
150  case FIB_PROTOCOL_IP4:
152  &prefix->fp_addr.ip4,
153  prefix->fp_len);
154  break;
155  case FIB_PROTOCOL_IP6:
157  &prefix->fp_addr.ip6,
158  prefix->fp_len);
159  break;
160  case FIB_PROTOCOL_MPLS:
162  prefix->fp_label,
163  prefix->fp_eos);
164  break;
165  }
166 
167  fib_entry_unlock(fib_entry_index);
168 }
169 
170 static void
172  const fib_prefix_t *prefix,
173  fib_node_index_t fib_entry_index)
174 {
175  fib_node_index_t fib_entry_cover_index;
176 
177  /*
178  * no cover relationships in the MPLS FIB
179  */
180  if (FIB_PROTOCOL_MPLS == prefix->fp_proto)
181  return;
182 
183  /*
184  * find the covering entry
185  */
186  fib_entry_cover_index = fib_table_get_less_specific_i(fib_table, prefix);
187  /*
188  * the indicies are the same when the default route is first added
189  */
190  if (fib_entry_cover_index != fib_entry_index)
191  {
192  /*
193  * push any inherting sources from the cover onto the covered
194  */
195  fib_entry_inherit(fib_entry_cover_index,
196  fib_entry_index);
197 
198  /*
199  * inform the covering entry that a new more specific
200  * has been inserted beneath it.
201  * If the prefix that has been inserted is a host route
202  * then it is not possible that it will be the cover for any
203  * other entry, so we can elide the walk. This is particularly
204  * beneficial since there are often many host entries sharing the
205  * same cover (i.e. ADJ or RR sourced entries).
206  */
207  if (!fib_entry_is_host(fib_entry_index))
208  {
209  fib_entry_cover_change_notify(fib_entry_cover_index,
210  fib_entry_index);
211  }
212  }
213 }
214 
215 static void
217  const fib_prefix_t *prefix,
218  fib_node_index_t fib_entry_index)
219 {
221 
222  fib_entry_lock(fib_entry_index);
223  fib_table->ft_total_route_counts++;
224 
225  switch (prefix->fp_proto)
226  {
227  case FIB_PROTOCOL_IP4:
229  &prefix->fp_addr.ip4,
230  prefix->fp_len,
231  fib_entry_index);
232  break;
233  case FIB_PROTOCOL_IP6:
235  &prefix->fp_addr.ip6,
236  prefix->fp_len,
237  fib_entry_index);
238  break;
239  case FIB_PROTOCOL_MPLS:
241  prefix->fp_label,
242  prefix->fp_eos,
243  fib_entry_index);
244  break;
245  }
246 
247  fib_table_post_insert_actions(fib_table, prefix, fib_entry_index);
248 }
249 
250 void
252  const fib_prefix_t *prefix,
253  const dpo_id_t *dpo)
254 {
256 
257  switch (prefix->fp_proto)
258  {
259  case FIB_PROTOCOL_IP4:
260  return (ip4_fib_table_fwding_dpo_update(ip4_fib_get(fib_index),
261  &prefix->fp_addr.ip4,
262  prefix->fp_len,
263  dpo));
264  case FIB_PROTOCOL_IP6:
265  return (ip6_fib_table_fwding_dpo_update(fib_index,
266  &prefix->fp_addr.ip6,
267  prefix->fp_len,
268  dpo));
269  case FIB_PROTOCOL_MPLS:
271  prefix->fp_label,
272  prefix->fp_eos,
273  dpo));
274  }
275 }
276 
277 void
279  const fib_prefix_t *prefix,
280  const dpo_id_t *dpo)
281 {
283 
284  switch (prefix->fp_proto)
285  {
286  case FIB_PROTOCOL_IP4:
287  return (ip4_fib_table_fwding_dpo_remove(ip4_fib_get(fib_index),
288  &prefix->fp_addr.ip4,
289  prefix->fp_len,
290  dpo,
291  fib_table_get_less_specific(fib_index,
292  prefix)));
293  case FIB_PROTOCOL_IP6:
294  return (ip6_fib_table_fwding_dpo_remove(fib_index,
295  &prefix->fp_addr.ip6,
296  prefix->fp_len,
297  dpo));
298  case FIB_PROTOCOL_MPLS:
300  prefix->fp_label,
301  prefix->fp_eos));
302  }
303 }
304 
305 
308  const fib_prefix_t *prefix,
309  fib_source_t source,
311  const dpo_id_t *dpo)
312 {
313  fib_node_index_t fib_entry_index;
314  fib_table_t *fib_table;
315 
316  fib_table = fib_table_get(fib_index, prefix->fp_proto);
317  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
318 
319  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
320  {
321  fib_entry_index = fib_entry_create_special(fib_index, prefix,
322  source, flags,
323  dpo);
324 
325  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
326  fib_table->ft_src_route_counts[source]++;
327  }
328  else
329  {
330  int was_sourced;
331 
332  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
333  fib_entry_special_add(fib_entry_index, source, flags, dpo);
334 
335  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
336  {
337  fib_table->ft_src_route_counts[source]++;
338  }
339  }
340 
341 
342  return (fib_entry_index);
343 }
344 
347  const fib_prefix_t *prefix,
348  fib_source_t source,
350  const dpo_id_t *dpo)
351 {
352  fib_node_index_t fib_entry_index;
353  fib_table_t *fib_table;
354 
355  fib_table = fib_table_get(fib_index, prefix->fp_proto);
356  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
357 
358  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
359  {
360  fib_entry_index = fib_entry_create_special(fib_index, prefix,
361  source, flags,
362  dpo);
363 
364  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
365  fib_table->ft_src_route_counts[source]++;
366  }
367  else
368  {
369  int was_sourced;
370 
371  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
372 
373  if (was_sourced)
374  fib_entry_special_update(fib_entry_index, source, flags, dpo);
375  else
376  fib_entry_special_add(fib_entry_index, source, flags, dpo);
377 
378  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
379  {
380  fib_table->ft_src_route_counts[source]++;
381  }
382  }
383 
384  return (fib_entry_index);
385 }
386 
389  const fib_prefix_t *prefix,
390  fib_source_t source,
392 {
393  fib_node_index_t fib_entry_index;
394  dpo_id_t tmp_dpo = DPO_INVALID;
395 
396  dpo_copy(&tmp_dpo, drop_dpo_get(fib_proto_to_dpo(prefix->fp_proto)));
397 
398  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix, source,
399  flags, &tmp_dpo);
400 
401  dpo_unlock(&tmp_dpo);
402 
403  return (fib_entry_index);
404 }
405 
406 void
408  const fib_prefix_t *prefix,
409  fib_source_t source)
410 {
411  /*
412  * 1 is it present
413  * yes => remove source
414  * 2 - is it still sourced?
415  * no => cover walk
416  */
417  fib_node_index_t fib_entry_index;
418  fib_table_t *fib_table;
419 
420  fib_table = fib_table_get(fib_index, prefix->fp_proto);
421  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
422 
423  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
424  {
425  /*
426  * removing an etry that does not exist. i'll allow it.
427  */
428  }
429  else
430  {
431  fib_entry_src_flag_t src_flag;
432  int was_sourced;
433 
434  /*
435  * don't nobody go nowhere
436  */
437  fib_entry_lock(fib_entry_index);
438  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
439 
440  src_flag = fib_entry_special_remove(fib_entry_index, source);
441 
442  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
443  {
444  /*
445  * last source gone. remove from the table
446  */
447  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
448 
449  /*
450  * now the entry is no longer in the table, we can
451  * inform the entries that it covers to re-calculate their cover
452  */
453  fib_entry_cover_change_notify(fib_entry_index,
455  }
456  /*
457  * else
458  * still has sources, leave it be.
459  */
460  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
461  {
462  fib_table->ft_src_route_counts[source]--;
463  }
464 
465  fib_entry_unlock(fib_entry_index);
466  }
467 }
468 
469 /**
470  * fib_table_route_path_fixup
471  *
472  * Convert attached hosts to attached next-hops.
473  *
474  * This special case is required because an attached path will link to a
475  * glean, and the FIB entry will have the interface or API/CLI source. When
476  * the ARP/ND process is completes then that source (which will provide a
477  * complete adjacency) will be lower priority and so the FIB entry will
478  * remain linked to a glean and traffic will never reach the hosts. For
479  * an ATTAHCED_HOST path we can link the path directly to the [incomplete]
480  * adjacency.
481  */
482 static void
484  fib_entry_flag_t *eflags,
485  fib_route_path_t *path)
486 {
487  /*
488  * not all zeros next hop &&
489  * is recursive path &&
490  * nexthop is same as the route's address
491  */
492  if ((!ip46_address_is_zero(&path->frp_addr)) &&
493  (~0 == path->frp_sw_if_index) &&
494  (0 == ip46_address_cmp(&path->frp_addr, &prefix->fp_addr)))
495  {
496  /* Prefix recurses via itse;f */
498  }
499  if (!(path->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
500  fib_prefix_is_host(prefix) &&
501  ip46_address_is_zero(&path->frp_addr) &&
502  path->frp_sw_if_index != ~0 &&
503  path->frp_proto != DPO_PROTO_ETHERNET)
504  {
505  path->frp_addr = prefix->fp_addr;
507  }
508  if (*eflags & FIB_ENTRY_FLAG_DROP)
509  {
511  }
512  if (*eflags & FIB_ENTRY_FLAG_LOCAL)
513  {
515  }
516  if (*eflags & FIB_ENTRY_FLAG_EXCLUSIVE)
517  {
519  }
520  if (path->frp_flags & FIB_ROUTE_PATH_LOCAL)
521  {
522  *eflags |= FIB_ENTRY_FLAG_LOCAL;
523 
524  if (path->frp_sw_if_index != ~0)
525  {
526  *eflags |= FIB_ENTRY_FLAG_CONNECTED;
527  }
528  }
529 }
530 
533  const fib_prefix_t *prefix,
534  fib_source_t source,
536  dpo_proto_t next_hop_proto,
537  const ip46_address_t *next_hop,
538  u32 next_hop_sw_if_index,
539  u32 next_hop_fib_index,
540  u32 next_hop_weight,
541  fib_mpls_label_t *next_hop_labels,
542  fib_route_path_flags_t path_flags)
543 {
544  fib_route_path_t path = {
545  .frp_proto = next_hop_proto,
546  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
547  .frp_sw_if_index = next_hop_sw_if_index,
548  .frp_fib_index = next_hop_fib_index,
549  .frp_weight = next_hop_weight,
550  .frp_flags = path_flags,
551  .frp_rpf_id = INDEX_INVALID,
552  .frp_label_stack = next_hop_labels,
553  };
554  fib_node_index_t fib_entry_index;
556 
557  vec_add1(paths, path);
558 
559  fib_entry_index = fib_table_entry_path_add2(fib_index, prefix,
560  source, flags, paths);
561 
562  vec_free(paths);
563  return (fib_entry_index);
564 }
565 
568  const fib_prefix_t *prefix,
569  fib_source_t source,
571  fib_route_path_t *rpaths)
572 {
573  fib_node_index_t fib_entry_index;
574  fib_table_t *fib_table;
575  u32 ii;
576 
577  fib_table = fib_table_get(fib_index, prefix->fp_proto);
578  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
579 
580  for (ii = 0; ii < vec_len(rpaths); ii++)
581  {
582  fib_table_route_path_fixup(prefix, &flags, &rpaths[ii]);
583  }
584 
585  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
586  {
587  fib_entry_index = fib_entry_create(fib_index, prefix,
588  source, flags,
589  rpaths);
590 
591  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
592  fib_table->ft_src_route_counts[source]++;
593  }
594  else
595  {
596  int was_sourced;
597 
598  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
599  fib_entry_path_add(fib_entry_index, source, flags, rpaths);;
600 
601  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
602  {
603  fib_table->ft_src_route_counts[source]++;
604  }
605  }
606 
607  return (fib_entry_index);
608 }
609 
610 void
612  const fib_prefix_t *prefix,
613  fib_source_t source,
614  fib_route_path_t *rpaths)
615 {
616  /*
617  * 1 is it present
618  * yes => remove source
619  * 2 - is it still sourced?
620  * no => cover walk
621  */
622  fib_node_index_t fib_entry_index;
623  fib_route_path_t *rpath;
624  fib_table_t *fib_table;
625 
626  fib_table = fib_table_get(fib_index, prefix->fp_proto);
627  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
628 
629  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
630  {
631  /*
632  * removing an etry that does not exist. i'll allow it.
633  */
634  }
635  else
636  {
637  fib_entry_src_flag_t src_flag;
638  int was_sourced;
639 
640  /*
641  * if it's not sourced, then there's nowt to remove
642  */
643  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
644  if (!was_sourced)
645  {
646  return;
647  }
648 
649  /*
650  * don't nobody go nowhere
651  */
652  fib_entry_lock(fib_entry_index);
653 
654  vec_foreach(rpath, rpaths)
655  {
656  fib_entry_flag_t eflags;
657 
658  eflags = fib_entry_get_flags_for_source(fib_entry_index,
659  source);
660  fib_table_route_path_fixup(prefix, &eflags, rpath);
661  }
662 
663  src_flag = fib_entry_path_remove(fib_entry_index, source, rpaths);
664 
665  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
666  {
667  /*
668  * last source gone. remove from the table
669  */
670  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
671 
672  /*
673  * now the entry is no longer in the table, we can
674  * inform the entries that it covers to re-calculate their cover
675  */
676  fib_entry_cover_change_notify(fib_entry_index,
678  }
679  /*
680  * else
681  * still has sources, leave it be.
682  */
683  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
684  {
685  fib_table->ft_src_route_counts[source]--;
686  }
687 
688  fib_entry_unlock(fib_entry_index);
689  }
690 }
691 
692 void
694  const fib_prefix_t *prefix,
695  fib_source_t source,
696  dpo_proto_t next_hop_proto,
697  const ip46_address_t *next_hop,
698  u32 next_hop_sw_if_index,
699  u32 next_hop_fib_index,
700  u32 next_hop_weight,
701  fib_route_path_flags_t path_flags)
702 {
703  /*
704  * 1 is it present
705  * yes => remove source
706  * 2 - is it still sourced?
707  * no => cover walk
708  */
709  fib_route_path_t path = {
710  .frp_proto = next_hop_proto,
711  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
712  .frp_sw_if_index = next_hop_sw_if_index,
713  .frp_fib_index = next_hop_fib_index,
714  .frp_weight = next_hop_weight,
715  .frp_flags = path_flags,
716  };
718 
719  vec_add1(paths, path);
720 
721  fib_table_entry_path_remove2(fib_index, prefix, source, paths);
722 
723  vec_free(paths);
724 }
725 
726 static int
728  void * v2)
729 {
730  return (fib_route_path_cmp(v1, v2));
731 }
732 
735  const fib_prefix_t *prefix,
736  fib_source_t source,
739 {
740  fib_node_index_t fib_entry_index;
741  fib_table_t *fib_table;
742  u32 ii;
743 
744  fib_table = fib_table_get(fib_index, prefix->fp_proto);
745  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
746 
747  for (ii = 0; ii < vec_len(paths); ii++)
748  {
749  fib_table_route_path_fixup(prefix, &flags, &paths[ii]);
750  }
751  /*
752  * sort the paths provided by the control plane. this means
753  * the paths and the extension on the entry will be sorted.
754  */
756 
757  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
758  {
759  fib_entry_index = fib_entry_create(fib_index, prefix,
760  source, flags,
761  paths);
762 
763  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
764  fib_table->ft_src_route_counts[source]++;
765  }
766  else
767  {
768  int was_sourced;
769 
770  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
771  fib_entry_update(fib_entry_index, source, flags, paths);
772 
773  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
774  {
775  fib_table->ft_src_route_counts[source]++;
776  }
777  }
778 
779  return (fib_entry_index);
780 }
781 
784  const fib_prefix_t *prefix,
785  fib_source_t source,
787  dpo_proto_t next_hop_proto,
788  const ip46_address_t *next_hop,
789  u32 next_hop_sw_if_index,
790  u32 next_hop_fib_index,
791  u32 next_hop_weight,
792  fib_mpls_label_t *next_hop_labels,
793  fib_route_path_flags_t path_flags)
794 {
795  fib_node_index_t fib_entry_index;
796  fib_route_path_t path = {
797  .frp_proto = next_hop_proto,
798  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
799  .frp_sw_if_index = next_hop_sw_if_index,
800  .frp_fib_index = next_hop_fib_index,
801  .frp_weight = next_hop_weight,
802  .frp_flags = path_flags,
803  .frp_label_stack = next_hop_labels,
804  };
806 
807  vec_add1(paths, path);
808 
809  fib_entry_index =
810  fib_table_entry_update(fib_index, prefix, source, flags, paths);
811 
812  vec_free(paths);
813 
814  return (fib_entry_index);
815 }
816 
817 static void
819  fib_node_index_t fib_entry_index,
820  const fib_prefix_t *prefix,
821  fib_source_t source)
822 {
823  fib_entry_src_flag_t src_flag;
824  fib_table_t *fib_table;
825  int was_sourced;
826 
827  fib_table = fib_table_get(fib_index, prefix->fp_proto);
828  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
829 
830  /*
831  * don't nobody go nowhere
832  */
833  fib_entry_lock(fib_entry_index);
834 
835  src_flag = fib_entry_delete(fib_entry_index, source);
836 
837  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
838  {
839  /*
840  * last source gone. remove from the table
841  */
842  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
843 
844  /*
845  * now the entry is no longer in the table, we can
846  * inform the entries that it covers to re-calculate their cover
847  */
848  fib_entry_cover_change_notify(fib_entry_index,
850  }
851  /*
852  * else
853  * still has sources, leave it be.
854  */
855  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
856  {
857  fib_table->ft_src_route_counts[source]--;
858  }
859 
860  fib_entry_unlock(fib_entry_index);
861 }
862 
863 void
865  const fib_prefix_t *prefix,
866  fib_source_t source)
867 {
868  fib_node_index_t fib_entry_index;
869 
870  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
871 
872  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
873  {
874  /*
875  * removing an etry that does not exist.
876  * i'll allow it, but i won't like it.
877  */
878  if (0)
879  clib_warning("%U not in FIB", format_fib_prefix, prefix);
880  }
881  else
882  {
883  fib_table_entry_delete_i(fib_index, fib_entry_index, prefix, source);
884  }
885 }
886 
887 void
889  fib_source_t source)
890 {
891  const fib_prefix_t *prefix;
892 
893  prefix = fib_entry_get_prefix(fib_entry_index);
894 
896  fib_entry_index, prefix, source);
897 }
898 
899 u32
901  const fib_prefix_t *prefix)
902 {
904  fib_table_lookup_exact_match(fib_index, prefix)));
905 }
906 
909  const fib_prefix_t *prefix,
911 {
912  fib_node_index_t fib_entry_index;
913 
914  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
915 
916  if (FIB_NODE_INDEX_INVALID == fib_entry_index ||
917  !fib_entry_is_sourced(fib_entry_index, FIB_SOURCE_MPLS))
918  {
919  /*
920  * only source the prefix once. this allows the label change
921  * operation to work
922  */
923  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix,
926  NULL);
927  }
928 
929  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &label);
930 
931  return (fib_entry_index);
932 }
933 
934 void
936  const fib_prefix_t *prefix,
938 {
939  fib_node_index_t fib_entry_index;
940  const void *data;
941  mpls_label_t pl;
942 
943  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
944 
945  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
946  return;
947 
948  data = fib_entry_get_source_data(fib_entry_index, FIB_SOURCE_MPLS);
949 
950  if (NULL == data)
951  return;
952 
953  pl = *(mpls_label_t*)data;
954 
955  if (pl != label)
956  return;
957 
958  pl = MPLS_LABEL_INVALID;
959 
960  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &pl);
962  prefix,
964 }
965 
966 u32
969 {
970  switch (proto)
971  {
972  case FIB_PROTOCOL_IP4:
973  return (ip4_fib_table_get_index_for_sw_if_index(sw_if_index));
974  case FIB_PROTOCOL_IP6:
975  return (ip6_fib_table_get_index_for_sw_if_index(sw_if_index));
976  case FIB_PROTOCOL_MPLS:
977  return (mpls_fib_table_get_index_for_sw_if_index(sw_if_index));
978  }
979  return (~0);
980 }
981 
985 {
986  fib_table_t *fib;
987 
988  fib = fib_table_get(fib_index, proto);
989 
990  return (fib->ft_flow_hash_config);
991 }
992 
995 {
996  switch (proto)
997  {
998  case FIB_PROTOCOL_IP4:
999  case FIB_PROTOCOL_IP6:
1000  return (IP_FLOW_HASH_DEFAULT);
1001 
1002  case FIB_PROTOCOL_MPLS:
1003  return (MPLS_FLOW_HASH_DEFAULT);
1004  }
1005 
1006  ASSERT(0);
1007  return (IP_FLOW_HASH_DEFAULT);
1008 }
1009 
1010 /**
1011  * @brief Table set flow hash config context.
1012  */
1014 {
1015  /**
1016  * the flow hash config to set
1017  */
1020 
1021 static fib_table_walk_rc_t
1023  void *arg)
1024 {
1026 
1027  fib_entry_set_flow_hash_config(fib_entry_index, ctx->hash_config);
1028 
1029  return (FIB_TABLE_WALK_CONTINUE);
1030 }
1031 
1032 void
1036 {
1038  .hash_config = hash_config,
1039  };
1040  fib_table_t *fib;
1041 
1042  fib = fib_table_get(fib_index, proto);
1044 
1045  fib_table_walk(fib_index, proto,
1047  &ctx);
1048 }
1049 
1050 u32
1052  u32 sw_if_index)
1053 {
1054  fib_table_t *fib_table;
1055 
1057  proto, sw_if_index),
1058  proto);
1059 
1060  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1061 }
1062 
1063 u32
1066 {
1067  fib_table_t *fib_table;
1068 
1069  fib_table = fib_table_get(fib_index, proto);
1070 
1071  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1072 }
1073 
1074 u32
1076  u32 table_id)
1077 {
1078  switch (proto)
1079  {
1080  case FIB_PROTOCOL_IP4:
1081  return (ip4_fib_index_from_table_id(table_id));
1082  case FIB_PROTOCOL_IP6:
1083  return (ip6_fib_index_from_table_id(table_id));
1084  case FIB_PROTOCOL_MPLS:
1085  return (mpls_fib_index_from_table_id(table_id));
1086  }
1087  return (~0);
1088 }
1089 
1090 static u32
1092  u32 table_id,
1093  fib_source_t src,
1094  const u8 *name)
1095 {
1096  fib_table_t *fib_table;
1097  fib_node_index_t fi;
1098 
1099  switch (proto)
1100  {
1101  case FIB_PROTOCOL_IP4:
1102  fi = ip4_fib_table_find_or_create_and_lock(table_id, src);
1103  break;
1104  case FIB_PROTOCOL_IP6:
1105  fi = ip6_fib_table_find_or_create_and_lock(table_id, src);
1106  break;
1107  case FIB_PROTOCOL_MPLS:
1108  fi = mpls_fib_table_find_or_create_and_lock(table_id, src);
1109  break;
1110  default:
1111  return (~0);
1112  }
1113 
1114  fib_table = fib_table_get(fi, proto);
1115 
1116  if (NULL == fib_table->ft_desc)
1117  {
1118  if (name && name[0])
1119  {
1120  fib_table->ft_desc = format(NULL, "%s", name);
1121  }
1122  else
1123  {
1124  fib_table->ft_desc = format(NULL, "%U-VRF:%d",
1125  format_fib_protocol, proto,
1126  table_id);
1127  }
1128  }
1129 
1130  return (fi);
1131 }
1132 
1133 u32
1135  u32 table_id,
1136  fib_source_t src)
1137 {
1138  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1139  src, NULL));
1140 }
1141 
1142 u32
1144  u32 table_id,
1145  fib_source_t src,
1146  const u8 *name)
1147 {
1148  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1149  src, name));
1150 }
1151 
1152 u32
1154  fib_source_t src,
1155  const char *const fmt,
1156  ...)
1157 {
1158  fib_table_t *fib_table;
1159  fib_node_index_t fi;
1160  va_list ap;
1161 
1162 
1163  switch (proto)
1164  {
1165  case FIB_PROTOCOL_IP4:
1167  break;
1168  case FIB_PROTOCOL_IP6:
1170  break;
1171  case FIB_PROTOCOL_MPLS:
1173  break;
1174  default:
1175  return (~0);
1176  }
1177 
1178  fib_table = fib_table_get(fi, proto);
1179 
1180  va_start(ap, fmt);
1181 
1182  fib_table->ft_desc = va_format(fib_table->ft_desc, fmt, &ap);
1183 
1184  va_end(ap);
1185  return (fi);
1186 }
1187 
1188 static void
1190 {
1191  vec_free(fib_table->ft_desc);
1192 
1193  switch (fib_table->ft_proto)
1194  {
1195  case FIB_PROTOCOL_IP4:
1196  ip4_fib_table_destroy(fib_table->ft_index);
1197  break;
1198  case FIB_PROTOCOL_IP6:
1199  ip6_fib_table_destroy(fib_table->ft_index);
1200  break;
1201  case FIB_PROTOCOL_MPLS:
1202  mpls_fib_table_destroy(fib_table->ft_index);
1203  break;
1204  }
1205 }
1206 
1207 void
1208 fib_table_walk (u32 fib_index,
1211  void *ctx)
1212 {
1213  switch (proto)
1214  {
1215  case FIB_PROTOCOL_IP4:
1216  ip4_fib_table_walk(ip4_fib_get(fib_index), fn, ctx);
1217  break;
1218  case FIB_PROTOCOL_IP6:
1219  ip6_fib_table_walk(fib_index, fn, ctx);
1220  break;
1221  case FIB_PROTOCOL_MPLS:
1222  mpls_fib_table_walk(mpls_fib_get(fib_index), fn, ctx);
1223  break;
1224  }
1225 }
1226 
1227 void
1230  const fib_prefix_t *root,
1232  void *ctx)
1233 {
1234  switch (proto)
1235  {
1236  case FIB_PROTOCOL_IP4:
1237  ip4_fib_table_sub_tree_walk(ip4_fib_get(fib_index), root, fn, ctx);
1238  break;
1239  case FIB_PROTOCOL_IP6:
1240  ip6_fib_table_sub_tree_walk(fib_index, root, fn, ctx);
1241  break;
1242  case FIB_PROTOCOL_MPLS:
1243  break;
1244  }
1245 }
1246 
1247 void
1250  fib_source_t source)
1251 {
1252  fib_table_t *fib_table;
1253 
1254  fib_table = fib_table_get(fib_index, proto);
1255  fib_table->ft_locks[source]--;
1256  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]--;
1257 
1258  if (0 == fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS])
1259  {
1260  /*
1261  * no more locak from any source - kill it
1262  */
1263  fib_table_destroy(fib_table);
1264  }
1265 }
1266 
1267 void
1268 fib_table_lock (u32 fib_index,
1270  fib_source_t source)
1271 {
1272  fib_table_t *fib_table;
1273 
1274  fib_table = fib_table_get(fib_index, proto);
1275 
1276  ASSERT(fib_table->ft_locks[source] < (0xffff - 1));
1277 
1278  fib_table->ft_locks[source]++;
1279  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]++;
1280 }
1281 
1282 u32
1285  fib_source_t source)
1286 {
1287  fib_table_t *fib_table;
1288 
1289  fib_table = fib_table_get(fib_index, proto);
1290 
1291  return (fib_table->ft_src_route_counts[source]);
1292 }
1293 
1294 u8*
1295 format_fib_table_name (u8* s, va_list* ap)
1296 {
1297  fib_node_index_t fib_index = va_arg(*ap, fib_node_index_t);
1298  fib_protocol_t proto = va_arg(*ap, int); // int promotion
1299  fib_table_t *fib_table;
1300 
1301  fib_table = fib_table_get(fib_index, proto);
1302 
1303  s = format(s, "%v", fib_table->ft_desc);
1304 
1305  return (s);
1306 }
1307 
1308 /**
1309  * @brief Table flush context. Store the indicies of matching FIB entries
1310  * that need to be removed.
1311  */
1313 {
1314  /**
1315  * The list of entries to flush
1316  */
1318 
1319  /**
1320  * The source we are flushing
1321  */
1324 
1325 static fib_table_walk_rc_t
1327  void *arg)
1328 {
1329  fib_table_flush_ctx_t *ctx = arg;
1330 
1331  if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
1332  {
1333  vec_add1(ctx->ftf_entries, fib_entry_index);
1334  }
1335  return (FIB_TABLE_WALK_CONTINUE);
1336 }
1337 
1338 
1339 void
1342  fib_source_t source)
1343 {
1344  fib_node_index_t *fib_entry_index;
1346  .ftf_entries = NULL,
1347  .ftf_source = source,
1348  };
1349 
1350  fib_table_walk(fib_index, proto,
1352  &ctx);
1353 
1354  vec_foreach(fib_entry_index, ctx.ftf_entries)
1355  {
1356  fib_table_entry_delete_index(*fib_entry_index, source);
1357  }
1358 
1359  vec_free(ctx.ftf_entries);
1360 }
1361 
1362 u8 *
1363 format_fib_table_memory (u8 *s, va_list *args)
1364 {
1365  s = format(s, "%U", format_ip4_fib_table_memory);
1366  s = format(s, "%U", format_ip6_fib_table_memory);
1367  s = format(s, "%U", format_mpls_fib_table_memory);
1368 
1369  return (s);
1370 }
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:373
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1691
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:532
void mpls_fib_table_entry_remove(mpls_fib_t *mf, mpls_label_t label, mpls_eos_bit_t eos)
Definition: mpls_fib.c:307
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:495
Continue on to the next entry.
Definition: fib_table.h:868
void fib_entry_unlock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1632
u32 flags
Definition: vhost_user.h:141
fib_protocol_t ft_proto
Which protocol this table serves.
Definition: fib_table.h:74
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:388
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:95
A representation of a path as described by a route producer.
Definition: fib_types.h:479
int fib_route_path_cmp(const fib_route_path_t *rpath1, const fib_route_path_t *rpath2)
Definition: fib_types.c:214
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:283
fib_source_t ftf_source
The source we are flushing.
Definition: fib_table.c:1322
A Drop path - resolve the path on the drop DPO.
Definition: fib_types.h:340
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:1509
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:1143
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:734
#define NULL
Definition: clib.h:58
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:967
u8 * format_ip6_fib_table_memory(u8 *s, va_list *args)
Definition: ip6_fib.c:572
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:26
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:567
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:262
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
void ip4_fib_table_destroy(u32 fib_index)
Definition: ip4_fib.c:159
vl_api_address_t src
Definition: gre.api:51
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:104
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1681
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
u8 * va_format(u8 *s, const char *fmt, va_list *va)
Definition: format.c:387
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:484
u8 data[128]
Definition: ipsec.api:249
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:278
vl_api_mprefix_t prefix
Definition: ip.api:456
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:203
#define ip46_address_cmp(ip46_1, ip46_2)
Definition: ip6_packet.h:92
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:935
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:162
static void vlib_smp_unsafe_warning(void)
Definition: threads.h:219
u8 * format_fib_protocol(u8 *s, va_list *ap)
Definition: fib_types.c:32
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:298
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:983
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:783
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:218
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:994
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip4_fib.c:224
fib_node_index_t ip6_fib_table_lookup_exact_match(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:218
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:171
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:888
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:519
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
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:73
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:407
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:1473
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:177
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:1340
Aggregrate type for a prefix.
Definition: fib_types.h:203
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:429
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
unsigned int u32
Definition: types.h:88
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:1075
u16 fp_len
The mask length.
Definition: fib_types.h:207
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:66
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_fib.c:326
Definition: fib_entry.h:281
static u32 mpls_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: mpls_fib.h:137
MPLS label.
Definition: fib_entry.h:119
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
Definition: fib_entry.h:286
Definition: fib_entry.h:285
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:216
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
enum fib_source_t_ fib_source_t
The different sources that can create a route.
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:340
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
u16 ft_locks[FIB_TABLE_N_LOCKS]
per-source number of locks on the table
Definition: fib_table.h:84
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:349
long ctx[MAX_CONNS]
Definition: main.c:144
static u32 ip6_fib_index_from_table_id(u32 table_id)
Definition: ip6_fib.h:173
#define MPLS_FLOW_HASH_DEFAULT
There are no options for controlling the MPLS flow hash.
Definition: mpls_fib.h:39
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:370
u32 ft_total_route_counts
Total route counters.
Definition: fib_table.h:109
Configuration for each label value in the output-stack.
Definition: fib_types.h:434
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:1283
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:1210
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:755
u32 label
Definition: fib_types.api:25
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:379
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:1248
u8 name[64]
Definition: memclnt.api:152
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:477
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:96
void fib_entry_inherit(fib_node_index_t cover, fib_node_index_t covered)
fib_entry_inherit
Definition: fib_entry.c:1197
void ip6_fib_table_entry_remove(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:257
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:291
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:818
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:388
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:314
fib_node_index_t ft_index
Index into FIB vector.
Definition: fib_table.h:94
static fib_node_index_t fib_table_lookup_i(fib_table_t *fib_table, const fib_prefix_t *prefix)
Definition: fib_table.c:44
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:611
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:346
void ip6_fib_table_destroy(u32 fib_index)
Definition: ip6_fib.c:121
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:908
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:251
mpls_main_t mpls_main
Definition: mpls.c:25
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
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:888
u32 ft_flow_hash_config
flow hash configuration
Definition: fib_table.h:99
static void fib_table_destroy(fib_table_t *fib_table)
Definition: fib_table.c:1189
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:341
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:864
u32 ip6_fib_table_create_and_lock(fib_source_t src, fib_table_flags_t flags, u8 *desc)
Definition: ip6_fib.c:113
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:1033
u8 * ft_desc
Table description.
Definition: fib_table.h:114
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:140
#define clib_warning(format, args...)
Definition: error.h:59
Definition: fib_entry.h:284
void fib_entry_cover_change_notify(fib_node_index_t cover_index, fib_node_index_t covered)
flow_hash_config_t hash_config
the flow hash config to set
Definition: fib_table.c:1018
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
u8 * format_fib_table_memory(u8 *s, va_list *args)
format (display) the memory used by the FIB tables
Definition: fib_table.c:1363
static int fib_route_path_cmp_for_sort(void *v1, void *v2)
Definition: fib_table.c:727
Don&#39;t resolve the path, use the DPO the client provides.
Definition: fib_types.h:344
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:412
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:882
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:907
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:1268
mpls_label_t fp_label
Definition: fib_types.h:229
void fib_entry_lock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1622
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:307
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:1051
#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:337
static mpls_fib_t * mpls_fib_get(fib_node_index_t index)
Definition: mpls_fib.h:62
ip6_main_t ip6_main
Definition: ip6_forward.c:2671
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:1208
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:1064
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:1134
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:589
Definition: fib_entry.h:342
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:237
u32 ft_src_route_counts[FIB_SOURCE_MAX]
Per-source route counters.
Definition: fib_table.h:104
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
Definition: lookup.h:70
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:315
u8 * format_ip4_fib_table_memory(u8 *s, va_list *args)
Definition: ip4_fib.c:566
enum fib_entry_src_flag_t_ fib_entry_src_flag_t
#define FIB_TABLE_TOTAL_LOCKS
Definition: fib_table.h:29
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:693
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:84
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:900
vl_api_mfib_path_t paths[n_paths]
Definition: ip.api:458
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:483
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:1091
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
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:716
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
A for-us/local path.
Definition: fib_types.h:332
#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:47
Definition: fib_entry.h:282
fib_node_index_t * ftf_entries
The list of entries to flush.
Definition: fib_table.c:1317
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:980
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:288
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:1022
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
u32 fib_entry_get_stats_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1538
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:27
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:1222
u8 * format_mpls_fib_table_memory(u8 *s, va_list *args)
Definition: mpls_fib.c:363
u8 * format_fib_table_name(u8 *s, va_list *ap)
Format the description/name of the table.
Definition: fib_table.c:1295
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:921
Table set flow hash config context.
Definition: fib_table.c:1013
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:110
#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:1003
fib_node_index_t ip6_fib_table_lookup(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:172
struct fib_table_flush_ctx_t_ fib_table_flush_ctx_t
Table flush context.
Attached path.
Definition: fib_types.h:336
Table flush context.
Definition: fib_table.c:1312
u32 table_id
Definition: fib_types.api:118
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:1228
u32 mpls_fib_table_create_and_lock(fib_source_t src)
Definition: mpls_fib.c:238
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:243
#define ip46_address_is_zero(ip46)
Definition: ip6_packet.h:93
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:500
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:1153
struct fib_table_t_ * fibs
Definition: ip6.h:182
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:871
const ip46_address_t zero_addr
Definition: lookup.c:319
fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry.c:1095
static fib_table_walk_rc_t fib_table_flush_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:1326
vl_api_fib_path_nh_proto_t proto
Definition: fib_types.api:125
A protocol Independent FIB table.
Definition: fib_table.h:69
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:131
mpls_eos_bit_t fp_eos
Definition: fib_types.h:230