FD.io VPP  v18.10-34-gcce845e
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 
28  fib_protocol_t proto)
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 (fib_prefix_is_host(prefix) &&
500  ip46_address_is_zero(&path->frp_addr) &&
501  path->frp_sw_if_index != ~0 &&
502  path->frp_proto != DPO_PROTO_ETHERNET)
503  {
504  path->frp_addr = prefix->fp_addr;
506  }
507  if (eflags & FIB_ENTRY_FLAG_DROP)
508  {
510  }
511  if (eflags & FIB_ENTRY_FLAG_LOCAL)
512  {
514  }
515  if (eflags & FIB_ENTRY_FLAG_EXCLUSIVE)
516  {
518  }
519 }
520 
523  const fib_prefix_t *prefix,
524  fib_source_t source,
526  dpo_proto_t next_hop_proto,
527  const ip46_address_t *next_hop,
528  u32 next_hop_sw_if_index,
529  u32 next_hop_fib_index,
530  u32 next_hop_weight,
531  fib_mpls_label_t *next_hop_labels,
532  fib_route_path_flags_t path_flags)
533 {
534  fib_route_path_t path = {
535  .frp_proto = next_hop_proto,
536  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
537  .frp_sw_if_index = next_hop_sw_if_index,
538  .frp_fib_index = next_hop_fib_index,
539  .frp_weight = next_hop_weight,
540  .frp_flags = path_flags,
541  .frp_label_stack = next_hop_labels,
542  };
543  fib_node_index_t fib_entry_index;
544  fib_route_path_t *paths = NULL;
545 
546  vec_add1(paths, path);
547 
548  fib_entry_index = fib_table_entry_path_add2(fib_index, prefix,
549  source, flags, paths);
550 
551  vec_free(paths);
552  return (fib_entry_index);
553 }
554 
557  const fib_prefix_t *prefix,
558  fib_source_t source,
560  fib_route_path_t *rpath)
561 {
562  fib_node_index_t fib_entry_index;
563  fib_table_t *fib_table;
564  u32 ii;
565 
566  fib_table = fib_table_get(fib_index, prefix->fp_proto);
567  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
568 
569  for (ii = 0; ii < vec_len(rpath); ii++)
570  {
571  fib_table_route_path_fixup(prefix, flags, &rpath[ii]);
572  }
573 
574  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
575  {
576  fib_entry_index = fib_entry_create(fib_index, prefix,
577  source, flags,
578  rpath);
579 
580  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
581  fib_table->ft_src_route_counts[source]++;
582  }
583  else
584  {
585  int was_sourced;
586 
587  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
588  fib_entry_path_add(fib_entry_index, source, flags, rpath);;
589 
590  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
591  {
592  fib_table->ft_src_route_counts[source]++;
593  }
594  }
595 
596  return (fib_entry_index);
597 }
598 
599 void
601  const fib_prefix_t *prefix,
602  fib_source_t source,
603  fib_route_path_t *rpath)
604 {
605  /*
606  * 1 is it present
607  * yes => remove source
608  * 2 - is it still sourced?
609  * no => cover walk
610  */
611  fib_node_index_t fib_entry_index;
612  fib_table_t *fib_table;
613  u32 ii;
614 
615  fib_table = fib_table_get(fib_index, prefix->fp_proto);
616  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
617 
618  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
619  {
620  /*
621  * removing an etry that does not exist. i'll allow it.
622  */
623  }
624  else
625  {
626  fib_entry_src_flag_t src_flag;
627  int was_sourced;
628 
629  /*
630  * if it's not sourced, then there's nowt to remove
631  */
632  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
633  if (!was_sourced)
634  {
635  return;
636  }
637 
638  /*
639  * don't nobody go nowhere
640  */
641  fib_entry_lock(fib_entry_index);
642 
643  for (ii = 0; ii < vec_len(rpath); ii++)
644  {
646  prefix,
647  fib_entry_get_flags_for_source(fib_entry_index,
648  source),
649  &rpath[ii]);
650  }
651 
652  src_flag = fib_entry_path_remove(fib_entry_index, source, rpath);
653 
654  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
655  {
656  /*
657  * last source gone. remove from the table
658  */
659  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
660 
661  /*
662  * now the entry is no longer in the table, we can
663  * inform the entries that it covers to re-calculate their cover
664  */
665  fib_entry_cover_change_notify(fib_entry_index,
667  }
668  /*
669  * else
670  * still has sources, leave it be.
671  */
672  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
673  {
674  fib_table->ft_src_route_counts[source]--;
675  }
676 
677  fib_entry_unlock(fib_entry_index);
678  }
679 }
680 
681 void
683  const fib_prefix_t *prefix,
684  fib_source_t source,
685  dpo_proto_t next_hop_proto,
686  const ip46_address_t *next_hop,
687  u32 next_hop_sw_if_index,
688  u32 next_hop_fib_index,
689  u32 next_hop_weight,
690  fib_route_path_flags_t path_flags)
691 {
692  /*
693  * 1 is it present
694  * yes => remove source
695  * 2 - is it still sourced?
696  * no => cover walk
697  */
698  fib_route_path_t path = {
699  .frp_proto = next_hop_proto,
700  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
701  .frp_sw_if_index = next_hop_sw_if_index,
702  .frp_fib_index = next_hop_fib_index,
703  .frp_weight = next_hop_weight,
704  .frp_flags = path_flags,
705  };
706  fib_route_path_t *paths = NULL;
707 
708  vec_add1(paths, path);
709 
710  fib_table_entry_path_remove2(fib_index, prefix, source, paths);
711 
712  vec_free(paths);
713 }
714 
715 static int
717  void * v2)
718 {
719  return (fib_route_path_cmp(v1, v2));
720 }
721 
724  const fib_prefix_t *prefix,
725  fib_source_t source,
727  fib_route_path_t *paths)
728 {
729  fib_node_index_t fib_entry_index;
730  fib_table_t *fib_table;
731  u32 ii;
732 
733  fib_table = fib_table_get(fib_index, prefix->fp_proto);
734  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
735 
736  for (ii = 0; ii < vec_len(paths); ii++)
737  {
738  fib_table_route_path_fixup(prefix, flags, &paths[ii]);
739  }
740  /*
741  * sort the paths provided by the control plane. this means
742  * the paths and the extension on the entry will be sorted.
743  */
745 
746  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
747  {
748  fib_entry_index = fib_entry_create(fib_index, prefix,
749  source, flags,
750  paths);
751 
752  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
753  fib_table->ft_src_route_counts[source]++;
754  }
755  else
756  {
757  int was_sourced;
758 
759  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
760  fib_entry_update(fib_entry_index, source, flags, paths);
761 
762  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
763  {
764  fib_table->ft_src_route_counts[source]++;
765  }
766  }
767 
768  return (fib_entry_index);
769 }
770 
773  const fib_prefix_t *prefix,
774  fib_source_t source,
776  dpo_proto_t next_hop_proto,
777  const ip46_address_t *next_hop,
778  u32 next_hop_sw_if_index,
779  u32 next_hop_fib_index,
780  u32 next_hop_weight,
781  fib_mpls_label_t *next_hop_labels,
782  fib_route_path_flags_t path_flags)
783 {
784  fib_node_index_t fib_entry_index;
785  fib_route_path_t path = {
786  .frp_proto = next_hop_proto,
787  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
788  .frp_sw_if_index = next_hop_sw_if_index,
789  .frp_fib_index = next_hop_fib_index,
790  .frp_weight = next_hop_weight,
791  .frp_flags = path_flags,
792  .frp_label_stack = next_hop_labels,
793  };
794  fib_route_path_t *paths = NULL;
795 
796  vec_add1(paths, path);
797 
798  fib_entry_index =
799  fib_table_entry_update(fib_index, prefix, source, flags, paths);
800 
801  vec_free(paths);
802 
803  return (fib_entry_index);
804 }
805 
806 static void
808  fib_node_index_t fib_entry_index,
809  const fib_prefix_t *prefix,
810  fib_source_t source)
811 {
812  fib_entry_src_flag_t src_flag;
813  fib_table_t *fib_table;
814  int was_sourced;
815 
816  fib_table = fib_table_get(fib_index, prefix->fp_proto);
817  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
818 
819  /*
820  * don't nobody go nowhere
821  */
822  fib_entry_lock(fib_entry_index);
823 
824  src_flag = fib_entry_delete(fib_entry_index, source);
825 
826  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
827  {
828  /*
829  * last source gone. remove from the table
830  */
831  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
832 
833  /*
834  * now the entry is no longer in the table, we can
835  * inform the entries that it covers to re-calculate their cover
836  */
837  fib_entry_cover_change_notify(fib_entry_index,
839  }
840  /*
841  * else
842  * still has sources, leave it be.
843  */
844  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
845  {
846  fib_table->ft_src_route_counts[source]--;
847  }
848 
849  fib_entry_unlock(fib_entry_index);
850 }
851 
852 void
854  const fib_prefix_t *prefix,
855  fib_source_t source)
856 {
857  fib_node_index_t fib_entry_index;
858 
859  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
860 
861  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
862  {
863  /*
864  * removing an etry that does not exist.
865  * i'll allow it, but i won't like it.
866  */
867  if (0)
868  clib_warning("%U not in FIB", format_fib_prefix, prefix);
869  }
870  else
871  {
872  fib_table_entry_delete_i(fib_index, fib_entry_index, prefix, source);
873  }
874 }
875 
876 void
878  fib_source_t source)
879 {
880  const fib_prefix_t *prefix;
881 
882  prefix = fib_entry_get_prefix(fib_entry_index);
883 
885  fib_entry_index, prefix, source);
886 }
887 
888 u32
890  const fib_prefix_t *prefix)
891 {
893  fib_table_lookup_exact_match(fib_index, prefix)));
894 }
895 
898  const fib_prefix_t *prefix,
899  mpls_label_t label)
900 {
901  fib_node_index_t fib_entry_index;
902 
903  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
904 
905  if (FIB_NODE_INDEX_INVALID == fib_entry_index ||
906  !fib_entry_is_sourced(fib_entry_index, FIB_SOURCE_MPLS))
907  {
908  /*
909  * only source the prefix once. this allows the label change
910  * operation to work
911  */
912  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix,
915  NULL);
916  }
917 
918  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &label);
919 
920  return (fib_entry_index);
921 }
922 
923 void
925  const fib_prefix_t *prefix,
926  mpls_label_t label)
927 {
928  fib_node_index_t fib_entry_index;
929  const void *data;
930  mpls_label_t pl;
931 
932  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
933 
934  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
935  return;
936 
937  data = fib_entry_get_source_data(fib_entry_index, FIB_SOURCE_MPLS);
938 
939  if (NULL == data)
940  return;
941 
942  pl = *(mpls_label_t*)data;
943 
944  if (pl != label)
945  return;
946 
947  pl = MPLS_LABEL_INVALID;
948 
949  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &pl);
951  prefix,
953 }
954 
955 u32
958 {
959  switch (proto)
960  {
961  case FIB_PROTOCOL_IP4:
962  return (ip4_fib_table_get_index_for_sw_if_index(sw_if_index));
963  case FIB_PROTOCOL_IP6:
964  return (ip6_fib_table_get_index_for_sw_if_index(sw_if_index));
965  case FIB_PROTOCOL_MPLS:
966  return (mpls_fib_table_get_index_for_sw_if_index(sw_if_index));
967  }
968  return (~0);
969 }
970 
973  fib_protocol_t proto)
974 {
975  fib_table_t *fib;
976 
977  fib = fib_table_get(fib_index, proto);
978 
979  return (fib->ft_flow_hash_config);
980 }
981 
984 {
985  switch (proto)
986  {
987  case FIB_PROTOCOL_IP4:
988  case FIB_PROTOCOL_IP6:
989  return (IP_FLOW_HASH_DEFAULT);
990 
991  case FIB_PROTOCOL_MPLS:
992  return (MPLS_FLOW_HASH_DEFAULT);
993  }
994 
995  ASSERT(0);
996  return (IP_FLOW_HASH_DEFAULT);
997 }
998 
999 /**
1000  * @brief Table set flow hash config context.
1001  */
1003 {
1004  /**
1005  * the flow hash config to set
1006  */
1009 
1010 static fib_table_walk_rc_t
1012  void *arg)
1013 {
1015 
1016  fib_entry_set_flow_hash_config(fib_entry_index, ctx->hash_config);
1017 
1018  return (FIB_TABLE_WALK_CONTINUE);
1019 }
1020 
1021 void
1023  fib_protocol_t proto,
1025 {
1027  .hash_config = hash_config,
1028  };
1029  fib_table_t *fib;
1030 
1031  fib = fib_table_get(fib_index, proto);
1033 
1034  fib_table_walk(fib_index, proto,
1036  &ctx);
1037 }
1038 
1039 u32
1041  u32 sw_if_index)
1042 {
1043  fib_table_t *fib_table;
1044 
1046  proto, sw_if_index),
1047  proto);
1048 
1049  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1050 }
1051 
1052 u32
1054  fib_protocol_t proto)
1055 {
1056  fib_table_t *fib_table;
1057 
1058  fib_table = fib_table_get(fib_index, proto);
1059 
1060  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1061 }
1062 
1063 u32
1065  u32 table_id)
1066 {
1067  switch (proto)
1068  {
1069  case FIB_PROTOCOL_IP4:
1070  return (ip4_fib_index_from_table_id(table_id));
1071  case FIB_PROTOCOL_IP6:
1072  return (ip6_fib_index_from_table_id(table_id));
1073  case FIB_PROTOCOL_MPLS:
1074  return (mpls_fib_index_from_table_id(table_id));
1075  }
1076  return (~0);
1077 }
1078 
1079 static u32
1081  u32 table_id,
1082  fib_source_t src,
1083  const u8 *name)
1084 {
1085  fib_table_t *fib_table;
1086  fib_node_index_t fi;
1087 
1088  switch (proto)
1089  {
1090  case FIB_PROTOCOL_IP4:
1091  fi = ip4_fib_table_find_or_create_and_lock(table_id, src);
1092  break;
1093  case FIB_PROTOCOL_IP6:
1094  fi = ip6_fib_table_find_or_create_and_lock(table_id, src);
1095  break;
1096  case FIB_PROTOCOL_MPLS:
1097  fi = mpls_fib_table_find_or_create_and_lock(table_id, src);
1098  break;
1099  default:
1100  return (~0);
1101  }
1102 
1103  fib_table = fib_table_get(fi, proto);
1104 
1105  if (NULL == fib_table->ft_desc)
1106  {
1107  if (name && name[0])
1108  {
1109  fib_table->ft_desc = format(NULL, "%s", name);
1110  }
1111  else
1112  {
1113  fib_table->ft_desc = format(NULL, "%U-VRF:%d",
1114  format_fib_protocol, proto,
1115  table_id);
1116  }
1117  }
1118 
1119  return (fi);
1120 }
1121 
1122 u32
1124  u32 table_id,
1125  fib_source_t src)
1126 {
1127  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1128  src, NULL));
1129 }
1130 
1131 u32
1133  u32 table_id,
1134  fib_source_t src,
1135  const u8 *name)
1136 {
1137  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1138  src, name));
1139 }
1140 
1141 u32
1143  fib_source_t src,
1144  const char *const fmt,
1145  ...)
1146 {
1147  fib_table_t *fib_table;
1148  fib_node_index_t fi;
1149  va_list ap;
1150 
1151  va_start(ap, fmt);
1152 
1153  switch (proto)
1154  {
1155  case FIB_PROTOCOL_IP4:
1157  break;
1158  case FIB_PROTOCOL_IP6:
1160  break;
1161  case FIB_PROTOCOL_MPLS:
1163  break;
1164  default:
1165  return (~0);
1166  }
1167 
1168  fib_table = fib_table_get(fi, proto);
1169 
1170  fib_table->ft_desc = va_format(fib_table->ft_desc, fmt, &ap);
1171 
1172  va_end(ap);
1173  return (fi);
1174 }
1175 
1176 static void
1178 {
1179  vec_free(fib_table->ft_desc);
1180 
1181  switch (fib_table->ft_proto)
1182  {
1183  case FIB_PROTOCOL_IP4:
1184  ip4_fib_table_destroy(fib_table->ft_index);
1185  break;
1186  case FIB_PROTOCOL_IP6:
1187  ip6_fib_table_destroy(fib_table->ft_index);
1188  break;
1189  case FIB_PROTOCOL_MPLS:
1190  mpls_fib_table_destroy(fib_table->ft_index);
1191  break;
1192  }
1193 }
1194 
1195 void
1196 fib_table_walk (u32 fib_index,
1197  fib_protocol_t proto,
1199  void *ctx)
1200 {
1201  switch (proto)
1202  {
1203  case FIB_PROTOCOL_IP4:
1204  ip4_fib_table_walk(ip4_fib_get(fib_index), fn, ctx);
1205  break;
1206  case FIB_PROTOCOL_IP6:
1207  ip6_fib_table_walk(fib_index, fn, ctx);
1208  break;
1209  case FIB_PROTOCOL_MPLS:
1210  mpls_fib_table_walk(mpls_fib_get(fib_index), fn, ctx);
1211  break;
1212  }
1213 }
1214 
1215 void
1217  fib_protocol_t proto,
1218  const fib_prefix_t *root,
1220  void *ctx)
1221 {
1222  switch (proto)
1223  {
1224  case FIB_PROTOCOL_IP4:
1225  ip4_fib_table_sub_tree_walk(ip4_fib_get(fib_index), root, fn, ctx);
1226  break;
1227  case FIB_PROTOCOL_IP6:
1228  ip6_fib_table_sub_tree_walk(fib_index, root, fn, ctx);
1229  break;
1230  case FIB_PROTOCOL_MPLS:
1231  break;
1232  }
1233 }
1234 
1235 void
1237  fib_protocol_t proto,
1238  fib_source_t source)
1239 {
1240  fib_table_t *fib_table;
1241 
1242  fib_table = fib_table_get(fib_index, proto);
1243  fib_table->ft_locks[source]--;
1244  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]--;
1245 
1246  if (0 == fib_table->ft_locks[source])
1247  {
1248  /*
1249  * The source no longer needs the table. flush any routes
1250  * from it just in case
1251  */
1252  fib_table_flush(fib_index, proto, source);
1253  }
1254 
1255  if (0 == fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS])
1256  {
1257  /*
1258  * no more locak from any source - kill it
1259  */
1260  fib_table_destroy(fib_table);
1261  }
1262 }
1263 
1264 void
1265 fib_table_lock (u32 fib_index,
1266  fib_protocol_t proto,
1267  fib_source_t source)
1268 {
1269  fib_table_t *fib_table;
1270 
1271  fib_table = fib_table_get(fib_index, proto);
1272 
1273  ASSERT(fib_table->ft_locks[source] < (0xffff - 1));
1274 
1275  fib_table->ft_locks[source]++;
1276  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]++;
1277 }
1278 
1279 u32
1281  fib_protocol_t proto,
1282  fib_source_t source)
1283 {
1284  fib_table_t *fib_table;
1285 
1286  fib_table = fib_table_get(fib_index, proto);
1287 
1288  return (fib_table->ft_src_route_counts[source]);
1289 }
1290 
1291 u8*
1292 format_fib_table_name (u8* s, va_list* ap)
1293 {
1294  fib_node_index_t fib_index = va_arg(*ap, fib_node_index_t);
1295  fib_protocol_t proto = va_arg(*ap, int); // int promotion
1296  fib_table_t *fib_table;
1297 
1298  fib_table = fib_table_get(fib_index, proto);
1299 
1300  s = format(s, "%v", fib_table->ft_desc);
1301 
1302  return (s);
1303 }
1304 
1305 /**
1306  * @brief Table flush context. Store the indicies of matching FIB entries
1307  * that need to be removed.
1308  */
1310 {
1311  /**
1312  * The list of entries to flush
1313  */
1315 
1316  /**
1317  * The source we are flushing
1318  */
1321 
1322 static fib_table_walk_rc_t
1324  void *arg)
1325 {
1326  fib_table_flush_ctx_t *ctx = arg;
1327 
1328  if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
1329  {
1330  vec_add1(ctx->ftf_entries, fib_entry_index);
1331  }
1332  return (FIB_TABLE_WALK_CONTINUE);
1333 }
1334 
1335 
1336 void
1338  fib_protocol_t proto,
1339  fib_source_t source)
1340 {
1341  fib_node_index_t *fib_entry_index;
1343  .ftf_entries = NULL,
1344  .ftf_source = source,
1345  };
1346 
1347  fib_table_walk(fib_index, proto,
1349  &ctx);
1350 
1351  vec_foreach(fib_entry_index, ctx.ftf_entries)
1352  {
1353  fib_table_entry_delete_index(*fib_entry_index, source);
1354  }
1355 
1356  vec_free(ctx.ftf_entries);
1357 }
1358 
1359 u8 *
1360 format_fib_table_memory (u8 *s, va_list *args)
1361 {
1362  s = format(s, "%U", format_ip4_fib_table_memory);
1363  s = format(s, "%U", format_ip6_fib_table_memory);
1364  s = format(s, "%U", format_mpls_fib_table_memory);
1365 
1366  return (s);
1367 }
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:372
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:1632
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:522
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:486
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:1593
vl_api_address_t src
Definition: vxlan_gbp.api:33
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:470
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:1319
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:1470
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 *rpath)
Definition: fib_entry.c:969
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 *rpath)
Definition: fib_entry.c:873
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:1132
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:723
#define NULL
Definition: clib.h:57
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 *rpath)
Add n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:556
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:956
u8 * format_ip6_fib_table_memory(u8 *s, va_list *args)
Definition: ip6_fib.c:569
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:261
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
void ip4_fib_table_destroy(u32 fib_index)
Definition: ip4_fib.c:159
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:1622
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
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:475
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
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:924
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:217
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:972
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:772
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
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:983
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:215
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:856
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:505
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
u32 sw_if_index
Definition: vxlan_gbp.api:39
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:1434
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:1337
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:1064
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:323
Definition: fib_entry.h:275
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:114
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
Definition: fib_entry.h:280
Definition: fib_entry.h:279
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:464
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:337
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:367
void fib_table_entry_path_remove2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:600
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:425
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:1280
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:1174
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:726
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:1236
u8 name[64]
Definition: memclnt.api:151
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:474
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:93
void fib_entry_inherit(fib_node_index_t cover, fib_node_index_t covered)
fib_entry_inherit
Definition: fib_entry.c:1161
void ip6_fib_table_entry_remove(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:254
u32 flags
Definition: vhost_user.h:115
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:807
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)
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:118
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:897
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:877
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:1177
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:339
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:853
u32 ip6_fib_table_create_and_lock(fib_source_t src, fib_table_flags_t flags, u8 *desc)
Definition: ip6_fib.c:110
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:1022
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:278
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:1007
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:1360
static int fib_route_path_cmp_for_sort(void *v1, void *v2)
Definition: fib_table.c:716
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_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:1265
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:1583
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:1040
#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:2590
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:1196
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:1053
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:1123
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:567
Definition: fib_entry.h:334
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:69
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:682
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:82
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:889
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:1080
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:689
#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)
fib_node_index_t * ftf_entries
The list of entries to flush.
Definition: fib_table.c:1314
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:982
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:285
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:1011
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:195
u32 fib_entry_get_stats_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1499
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
typedef prefix
Definition: ip_types.api:40
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:1186
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:1292
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:900
Table set flow hash config context.
Definition: fib_table.c:1002
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:101
#define vec_foreach(var, vec)
Vector iterator.
fib_node_index_t ip6_fib_table_lookup(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:169
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:1309
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:1216
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:497
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:1142
struct fib_table_t_ * fibs
Definition: ip6.h:164
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:840
const ip46_address_t zero_addr
Definition: lookup.c:318
fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry.c:1061
static fib_table_walk_rc_t fib_table_flush_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:1323
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