FD.io VPP  v18.07-rc0-415-g6c78436
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  fib_prefix_t prefix;
881 
882  fib_entry_get_prefix(fib_entry_index, &prefix);
883 
885  fib_entry_index, &prefix, source);
886 }
887 
890  const fib_prefix_t *prefix,
891  mpls_label_t label)
892 {
893  fib_node_index_t fib_entry_index;
894 
895  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
896 
897  if (FIB_NODE_INDEX_INVALID == fib_entry_index ||
898  !fib_entry_is_sourced(fib_entry_index, FIB_SOURCE_MPLS))
899  {
900  /*
901  * only source the prefix once. this allows the label change
902  * operation to work
903  */
904  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix,
907  NULL);
908  }
909 
910  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &label);
911 
912  return (fib_entry_index);
913 }
914 
915 void
917  const fib_prefix_t *prefix,
918  mpls_label_t label)
919 {
920  fib_node_index_t fib_entry_index;
921  const void *data;
922  mpls_label_t pl;
923 
924  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
925 
926  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
927  return;
928 
929  data = fib_entry_get_source_data(fib_entry_index, FIB_SOURCE_MPLS);
930 
931  if (NULL == data)
932  return;
933 
934  pl = *(mpls_label_t*)data;
935 
936  if (pl != label)
937  return;
938 
939  pl = MPLS_LABEL_INVALID;
940 
941  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &pl);
943  prefix,
945 }
946 
947 u32
949  u32 sw_if_index)
950 {
951  switch (proto)
952  {
953  case FIB_PROTOCOL_IP4:
954  return (ip4_fib_table_get_index_for_sw_if_index(sw_if_index));
955  case FIB_PROTOCOL_IP6:
956  return (ip6_fib_table_get_index_for_sw_if_index(sw_if_index));
957  case FIB_PROTOCOL_MPLS:
958  return (mpls_fib_table_get_index_for_sw_if_index(sw_if_index));
959  }
960  return (~0);
961 }
962 
965  fib_protocol_t proto)
966 {
967  fib_table_t *fib;
968 
969  fib = fib_table_get(fib_index, proto);
970 
971  return (fib->ft_flow_hash_config);
972 }
973 
976 {
977  switch (proto)
978  {
979  case FIB_PROTOCOL_IP4:
980  case FIB_PROTOCOL_IP6:
981  return (IP_FLOW_HASH_DEFAULT);
982 
983  case FIB_PROTOCOL_MPLS:
984  return (MPLS_FLOW_HASH_DEFAULT);
985  }
986 
987  ASSERT(0);
988  return (IP_FLOW_HASH_DEFAULT);
989 }
990 
991 /**
992  * @brief Table set flow hash config context.
993  */
995 {
996  /**
997  * the flow hash config to set
998  */
1001 
1002 static fib_table_walk_rc_t
1004  void *arg)
1005 {
1007 
1008  fib_entry_set_flow_hash_config(fib_entry_index, ctx->hash_config);
1009 
1010  return (FIB_TABLE_WALK_CONTINUE);
1011 }
1012 
1013 void
1015  fib_protocol_t proto,
1017 {
1019  .hash_config = hash_config,
1020  };
1021  fib_table_t *fib;
1022 
1023  fib = fib_table_get(fib_index, proto);
1025 
1026  fib_table_walk(fib_index, proto,
1028  &ctx);
1029 }
1030 
1031 u32
1033  u32 sw_if_index)
1034 {
1035  fib_table_t *fib_table;
1036 
1038  proto, sw_if_index),
1039  proto);
1040 
1041  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1042 }
1043 
1044 u32
1046  fib_protocol_t proto)
1047 {
1048  fib_table_t *fib_table;
1049 
1050  fib_table = fib_table_get(fib_index, proto);
1051 
1052  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1053 }
1054 
1055 u32
1057  u32 table_id)
1058 {
1059  switch (proto)
1060  {
1061  case FIB_PROTOCOL_IP4:
1062  return (ip4_fib_index_from_table_id(table_id));
1063  case FIB_PROTOCOL_IP6:
1064  return (ip6_fib_index_from_table_id(table_id));
1065  case FIB_PROTOCOL_MPLS:
1066  return (mpls_fib_index_from_table_id(table_id));
1067  }
1068  return (~0);
1069 }
1070 
1071 static u32
1073  u32 table_id,
1074  fib_source_t src,
1075  const u8 *name)
1076 {
1077  fib_table_t *fib_table;
1078  fib_node_index_t fi;
1079 
1080  switch (proto)
1081  {
1082  case FIB_PROTOCOL_IP4:
1083  fi = ip4_fib_table_find_or_create_and_lock(table_id, src);
1084  break;
1085  case FIB_PROTOCOL_IP6:
1086  fi = ip6_fib_table_find_or_create_and_lock(table_id, src);
1087  break;
1088  case FIB_PROTOCOL_MPLS:
1089  fi = mpls_fib_table_find_or_create_and_lock(table_id, src);
1090  break;
1091  default:
1092  return (~0);
1093  }
1094 
1095  fib_table = fib_table_get(fi, proto);
1096 
1097  if (NULL == fib_table->ft_desc)
1098  {
1099  if (name && name[0])
1100  {
1101  fib_table->ft_desc = format(NULL, "%s", name);
1102  }
1103  else
1104  {
1105  fib_table->ft_desc = format(NULL, "%U-VRF:%d",
1106  format_fib_protocol, proto,
1107  table_id);
1108  }
1109  }
1110 
1111  return (fi);
1112 }
1113 
1114 u32
1116  u32 table_id,
1117  fib_source_t src)
1118 {
1119  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1120  src, NULL));
1121 }
1122 
1123 u32
1125  u32 table_id,
1126  fib_source_t src,
1127  const u8 *name)
1128 {
1129  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1130  src, name));
1131 }
1132 
1133 u32
1135  fib_source_t src,
1136  const char *const fmt,
1137  ...)
1138 {
1139  fib_table_t *fib_table;
1140  fib_node_index_t fi;
1141  va_list ap;
1142 
1143  va_start(ap, fmt);
1144 
1145  switch (proto)
1146  {
1147  case FIB_PROTOCOL_IP4:
1149  break;
1150  case FIB_PROTOCOL_IP6:
1152  break;
1153  case FIB_PROTOCOL_MPLS:
1155  break;
1156  default:
1157  return (~0);
1158  }
1159 
1160  fib_table = fib_table_get(fi, proto);
1161 
1162  fib_table->ft_desc = va_format(fib_table->ft_desc, fmt, &ap);
1163 
1164  va_end(ap);
1165  return (fi);
1166 }
1167 
1168 static void
1170 {
1171  vec_free(fib_table->ft_desc);
1172 
1173  switch (fib_table->ft_proto)
1174  {
1175  case FIB_PROTOCOL_IP4:
1176  ip4_fib_table_destroy(fib_table->ft_index);
1177  break;
1178  case FIB_PROTOCOL_IP6:
1179  ip6_fib_table_destroy(fib_table->ft_index);
1180  break;
1181  case FIB_PROTOCOL_MPLS:
1182  mpls_fib_table_destroy(fib_table->ft_index);
1183  break;
1184  }
1185 }
1186 
1187 void
1188 fib_table_walk (u32 fib_index,
1189  fib_protocol_t proto,
1191  void *ctx)
1192 {
1193  switch (proto)
1194  {
1195  case FIB_PROTOCOL_IP4:
1196  ip4_fib_table_walk(ip4_fib_get(fib_index), fn, ctx);
1197  break;
1198  case FIB_PROTOCOL_IP6:
1199  ip6_fib_table_walk(fib_index, fn, ctx);
1200  break;
1201  case FIB_PROTOCOL_MPLS:
1202  mpls_fib_table_walk(mpls_fib_get(fib_index), fn, ctx);
1203  break;
1204  }
1205 }
1206 
1207 void
1209  fib_protocol_t proto,
1210  const fib_prefix_t *root,
1212  void *ctx)
1213 {
1214  switch (proto)
1215  {
1216  case FIB_PROTOCOL_IP4:
1217  ip4_fib_table_sub_tree_walk(ip4_fib_get(fib_index), root, fn, ctx);
1218  break;
1219  case FIB_PROTOCOL_IP6:
1220  ip6_fib_table_sub_tree_walk(fib_index, root, fn, ctx);
1221  break;
1222  case FIB_PROTOCOL_MPLS:
1223  break;
1224  }
1225 }
1226 
1227 void
1229  fib_protocol_t proto,
1230  fib_source_t source)
1231 {
1232  fib_table_t *fib_table;
1233 
1234  fib_table = fib_table_get(fib_index, proto);
1235  fib_table->ft_locks[source]--;
1236  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]--;
1237 
1238  if (0 == fib_table->ft_locks[source])
1239  {
1240  /*
1241  * The source no longer needs the table. flush any routes
1242  * from it just in case
1243  */
1244  fib_table_flush(fib_index, proto, source);
1245  }
1246 
1247  if (0 == fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS])
1248  {
1249  /*
1250  * no more locak from any source - kill it
1251  */
1252  fib_table_destroy(fib_table);
1253  }
1254 }
1255 
1256 void
1257 fib_table_lock (u32 fib_index,
1258  fib_protocol_t proto,
1259  fib_source_t source)
1260 {
1261  fib_table_t *fib_table;
1262 
1263  fib_table = fib_table_get(fib_index, proto);
1264  fib_table->ft_locks[source]++;
1265  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]++;
1266 }
1267 
1268 u32
1270  fib_protocol_t proto,
1271  fib_source_t source)
1272 {
1273  fib_table_t *fib_table;
1274 
1275  fib_table = fib_table_get(fib_index, proto);
1276 
1277  return (fib_table->ft_src_route_counts[source]);
1278 }
1279 
1280 u8*
1281 format_fib_table_name (u8* s, va_list* ap)
1282 {
1283  fib_node_index_t fib_index = va_arg(*ap, fib_node_index_t);
1284  fib_protocol_t proto = va_arg(*ap, int); // int promotion
1285  fib_table_t *fib_table;
1286 
1287  fib_table = fib_table_get(fib_index, proto);
1288 
1289  s = format(s, "%v", fib_table->ft_desc);
1290 
1291  return (s);
1292 }
1293 
1294 /**
1295  * @brief Table flush context. Store the indicies of matching FIB entries
1296  * that need to be removed.
1297  */
1299 {
1300  /**
1301  * The list of entries to flush
1302  */
1304 
1305  /**
1306  * The source we are flushing
1307  */
1310 
1311 static fib_table_walk_rc_t
1313  void *arg)
1314 {
1315  fib_table_flush_ctx_t *ctx = arg;
1316 
1317  if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
1318  {
1319  vec_add1(ctx->ftf_entries, fib_entry_index);
1320  }
1321  return (FIB_TABLE_WALK_CONTINUE);
1322 }
1323 
1324 
1325 void
1327  fib_protocol_t proto,
1328  fib_source_t source)
1329 {
1330  fib_node_index_t *fib_entry_index;
1332  .ftf_entries = NULL,
1333  .ftf_source = source,
1334  };
1335 
1336  fib_table_walk(fib_index, proto,
1338  &ctx);
1339 
1340  vec_foreach(fib_entry_index, ctx.ftf_entries)
1341  {
1342  fib_table_entry_delete_index(*fib_entry_index, source);
1343  }
1344 
1345  vec_free(ctx.ftf_entries);
1346 }
1347 
1348 u8 *
1349 format_fib_table_memory (u8 *s, va_list *args)
1350 {
1351  s = format(s, "%U", format_ip4_fib_table_memory);
1352  s = format(s, "%U", format_ip6_fib_table_memory);
1353  s = format(s, "%U", format_mpls_fib_table_memory);
1354 
1355  return (s);
1356 }
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:197
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1626
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:471
Continue on to the next entry.
Definition: fib_table.h:857
void fib_entry_unlock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1587
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:390
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:455
int fib_route_path_cmp(const fib_route_path_t *rpath1, const fib_route_path_t *rpath2)
Definition: fib_types.c:213
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:1308
A Drop path - resolve the path on the drop DPO.
Definition: fib_types.h:325
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:1474
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
void fib_entry_get_prefix(fib_node_index_t fib_entry_index, fib_prefix_t *pfx)
Definition: fib_entry.c:1616
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:1124
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:55
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:948
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:161
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
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:460
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:205
#define ip46_address_cmp(ip46_1, ip46_2)
Definition: ip6_packet.h:85
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:916
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:161
static void vlib_smp_unsafe_warning(void)
Definition: threads.h:227
u8 * format_fib_protocol(u8 *s, va_list *ap)
Definition: fib_types.c:31
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:964
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:220
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:975
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip4_fib.c:226
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:490
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:1434
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:176
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:1326
Aggregrate type for a prefix.
Definition: fib_types.h:188
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:433
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:1056
u16 fp_len
The mask length.
Definition: fib_types.h:192
void ip4_fib_table_entry_remove(ip4_fib_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib.c:351
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:270
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:110
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:275
Definition: fib_entry.h:274
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:461
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:211
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
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:410
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:1269
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:381
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:1228
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
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:293
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:316
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:889
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:1169
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:117
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:1014
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:273
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:999
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:1349
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:329
static u32 ip4_fib_index_from_table_id(u32 table_id)
Definition: ip4_fib.h:149
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:416
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:871
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:1257
mpls_label_t fp_label
Definition: fib_types.h:214
void fib_entry_lock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1577
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:1032
#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:2574
long ctx[MAX_CONNS]
Definition: main.c:126
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:1188
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:1045
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:1115
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:547
Definition: fib_entry.h:329
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:236
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:570
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
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:1072
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:317
#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:1303
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:961
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:1003
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:195
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: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:1281
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:832
Table set flow hash config context.
Definition: fib_table.c:994
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:100
#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:321
Table flush context.
Definition: fib_table.c:1298
u32 flags
Definition: vhost-user.h:77
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:1208
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:245
#define ip46_address_is_zero(ip46)
Definition: ip6_packet.h:86
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:1134
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:1312
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:215