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