FD.io VPP  v18.01-8-g0eacf49
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 and inform the covering entry that a new more specific
185  * has been inserted beneath it
186  */
187  fib_entry_cover_index = fib_table_get_less_specific_i(fib_table, prefix);
188  /*
189  * the indicies are the same when the default route is first added
190  */
191  if (fib_entry_cover_index != fib_entry_index)
192  {
193  fib_entry_cover_change_notify(fib_entry_cover_index,
194  fib_entry_index);
195  }
196 }
197 
198 static void
200  const fib_prefix_t *prefix,
201  fib_node_index_t fib_entry_index)
202 {
204 
205  fib_entry_lock(fib_entry_index);
206  fib_table->ft_total_route_counts++;
207 
208  switch (prefix->fp_proto)
209  {
210  case FIB_PROTOCOL_IP4:
212  &prefix->fp_addr.ip4,
213  prefix->fp_len,
214  fib_entry_index);
215  break;
216  case FIB_PROTOCOL_IP6:
218  &prefix->fp_addr.ip6,
219  prefix->fp_len,
220  fib_entry_index);
221  break;
222  case FIB_PROTOCOL_MPLS:
224  prefix->fp_label,
225  prefix->fp_eos,
226  fib_entry_index);
227  break;
228  }
229 
230  fib_table_post_insert_actions(fib_table, prefix, fib_entry_index);
231 }
232 
233 void
235  const fib_prefix_t *prefix,
236  const dpo_id_t *dpo)
237 {
239 
240  switch (prefix->fp_proto)
241  {
242  case FIB_PROTOCOL_IP4:
243  return (ip4_fib_table_fwding_dpo_update(ip4_fib_get(fib_index),
244  &prefix->fp_addr.ip4,
245  prefix->fp_len,
246  dpo));
247  case FIB_PROTOCOL_IP6:
248  return (ip6_fib_table_fwding_dpo_update(fib_index,
249  &prefix->fp_addr.ip6,
250  prefix->fp_len,
251  dpo));
252  case FIB_PROTOCOL_MPLS:
254  prefix->fp_label,
255  prefix->fp_eos,
256  dpo));
257  }
258 }
259 
260 void
262  const fib_prefix_t *prefix,
263  const dpo_id_t *dpo)
264 {
266 
267  switch (prefix->fp_proto)
268  {
269  case FIB_PROTOCOL_IP4:
270  return (ip4_fib_table_fwding_dpo_remove(ip4_fib_get(fib_index),
271  &prefix->fp_addr.ip4,
272  prefix->fp_len,
273  dpo,
274  fib_table_get_less_specific(fib_index,
275  prefix)));
276  case FIB_PROTOCOL_IP6:
277  return (ip6_fib_table_fwding_dpo_remove(fib_index,
278  &prefix->fp_addr.ip6,
279  prefix->fp_len,
280  dpo));
281  case FIB_PROTOCOL_MPLS:
283  prefix->fp_label,
284  prefix->fp_eos));
285  }
286 }
287 
288 
291  const fib_prefix_t *prefix,
292  fib_source_t source,
294  const dpo_id_t *dpo)
295 {
296  fib_node_index_t fib_entry_index;
297  fib_table_t *fib_table;
298 
299  fib_table = fib_table_get(fib_index, prefix->fp_proto);
300  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
301 
302  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
303  {
304  fib_entry_index = fib_entry_create_special(fib_index, prefix,
305  source, flags,
306  dpo);
307 
308  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
309  fib_table->ft_src_route_counts[source]++;
310  }
311  else
312  {
313  int was_sourced;
314 
315  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
316  fib_entry_special_add(fib_entry_index, source, flags, dpo);
317 
318  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
319  {
320  fib_table->ft_src_route_counts[source]++;
321  }
322  }
323 
324 
325  return (fib_entry_index);
326 }
327 
330  const fib_prefix_t *prefix,
331  fib_source_t source,
333  const dpo_id_t *dpo)
334 {
335  fib_node_index_t fib_entry_index;
336  fib_table_t *fib_table;
337 
338  fib_table = fib_table_get(fib_index, prefix->fp_proto);
339  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
340 
341  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
342  {
343  fib_entry_index = fib_entry_create_special(fib_index, prefix,
344  source, flags,
345  dpo);
346 
347  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
348  fib_table->ft_src_route_counts[source]++;
349  }
350  else
351  {
352  int was_sourced;
353 
354  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
355 
356  if (was_sourced)
357  fib_entry_special_update(fib_entry_index, source, flags, dpo);
358  else
359  fib_entry_special_add(fib_entry_index, source, flags, dpo);
360 
361  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
362  {
363  fib_table->ft_src_route_counts[source]++;
364  }
365  }
366 
367  return (fib_entry_index);
368 }
369 
372  const fib_prefix_t *prefix,
373  fib_source_t source,
375 {
376  fib_node_index_t fib_entry_index;
377  dpo_id_t tmp_dpo = DPO_INVALID;
378 
379  dpo_copy(&tmp_dpo, drop_dpo_get(fib_proto_to_dpo(prefix->fp_proto)));
380 
381  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix, source,
382  flags, &tmp_dpo);
383 
384  dpo_unlock(&tmp_dpo);
385 
386  return (fib_entry_index);
387 }
388 
389 void
391  const fib_prefix_t *prefix,
392  fib_source_t source)
393 {
394  /*
395  * 1 is it present
396  * yes => remove source
397  * 2 - is it still sourced?
398  * no => cover walk
399  */
400  fib_node_index_t fib_entry_index;
401  fib_table_t *fib_table;
402 
403  fib_table = fib_table_get(fib_index, prefix->fp_proto);
404  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
405 
406  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
407  {
408  /*
409  * removing an etry that does not exist. i'll allow it.
410  */
411  }
412  else
413  {
414  fib_entry_src_flag_t src_flag;
415  int was_sourced;
416 
417  /*
418  * don't nobody go nowhere
419  */
420  fib_entry_lock(fib_entry_index);
421  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
422 
423  src_flag = fib_entry_special_remove(fib_entry_index, source);
424 
425  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
426  {
427  /*
428  * last source gone. remove from the table
429  */
430  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
431 
432  /*
433  * now the entry is no longer in the table, we can
434  * inform the entries that it covers to re-calculate their cover
435  */
436  fib_entry_cover_change_notify(fib_entry_index,
438  }
439  /*
440  * else
441  * still has sources, leave it be.
442  */
443  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
444  {
445  fib_table->ft_src_route_counts[source]--;
446  }
447 
448  fib_entry_unlock(fib_entry_index);
449  }
450 }
451 
452 /**
453  * fib_table_route_path_fixup
454  *
455  * Convert attached hosts to attached next-hops.
456  *
457  * This special case is required because an attached path will link to a
458  * glean, and the FIB entry will have the interface or API/CLI source. When
459  * the ARP/ND process is completes then that source (which will provide a
460  * complete adjacency) will be lower priority and so the FIB entry will
461  * remain linked to a glean and traffic will never reach the hosts. For
462  * an ATTAHCED_HOST path we can link the path directly to the [incomplete]
463  * adjacency.
464  */
465 static void
467  fib_entry_flag_t eflags,
468  fib_route_path_t *path)
469 {
470  /*
471  * not all zeros next hop &&
472  * is recursive path &&
473  * nexthop is same as the route's address
474  */
475  if ((!ip46_address_is_zero(&path->frp_addr)) &&
476  (~0 == path->frp_sw_if_index) &&
477  (0 == ip46_address_cmp(&path->frp_addr, &prefix->fp_addr)))
478  {
479  /* Prefix recurses via itse;f */
481  }
482  if (fib_prefix_is_host(prefix) &&
483  ip46_address_is_zero(&path->frp_addr) &&
484  path->frp_sw_if_index != ~0 &&
485  path->frp_proto != DPO_PROTO_ETHERNET)
486  {
487  path->frp_addr = prefix->fp_addr;
489  }
490  if (eflags & FIB_ENTRY_FLAG_DROP)
491  {
493  }
494  if (eflags & FIB_ENTRY_FLAG_LOCAL)
495  {
497  }
498  if (eflags & FIB_ENTRY_FLAG_EXCLUSIVE)
499  {
501  }
502 }
503 
506  const fib_prefix_t *prefix,
507  fib_source_t source,
509  dpo_proto_t next_hop_proto,
510  const ip46_address_t *next_hop,
511  u32 next_hop_sw_if_index,
512  u32 next_hop_fib_index,
513  u32 next_hop_weight,
514  mpls_label_t *next_hop_labels,
515  fib_route_path_flags_t path_flags)
516 {
517  fib_route_path_t path = {
518  .frp_proto = next_hop_proto,
519  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
520  .frp_sw_if_index = next_hop_sw_if_index,
521  .frp_fib_index = next_hop_fib_index,
522  .frp_weight = next_hop_weight,
523  .frp_flags = path_flags,
524  .frp_label_stack = next_hop_labels,
525  };
526  fib_node_index_t fib_entry_index;
527  fib_route_path_t *paths = NULL;
528 
529  vec_add1(paths, path);
530 
531  fib_entry_index = fib_table_entry_path_add2(fib_index, prefix,
532  source, flags, paths);
533 
534  vec_free(paths);
535  return (fib_entry_index);
536 }
537 
540  const fib_prefix_t *prefix,
541  fib_source_t source,
543  fib_route_path_t *rpath)
544 {
545  fib_node_index_t fib_entry_index;
546  fib_table_t *fib_table;
547  u32 ii;
548 
549  fib_table = fib_table_get(fib_index, prefix->fp_proto);
550  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
551 
552  for (ii = 0; ii < vec_len(rpath); ii++)
553  {
554  fib_table_route_path_fixup(prefix, flags, &rpath[ii]);
555  }
556 
557  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
558  {
559  fib_entry_index = fib_entry_create(fib_index, prefix,
560  source, flags,
561  rpath);
562 
563  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
564  fib_table->ft_src_route_counts[source]++;
565  }
566  else
567  {
568  int was_sourced;
569 
570  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
571  fib_entry_path_add(fib_entry_index, source, flags, rpath);;
572 
573  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
574  {
575  fib_table->ft_src_route_counts[source]++;
576  }
577  }
578 
579  return (fib_entry_index);
580 }
581 
582 void
584  const fib_prefix_t *prefix,
585  fib_source_t source,
586  fib_route_path_t *rpath)
587 {
588  /*
589  * 1 is it present
590  * yes => remove source
591  * 2 - is it still sourced?
592  * no => cover walk
593  */
594  fib_node_index_t fib_entry_index;
595  fib_table_t *fib_table;
596  u32 ii;
597 
598  fib_table = fib_table_get(fib_index, prefix->fp_proto);
599  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
600 
601  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
602  {
603  /*
604  * removing an etry that does not exist. i'll allow it.
605  */
606  }
607  else
608  {
609  fib_entry_src_flag_t src_flag;
610  int was_sourced;
611 
612  /*
613  * if it's not sourced, then there's nowt to remove
614  */
615  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
616  if (!was_sourced)
617  {
618  return;
619  }
620 
621  /*
622  * don't nobody go nowhere
623  */
624  fib_entry_lock(fib_entry_index);
625 
626  for (ii = 0; ii < vec_len(rpath); ii++)
627  {
629  prefix,
630  fib_entry_get_flags_for_source(fib_entry_index,
631  source),
632  &rpath[ii]);
633  }
634 
635  src_flag = fib_entry_path_remove(fib_entry_index, source, rpath);
636 
637  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
638  {
639  /*
640  * last source gone. remove from the table
641  */
642  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
643 
644  /*
645  * now the entry is no longer in the table, we can
646  * inform the entries that it covers to re-calculate their cover
647  */
648  fib_entry_cover_change_notify(fib_entry_index,
650  }
651  /*
652  * else
653  * still has sources, leave it be.
654  */
655  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
656  {
657  fib_table->ft_src_route_counts[source]--;
658  }
659 
660  fib_entry_unlock(fib_entry_index);
661  }
662 }
663 
664 void
666  const fib_prefix_t *prefix,
667  fib_source_t source,
668  dpo_proto_t next_hop_proto,
669  const ip46_address_t *next_hop,
670  u32 next_hop_sw_if_index,
671  u32 next_hop_fib_index,
672  u32 next_hop_weight,
673  fib_route_path_flags_t path_flags)
674 {
675  /*
676  * 1 is it present
677  * yes => remove source
678  * 2 - is it still sourced?
679  * no => cover walk
680  */
681  fib_route_path_t path = {
682  .frp_proto = next_hop_proto,
683  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
684  .frp_sw_if_index = next_hop_sw_if_index,
685  .frp_fib_index = next_hop_fib_index,
686  .frp_weight = next_hop_weight,
687  .frp_flags = path_flags,
688  };
689  fib_route_path_t *paths = NULL;
690 
691  vec_add1(paths, path);
692 
693  fib_table_entry_path_remove2(fib_index, prefix, source, paths);
694 
695  vec_free(paths);
696 }
697 
698 static int
700  void * v2)
701 {
702  return (fib_route_path_cmp(v1, v2));
703 }
704 
707  const fib_prefix_t *prefix,
708  fib_source_t source,
710  fib_route_path_t *paths)
711 {
712  fib_node_index_t fib_entry_index;
713  fib_table_t *fib_table;
714  u32 ii;
715 
716  fib_table = fib_table_get(fib_index, prefix->fp_proto);
717  fib_entry_index = fib_table_lookup_exact_match_i(fib_table, prefix);
718 
719  for (ii = 0; ii < vec_len(paths); ii++)
720  {
721  fib_table_route_path_fixup(prefix, flags, &paths[ii]);
722  }
723  /*
724  * sort the paths provided by the control plane. this means
725  * the paths and the extension on the entry will be sorted.
726  */
728 
729  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
730  {
731  fib_entry_index = fib_entry_create(fib_index, prefix,
732  source, flags,
733  paths);
734 
735  fib_table_entry_insert(fib_table, prefix, fib_entry_index);
736  fib_table->ft_src_route_counts[source]++;
737  }
738  else
739  {
740  int was_sourced;
741 
742  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
743  fib_entry_update(fib_entry_index, source, flags, paths);
744 
745  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
746  {
747  fib_table->ft_src_route_counts[source]++;
748  }
749  }
750 
751  return (fib_entry_index);
752 }
753 
756  const fib_prefix_t *prefix,
757  fib_source_t source,
759  dpo_proto_t next_hop_proto,
760  const ip46_address_t *next_hop,
761  u32 next_hop_sw_if_index,
762  u32 next_hop_fib_index,
763  u32 next_hop_weight,
764  mpls_label_t *next_hop_labels,
765  fib_route_path_flags_t path_flags)
766 {
767  fib_node_index_t fib_entry_index;
768  fib_route_path_t path = {
769  .frp_proto = next_hop_proto,
770  .frp_addr = (NULL == next_hop? zero_addr : *next_hop),
771  .frp_sw_if_index = next_hop_sw_if_index,
772  .frp_fib_index = next_hop_fib_index,
773  .frp_weight = next_hop_weight,
774  .frp_flags = path_flags,
775  .frp_label_stack = next_hop_labels,
776  };
777  fib_route_path_t *paths = NULL;
778 
779  vec_add1(paths, path);
780 
781  fib_entry_index =
782  fib_table_entry_update(fib_index, prefix, source, flags, paths);
783 
784  vec_free(paths);
785 
786  return (fib_entry_index);
787 }
788 
789 static void
791  fib_node_index_t fib_entry_index,
792  const fib_prefix_t *prefix,
793  fib_source_t source)
794 {
795  fib_entry_src_flag_t src_flag;
796  fib_table_t *fib_table;
797  int was_sourced;
798 
799  fib_table = fib_table_get(fib_index, prefix->fp_proto);
800  was_sourced = fib_entry_is_sourced(fib_entry_index, source);
801 
802  /*
803  * don't nobody go nowhere
804  */
805  fib_entry_lock(fib_entry_index);
806 
807  src_flag = fib_entry_delete(fib_entry_index, source);
808 
809  if (!(FIB_ENTRY_SRC_FLAG_ADDED & src_flag))
810  {
811  /*
812  * last source gone. remove from the table
813  */
814  fib_table_entry_remove(fib_table, prefix, fib_entry_index);
815 
816  /*
817  * now the entry is no longer in the table, we can
818  * inform the entries that it covers to re-calculate their cover
819  */
820  fib_entry_cover_change_notify(fib_entry_index,
822  }
823  /*
824  * else
825  * still has sources, leave it be.
826  */
827  if (was_sourced != fib_entry_is_sourced(fib_entry_index, source))
828  {
829  fib_table->ft_src_route_counts[source]--;
830  }
831 
832  fib_entry_unlock(fib_entry_index);
833 }
834 
835 void
837  const fib_prefix_t *prefix,
838  fib_source_t source)
839 {
840  fib_node_index_t fib_entry_index;
841 
842  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
843 
844  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
845  {
846  /*
847  * removing an etry that does not exist.
848  * i'll allow it, but i won't like it.
849  */
850  if (0)
851  clib_warning("%U not in FIB", format_fib_prefix, prefix);
852  }
853  else
854  {
855  fib_table_entry_delete_i(fib_index, fib_entry_index, prefix, source);
856  }
857 }
858 
859 void
861  fib_source_t source)
862 {
863  fib_prefix_t prefix;
864 
865  fib_entry_get_prefix(fib_entry_index, &prefix);
866 
868  fib_entry_index, &prefix, source);
869 }
870 
873  const fib_prefix_t *prefix,
874  mpls_label_t label)
875 {
876  fib_node_index_t fib_entry_index;
877 
878  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
879 
880  if (FIB_NODE_INDEX_INVALID == fib_entry_index ||
881  !fib_entry_is_sourced(fib_entry_index, FIB_SOURCE_MPLS))
882  {
883  /*
884  * only source the prefix once. this allows the label change
885  * operation to work
886  */
887  fib_entry_index = fib_table_entry_special_dpo_add(fib_index, prefix,
890  NULL);
891  }
892 
893  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &label);
894 
895  return (fib_entry_index);
896 }
897 
898 void
900  const fib_prefix_t *prefix,
901  mpls_label_t label)
902 {
903  fib_node_index_t fib_entry_index;
904  const void *data;
905  mpls_label_t pl;
906 
907  fib_entry_index = fib_table_lookup_exact_match(fib_index, prefix);
908 
909  if (FIB_NODE_INDEX_INVALID == fib_entry_index)
910  return;
911 
912  data = fib_entry_get_source_data(fib_entry_index, FIB_SOURCE_MPLS);
913 
914  if (NULL == data)
915  return;
916 
917  pl = *(mpls_label_t*)data;
918 
919  if (pl != label)
920  return;
921 
922  pl = MPLS_LABEL_INVALID;
923 
924  fib_entry_set_source_data(fib_entry_index, FIB_SOURCE_MPLS, &pl);
926  prefix,
928 }
929 
930 u32
932  u32 sw_if_index)
933 {
934  switch (proto)
935  {
936  case FIB_PROTOCOL_IP4:
937  return (ip4_fib_table_get_index_for_sw_if_index(sw_if_index));
938  case FIB_PROTOCOL_IP6:
939  return (ip6_fib_table_get_index_for_sw_if_index(sw_if_index));
940  case FIB_PROTOCOL_MPLS:
941  return (mpls_fib_table_get_index_for_sw_if_index(sw_if_index));
942  }
943  return (~0);
944 }
945 
948  fib_protocol_t proto)
949 {
950  fib_table_t *fib;
951 
952  fib = fib_table_get(fib_index, proto);
953 
954  return (fib->ft_flow_hash_config);
955 }
956 
959 {
960  switch (proto)
961  {
962  case FIB_PROTOCOL_IP4:
963  case FIB_PROTOCOL_IP6:
964  return (IP_FLOW_HASH_DEFAULT);
965 
966  case FIB_PROTOCOL_MPLS:
967  return (MPLS_FLOW_HASH_DEFAULT);
968  }
969 
970  ASSERT(0);
971  return (IP_FLOW_HASH_DEFAULT);
972 }
973 
974 /**
975  * @brief Table set flow hash config context.
976  */
978 {
979  /**
980  * the flow hash config to set
981  */
984 
985 static int
987  void *arg)
988 {
990 
991  fib_entry_set_flow_hash_config(fib_entry_index, ctx->hash_config);
992 
993  return (1);
994 }
995 
996 void
998  fib_protocol_t proto,
1000 {
1002  .hash_config = hash_config,
1003  };
1004  fib_table_t *fib;
1005 
1006  fib = fib_table_get(fib_index, proto);
1008 
1009  fib_table_walk(fib_index, proto,
1011  &ctx);
1012 }
1013 
1014 u32
1016  u32 sw_if_index)
1017 {
1018  fib_table_t *fib_table;
1019 
1021  proto, sw_if_index),
1022  proto);
1023 
1024  return ((NULL != fib_table ? fib_table->ft_table_id : ~0));
1025 }
1026 
1027 u32
1029  u32 table_id)
1030 {
1031  switch (proto)
1032  {
1033  case FIB_PROTOCOL_IP4:
1034  return (ip4_fib_index_from_table_id(table_id));
1035  case FIB_PROTOCOL_IP6:
1036  return (ip6_fib_index_from_table_id(table_id));
1037  case FIB_PROTOCOL_MPLS:
1038  return (mpls_fib_index_from_table_id(table_id));
1039  }
1040  return (~0);
1041 }
1042 
1043 static u32
1045  u32 table_id,
1046  fib_source_t src,
1047  const u8 *name)
1048 {
1049  fib_table_t *fib_table;
1050  fib_node_index_t fi;
1051 
1052  switch (proto)
1053  {
1054  case FIB_PROTOCOL_IP4:
1055  fi = ip4_fib_table_find_or_create_and_lock(table_id, src);
1056  break;
1057  case FIB_PROTOCOL_IP6:
1058  fi = ip6_fib_table_find_or_create_and_lock(table_id, src);
1059  break;
1060  case FIB_PROTOCOL_MPLS:
1061  fi = mpls_fib_table_find_or_create_and_lock(table_id, src);
1062  break;
1063  default:
1064  return (~0);
1065  }
1066 
1067  fib_table = fib_table_get(fi, proto);
1068 
1069  if (NULL == fib_table->ft_desc)
1070  {
1071  if (name && name[0])
1072  {
1073  fib_table->ft_desc = format(NULL, "%s", name);
1074  }
1075  else
1076  {
1077  fib_table->ft_desc = format(NULL, "%U-VRF:%d",
1078  format_fib_protocol, proto,
1079  table_id);
1080  }
1081  }
1082 
1083  return (fi);
1084 }
1085 
1086 u32
1088  u32 table_id,
1089  fib_source_t src)
1090 {
1091  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1092  src, NULL));
1093 }
1094 
1095 u32
1097  u32 table_id,
1098  fib_source_t src,
1099  const u8 *name)
1100 {
1101  return (fib_table_find_or_create_and_lock_i(proto, table_id,
1102  src, name));
1103 }
1104 
1105 u32
1107  fib_source_t src,
1108  const char *const fmt,
1109  ...)
1110 {
1111  fib_table_t *fib_table;
1112  fib_node_index_t fi;
1113  va_list ap;
1114 
1115  va_start(ap, fmt);
1116 
1117  switch (proto)
1118  {
1119  case FIB_PROTOCOL_IP4:
1121  break;
1122  case FIB_PROTOCOL_IP6:
1124  break;
1125  case FIB_PROTOCOL_MPLS:
1127  break;
1128  default:
1129  return (~0);
1130  }
1131 
1132  fib_table = fib_table_get(fi, proto);
1133 
1134  fib_table->ft_desc = va_format(fib_table->ft_desc, fmt, &ap);
1135 
1136  va_end(ap);
1137  return (fi);
1138 }
1139 
1140 static void
1142 {
1143  vec_free(fib_table->ft_desc);
1144 
1145  switch (fib_table->ft_proto)
1146  {
1147  case FIB_PROTOCOL_IP4:
1148  ip4_fib_table_destroy(fib_table->ft_index);
1149  break;
1150  case FIB_PROTOCOL_IP6:
1151  ip6_fib_table_destroy(fib_table->ft_index);
1152  break;
1153  case FIB_PROTOCOL_MPLS:
1154  mpls_fib_table_destroy(fib_table->ft_index);
1155  break;
1156  }
1157 }
1158 
1159 void
1160 fib_table_walk (u32 fib_index,
1161  fib_protocol_t proto,
1163  void *ctx)
1164 {
1165  switch (proto)
1166  {
1167  case FIB_PROTOCOL_IP4:
1168  ip4_fib_table_walk(ip4_fib_get(fib_index), fn, ctx);
1169  break;
1170  case FIB_PROTOCOL_IP6:
1171  ip6_fib_table_walk(fib_index, fn, ctx);
1172  break;
1173  case FIB_PROTOCOL_MPLS:
1174  mpls_fib_table_walk(mpls_fib_get(fib_index), fn, ctx);
1175  break;
1176  }
1177 }
1178 
1179 void
1181  fib_protocol_t proto,
1182  fib_source_t source)
1183 {
1184  fib_table_t *fib_table;
1185 
1186  fib_table = fib_table_get(fib_index, proto);
1187  fib_table->ft_locks[source]--;
1188  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]--;
1189 
1190  if (0 == fib_table->ft_locks[source])
1191  {
1192  /*
1193  * The source no longer needs the table. flush any routes
1194  * from it just in case
1195  */
1196  fib_table_flush(fib_index, proto, source);
1197  }
1198 
1199  if (0 == fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS])
1200  {
1201  /*
1202  * no more locak from any source - kill it
1203  */
1204  fib_table_destroy(fib_table);
1205  }
1206 }
1207 
1208 void
1209 fib_table_lock (u32 fib_index,
1210  fib_protocol_t proto,
1211  fib_source_t source)
1212 {
1213  fib_table_t *fib_table;
1214 
1215  fib_table = fib_table_get(fib_index, proto);
1216  fib_table->ft_locks[source]++;
1217  fib_table->ft_locks[FIB_TABLE_TOTAL_LOCKS]++;
1218 }
1219 
1220 u32
1222  fib_protocol_t proto,
1223  fib_source_t source)
1224 {
1225  fib_table_t *fib_table;
1226 
1227  fib_table = fib_table_get(fib_index, proto);
1228 
1229  return (fib_table->ft_src_route_counts[source]);
1230 }
1231 
1232 u8*
1233 format_fib_table_name (u8* s, va_list* ap)
1234 {
1235  fib_node_index_t fib_index = va_arg(*ap, fib_node_index_t);
1236  fib_protocol_t proto = va_arg(*ap, int); // int promotion
1237  fib_table_t *fib_table;
1238 
1239  fib_table = fib_table_get(fib_index, proto);
1240 
1241  s = format(s, "%v", fib_table->ft_desc);
1242 
1243  return (s);
1244 }
1245 
1246 /**
1247  * @brief Table flush context. Store the indicies of matching FIB entries
1248  * that need to be removed.
1249  */
1251 {
1252  /**
1253  * The list of entries to flush
1254  */
1256 
1257  /**
1258  * The source we are flushing
1259  */
1262 
1263 static int
1265  void *arg)
1266 {
1267  fib_table_flush_ctx_t *ctx = arg;
1268 
1269  if (fib_entry_is_sourced(fib_entry_index, ctx->ftf_source))
1270  {
1271  vec_add1(ctx->ftf_entries, fib_entry_index);
1272  }
1273  return (1);
1274 }
1275 
1276 
1277 void
1279  fib_protocol_t proto,
1280  fib_source_t source)
1281 {
1282  fib_node_index_t *fib_entry_index;
1284  .ftf_entries = NULL,
1285  .ftf_source = source,
1286  };
1287 
1288  fib_table_walk(fib_index, proto,
1290  &ctx);
1291 
1292  vec_foreach(fib_entry_index, ctx.ftf_entries)
1293  {
1294  fib_table_entry_delete_index(*fib_entry_index, source);
1295  }
1296 
1297  vec_free(ctx.ftf_entries);
1298 }
1299 
1300 u8 *
1301 format_fib_table_memory (u8 *s, va_list *args)
1302 {
1303  s = format(s, "%U", format_ip4_fib_table_memory);
1304  s = format(s, "%U", format_ip6_fib_table_memory);
1305  s = format(s, "%U", format_mpls_fib_table_memory);
1306 
1307  return (s);
1308 }
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:342
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:181
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1556
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:393
void fib_entry_unlock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1517
fib_protocol_t ft_proto
Which protocol this table serves.
Definition: fib_table.h:40
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:377
int fib_route_path_cmp(const fib_route_path_t *rpath1, const fib_route_path_t *rpath2)
Definition: fib_types.c:188
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:1260
A Drop path - resolve the path on the drop DPO.
Definition: fib_types.h:309
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:1404
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:899
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:836
void fib_entry_get_prefix(fib_node_index_t fib_entry_index, fib_prefix_t *pfx)
Definition: fib_entry.c:1546
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:1096
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:706
#define NULL
Definition: clib.h:55
int(* 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:798
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:539
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:931
u8 * format_ip6_fib_table_memory(u8 *s, va_list *args)
Definition: ip6_fib.c:528
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:258
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
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
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, 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:755
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:382
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:261
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:80
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:899
int fib_prefix_is_host(const fib_prefix_t *prefix)
Return true is the prefix is a host prefix.
Definition: fib_types.c:136
static void vlib_smp_unsafe_warning(void)
Definition: threads.h:227
u8 * format_fib_protocol(u8 *s, va_list *ap)
Definition: fib_types.c:30
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:947
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:466
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:958
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:247
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:814
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:412
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:390
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:151
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:1278
Aggregrate type for a prefix.
Definition: fib_types.h:172
static int fib_table_flush_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:1264
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1028
u16 fp_len
The mask length.
Definition: fib_types.h:176
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:355
Definition: fib_entry.h:238
static u32 mpls_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: mpls_fib.h:132
MPLS label.
Definition: fib_entry.h:106
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:166
Definition: fib_entry.h:243
Definition: fib_entry.h:242
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:199
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:459
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:369
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:195
u16 ft_locks[FIB_TABLE_N_LOCKS]
per-source number of locks on the table
Definition: fib_table.h:45
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:161
#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:399
u32 ip6_fib_table_create_and_lock(fib_source_t src)
Definition: ip6_fib.c:102
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:583
u32 ft_total_route_counts
Total route counters.
Definition: fib_table.h:70
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:1221
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:1084
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:704
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:1180
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:457
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:87
void ip6_fib_table_entry_remove(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:286
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:790
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:371
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:55
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)
Definition: fib_entry_src.c:99
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:329
void ip6_fib_table_destroy(u32 fib_index)
Definition: ip6_fib.c:108
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:872
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:234
mpls_main_t mpls_main
Definition: mpls.c:25
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:50
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:860
u32 ft_flow_hash_config
flow hash configuration
Definition: fib_table.h:60
static void fib_table_destroy(fib_table_t *fib_table)
Definition: fib_table.c:1141
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:48
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
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:836
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:105
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:997
u8 * ft_desc
Table description.
Definition: fib_table.h:75
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:241
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:982
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
u8 * format_fib_table_memory(u8 *s, va_list *args)
format (display) the memory used by the FIB tables
Definition: fib_table.c:1301
static int fib_route_path_cmp_for_sort(void *v1, void *v2)
Definition: fib_table.c:699
Don&#39;t resolve the path, use the DPO the client provides.
Definition: fib_types.h:313
static u32 ip4_fib_index_from_table_id(u32 table_id)
Definition: ip4_fib.h:137
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
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:1209
mpls_label_t fp_label
Definition: fib_types.h:198
void fib_entry_lock(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1507
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:290
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:1015
#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
unsigned int u32
Definition: types.h:88
static mpls_fib_t * mpls_fib_get(fib_node_index_t index)
Definition: mpls_fib.h:57
ip6_main_t ip6_main
Definition: ip6_forward.c:3009
long ctx[MAX_CONNS]
Definition: main.c:122
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:1160
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:1087
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:469
Definition: fib_entry.h:280
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:211
u32 ft_src_route_counts[FIB_SOURCE_MAX]
Per-source route counters.
Definition: fib_table.h:65
#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:497
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:665
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:1044
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:667
static int fib_table_set_flow_hash_config_cb(fib_node_index_t fib_entry_index, void *arg)
Definition: fib_table.c:986
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
A for-us/local path.
Definition: fib_types.h:301
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
fib_node_index_t * ftf_entries
The list of entries to flush.
Definition: fib_table.c:1255
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:956
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:317
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:193
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:1096
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:1233
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1181
Table set flow hash config context.
Definition: fib_table.c:977
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:201
struct fib_table_flush_ctx_t_ fib_table_flush_ctx_t
Table flush context.
Attached path.
Definition: fib_types.h:305
Table flush context.
Definition: fib_table.c:1250
u32 flags
Definition: vhost-user.h:77
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:81
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:1106
struct fib_table_t_ * fibs
Definition: ip6.h:161
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:793
const ip46_address_t zero_addr
Definition: lookup.c:359
fib_entry_src_flag_t fib_entry_special_remove(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry.c:996
A protocol Independent FIB table.
Definition: fib_table.h:35
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, 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:505
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:199