FD.io VPP  v21.01.1
Vector Packet Processing
ip6_fib.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 <vnet/fib/ip6_fib.h>
17 #include <vnet/fib/fib_table.h>
18 #include <vnet/dpo/ip6_ll_dpo.h>
19 
20 #include <vppinfra/bihash_24_8.h>
22 
24 
25 /* ip6 lookup table config parameters */
28 
29 static void
31 {
32  fib_prefix_t pfx = {
34  .fp_len = 0,
35  .fp_addr = {
36  .ip6 = {
37  { 0, 0, },
38  },
39  }
40  };
41 
42  /*
43  * Add the default route.
44  */
46  &pfx,
49 
50  /*
51  * all link local via the link local lookup DPO
52  */
53  pfx.fp_addr.ip6.as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL);
54  pfx.fp_addr.ip6.as_u64[1] = 0;
55  pfx.fp_len = 10;
57  &pfx,
60  ip6_ll_dpo_get());
61 }
62 
63 static u32
67  u8 *desc)
68 {
69  fib_table_t *fib_table;
70  ip6_fib_t *v6_fib;
71 
72  pool_get(ip6_main.fibs, fib_table);
74 
75  clib_memset(fib_table, 0, sizeof(*fib_table));
76  clib_memset(v6_fib, 0, sizeof(*v6_fib));
77 
78  ASSERT((fib_table - ip6_main.fibs) ==
79  (v6_fib - ip6_main.v6_fibs));
80 
81  fib_table->ft_proto = FIB_PROTOCOL_IP6;
82  fib_table->ft_index =
83  v6_fib->index =
84  (fib_table - ip6_main.fibs);
85 
86  hash_set(ip6_main.fib_index_by_table_id, table_id, fib_table->ft_index);
87 
88  fib_table->ft_table_id =
89  v6_fib->table_id =
90  table_id;
92  fib_table->ft_flags = flags;
93  fib_table->ft_desc = desc;
94 
95  vnet_ip6_fib_init(fib_table->ft_index);
96  fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP6, src);
97 
98  return (fib_table->ft_index);
99 }
100 
101 u32
104 {
105  uword * p;
106 
107  p = hash_get (ip6_main.fib_index_by_table_id, table_id);
108  if (NULL == p)
109  return create_fib_with_table_id(table_id, src,
111  NULL);
112 
113  fib_table_lock(p[0], FIB_PROTOCOL_IP6, src);
114 
115  return (p[0]);
116 }
117 
118 u32
121  u8 *desc)
122 {
123  return (create_fib_with_table_id(~0, src, flags, desc));
124 }
125 
126 void
128 {
129  /*
130  * all link local first ...
131  */
132  fib_prefix_t pfx = {
134  .fp_len = 10,
135  .fp_addr = {
136  .ip6 = {
137  .as_u8 = {
138  [0] = 0xFE,
139  [1] = 0x80,
140  },
141  },
142  }
143  };
144  fib_table_entry_delete(fib_index,
145  &pfx,
147 
148  /*
149  * ... then the default route.
150  */
151  pfx.fp_addr.ip6.as_u64[0] = 0;
152  pfx.fp_len = 00;
154  &pfx,
156 
157  fib_table_t *fib_table = fib_table_get(fib_index, FIB_PROTOCOL_IP6);
158  fib_source_t source;
159 
160  /*
161  * validate no more routes.
162  */
163 #if CLIB_DEBUG > 0
164  if (0 != fib_table->ft_total_route_counts)
165  fib_table_assert_empty(fib_table);
166 #endif
167 
168  vec_foreach_index(source, fib_table->ft_src_route_counts)
169  {
170  ASSERT(0 == fib_table->ft_src_route_counts[source]);
171  }
172 
173  if (~0 != fib_table->ft_table_id)
174  {
176  }
177  vec_free(fib_table->ft_src_route_counts);
179  pool_put(ip6_main.fibs, fib_table);
180 }
181 
184  const ip6_address_t *addr,
185  u32 len)
186 {
189  int i, n_p, rv;
190  u64 fib;
191 
192  table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
194 
195  kv.key[0] = addr->as_u64[0];
196  kv.key[1] = addr->as_u64[1];
197  fib = ((u64)((fib_index))<<32);
198 
199  /*
200  * start search from a mask length same length or shorter.
201  * we don't want matches longer than the mask passed
202  */
203  i = 0;
204  while (i < n_p && table->prefix_lengths_in_search_order[i] > len)
205  {
206  i++;
207  }
208 
209  for (; i < n_p; i++)
210  {
211  int dst_address_length = table->prefix_lengths_in_search_order[i];
212  ip6_address_t * mask = &ip6_main.fib_masks[dst_address_length];
213 
214  ASSERT(dst_address_length >= 0 && dst_address_length <= 128);
215  //As lengths are decreasing, masks are increasingly specific.
216  kv.key[0] &= mask->as_u64[0];
217  kv.key[1] &= mask->as_u64[1];
218  kv.key[2] = fib | dst_address_length;
219 
220  rv = clib_bihash_search_inline_2_24_8(&table->ip6_hash, &kv, &value);
221  if (rv == 0)
222  return value.value;
223  }
224 
225  return (FIB_NODE_INDEX_INVALID);
226 }
227 
230  const ip6_address_t *addr,
231  u32 len)
232 {
235  ip6_address_t *mask;
236  u64 fib;
237  int rv;
238 
239  table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
240  mask = &ip6_main.fib_masks[len];
241  fib = ((u64)((fib_index))<<32);
242 
243  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
244  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
245  kv.key[2] = fib | len;
246 
247  rv = clib_bihash_search_inline_2_24_8(&table->ip6_hash, &kv, &value);
248  if (rv == 0)
249  return value.value;
250 
251  return (FIB_NODE_INDEX_INVALID);
252 }
253 
254 static void
256 {
257  u8 *old, *prefix_lengths_in_search_order = NULL;
258  int i;
259 
260  /*
261  * build the list in a scratch space then cutover so the workers
262  * can continue uninterrupted.
263  */
264  old = table->prefix_lengths_in_search_order;
265 
266  /* Note: bitmap reversed so this is in fact a longest prefix match */
268  {
269  int dst_address_length = 128 - i;
270  vec_add1(prefix_lengths_in_search_order, dst_address_length);
271  }
272 
273  table->prefix_lengths_in_search_order = prefix_lengths_in_search_order;
274 
275  /*
276  * let the workers go once round the track before we free the old set
277  */
279  vec_free(old);
280 }
281 
282 void
284  const ip6_address_t *addr,
285  u32 len)
286 {
289  ip6_address_t *mask;
290  u64 fib;
291 
292  table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
293  mask = &ip6_main.fib_masks[len];
294  fib = ((u64)((fib_index))<<32);
295 
296  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
297  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
298  kv.key[2] = fib | len;
299 
300  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 0);
301 
302  /* refcount accounting */
303  ASSERT (table->dst_address_length_refcounts[len] > 0);
304  if (--table->dst_address_length_refcounts[len] == 0)
305  {
308  128 - len, 0);
310  }
311 }
312 
313 void
315  const ip6_address_t *addr,
316  u32 len,
317  fib_node_index_t fib_entry_index)
318 {
321  ip6_address_t *mask;
322  u64 fib;
323 
324  table = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING];
325  mask = &ip6_main.fib_masks[len];
326  fib = ((u64)((fib_index))<<32);
327 
328  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
329  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
330  kv.key[2] = fib | len;
331  kv.value = fib_entry_index;
332 
333  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 1);
334 
335  if (0 == table->dst_address_length_refcounts[len]++)
336  {
339  128 - len, 1);
341  }
342 }
343 
346  const ip6_address_t * dst)
347 {
348  u32 fib_index = vec_elt (im->fib_index_by_sw_if_index, sw_if_index);
349  return ip6_fib_table_fwding_lookup(fib_index, dst);
350 }
351 
352 u32
354 {
355  if (sw_if_index >= vec_len(ip6_main.fib_index_by_sw_if_index))
356  {
357  /*
358  * This is the case for interfaces that are not yet mapped to
359  * a IP table
360  */
361  return (~0);
362  }
363  return (ip6_main.fib_index_by_sw_if_index[sw_if_index]);
364 }
365 
366 void
368  const ip6_address_t *addr,
369  u32 len,
370  const dpo_id_t *dpo)
371 {
374  ip6_address_t *mask;
375  u64 fib;
376 
377  table = &ip6_fib_table[IP6_FIB_TABLE_FWDING];
378  mask = &ip6_main.fib_masks[len];
379  fib = ((u64)((fib_index))<<32);
380 
381  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
382  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
383  kv.key[2] = fib | len;
384  kv.value = dpo->dpoi_index;
385 
386  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 1);
387 
388  if (0 == table->dst_address_length_refcounts[len]++)
389  {
392  128 - len, 1);
394  }
395 }
396 
397 void
399  const ip6_address_t *addr,
400  u32 len,
401  const dpo_id_t *dpo)
402 {
405  ip6_address_t *mask;
406  u64 fib;
407 
408  table = &ip6_fib_table[IP6_FIB_TABLE_FWDING];
409  mask = &ip6_main.fib_masks[len];
410  fib = ((u64)((fib_index))<<32);
411 
412  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
413  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
414  kv.key[2] = fib | len;
415  kv.value = dpo->dpoi_index;
416 
417  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 0);
418 
419  /* refcount accounting */
420  ASSERT (table->dst_address_length_refcounts[len] > 0);
421  if (--table->dst_address_length_refcounts[len] == 0)
422  {
425  128 - len, 0);
427  }
428 }
429 
430 /**
431  * @brief Context when walking the IPv6 table. Since all VRFs are in the
432  * same hash table, we need to filter only those we need as we walk
433  */
434 typedef struct ip6_fib_walk_ctx_t_
435 {
438  void *i6w_ctx;
442 
443 static int
445  void *arg)
446 {
447  ip6_fib_walk_ctx_t *ctx = arg;
448  ip6_address_t key;
449 
450  if ((kvp->key[2] >> 32) == ctx->i6w_fib_index)
451  {
452  key.as_u64[0] = kvp->key[0];
453  key.as_u64[1] = kvp->key[1];
454 
456  &key,
457  &ctx->i6w_root.fp_addr.ip6,
458  ctx->i6w_root.fp_len))
459  {
460  const fib_prefix_t *sub_tree;
461  int skip = 0;
462 
463  /*
464  * exclude sub-trees the walk does not want to explore
465  */
466  vec_foreach(sub_tree, ctx->i6w_sub_trees)
467  {
469  &key,
470  &sub_tree->fp_addr.ip6,
471  sub_tree->fp_len))
472  {
473  skip = 1;
474  break;
475  }
476  }
477 
478  if (!skip)
479  {
480  switch (ctx->i6w_fn(kvp->value, ctx->i6w_ctx))
481  {
483  break;
485  fib_prefix_t pfx = {
487  .fp_len = kvp->key[2] & 0xffffffff,
488  .fp_addr.ip6 = key,
489  };
490  vec_add1(ctx->i6w_sub_trees, pfx);
491  break;
492  }
493  case FIB_TABLE_WALK_STOP:
494  goto done;
495  }
496  }
497  }
498  }
499 done:
500 
501  return (1);
502 }
503 
504 void
507  void *arg)
508 {
510  .i6w_fib_index = fib_index,
511  .i6w_fn = fn,
512  .i6w_ctx = arg,
513  .i6w_root = {
514  .fp_proto = FIB_PROTOCOL_IP6,
515  },
516  .i6w_sub_trees = NULL,
517  };
518 
519  clib_bihash_foreach_key_value_pair_24_8(
520  &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
522  &ctx);
523 
524  vec_free(ctx.i6w_sub_trees);
525 }
526 
527 void
529  const fib_prefix_t *root,
531  void *arg)
532 {
534  .i6w_fib_index = fib_index,
535  .i6w_fn = fn,
536  .i6w_ctx = arg,
537  .i6w_root = *root,
538  };
539 
540  clib_bihash_foreach_key_value_pair_24_8(
541  &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
543  &ctx);
544 }
545 
546 typedef struct ip6_fib_show_ctx_t_ {
549 
550 static fib_table_walk_rc_t
552  void *arg)
553 {
554  ip6_fib_show_ctx_t *ctx = arg;
555 
556  vec_add1(ctx->entries, fib_entry_index);
557 
558  return (FIB_TABLE_WALK_CONTINUE);
559 }
560 
561 static void
563  vlib_main_t * vm)
564 {
565  fib_node_index_t *fib_entry_index;
567  .entries = NULL,
568  };
569 
572 
573  vec_foreach(fib_entry_index, ctx.entries)
574  {
575  vlib_cli_output(vm, "%U",
577  *fib_entry_index,
579  }
580 
581  vec_free(ctx.entries);
582 }
583 
584 static void
586  vlib_main_t * vm,
587  ip6_address_t *address,
588  u32 mask_len,
589  int detail)
590 {
591  vlib_cli_output(vm, "%U",
593  ip6_fib_table_lookup(fib->index, address, mask_len),
594  (detail ?
597 }
598 
599 u8 *
600 format_ip6_fib_table_memory (u8 * s, va_list * args)
601 {
602  uword bytes_inuse;
603 
604  bytes_inuse = (alloc_arena_next(&(ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash)) +
605  alloc_arena_next(&(ip6_fib_table[IP6_FIB_TABLE_FWDING].ip6_hash)));
606 
607  s = format(s, "%=30s %=6d %=12ld\n",
608  "IPv6 unicast",
610  bytes_inuse);
611  return (s);
612 }
613 
614 typedef struct {
616  u64 count_by_prefix_length[129];
618 
619 static int
621  void *arg)
622 {
624  int mask_width;
625 
626  if ((kvp->key[2]>>32) != ap->fib_index)
627  return (BIHASH_WALK_CONTINUE);
628 
629  mask_width = kvp->key[2] & 0xFF;
630 
632 
633  return (BIHASH_WALK_CONTINUE);
634 }
635 
636 static clib_error_t *
638  unformat_input_t * input,
639  vlib_cli_command_t * cmd)
640 {
642  ip6_main_t * im6 = &ip6_main;
643  fib_table_t *fib_table;
644  ip6_fib_t * fib;
645  int verbose, matching;
646  ip6_address_t matching_address;
647  u32 mask_len = 128;
648  int table_id = -1, fib_index = ~0;
649  int detail = 0;
650  int hash = 0;
651 
652  verbose = 1;
653  matching = 0;
654 
656  {
657  if (unformat (input, "brief") ||
658  unformat (input, "summary") ||
659  unformat (input, "sum"))
660  verbose = 0;
661 
662  else if (unformat (input, "detail") ||
663  unformat (input, "det"))
664  detail = 1;
665 
666  else if (unformat (input, "hash") ||
667  unformat (input, "mem") ||
668  unformat (input, "memory"))
669  hash = 1;
670 
671  else if (unformat (input, "%U/%d",
672  unformat_ip6_address, &matching_address, &mask_len))
673  matching = 1;
674 
675  else if (unformat (input, "%U", unformat_ip6_address, &matching_address))
676  matching = 1;
677 
678  else if (unformat (input, "table %d", &table_id))
679  ;
680  else if (unformat (input, "index %d", &fib_index))
681  ;
682  else
683  break;
684  }
685 
686  if (hash)
687  {
688  vlib_cli_output (vm, "IPv6 Non-Forwarding Hash Table:\n%U\n",
689  BV (format_bihash),
690  &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
691  detail);
692  vlib_cli_output (vm, "IPv6 Forwarding Hash Table:\n%U\n",
693  BV (format_bihash),
694  &ip6_fib_table[IP6_FIB_TABLE_FWDING].ip6_hash,
695  detail);
696  return (NULL);
697  }
698 
699  pool_foreach (fib_table, im6->fibs)
700  {
701  fib_source_t source;
702  u8 *s = NULL;
703 
704  fib = pool_elt_at_index(im6->v6_fibs, fib_table->ft_index);
705  if (table_id >= 0 && table_id != (int)fib->table_id)
706  continue;
707  if (fib_index != ~0 && fib_index != (int)fib->index)
708  continue;
709  if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
710  continue;
711 
712  s = format(s, "%U, fib_index:%d, flow hash:[%U] epoch:%d flags:%U locks:[",
715  fib->index,
717  fib_table->ft_flow_hash_config,
718  fib_table->ft_epoch,
719  format_fib_table_flags, fib_table->ft_flags);
720 
721  vec_foreach_index(source, fib_table->ft_locks)
722  {
723  if (0 != fib_table->ft_locks[source])
724  {
725  s = format(s, "%U:%d, ",
726  format_fib_source, source,
727  fib_table->ft_locks[source]);
728  }
729  }
730  s = format (s, "]");
731  vlib_cli_output (vm, "%v", s);
732  vec_free(s);
733 
734  /* Show summary? */
735  if (! verbose)
736  {
737  clib_bihash_24_8_t * h = &ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash;
738  int len;
739 
740  vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count");
741 
742  clib_memset (ca, 0, sizeof(*ca));
743  ca->fib_index = fib->index;
744 
745  clib_bihash_foreach_key_value_pair_24_8
747 
748  for (len = 128; len >= 0; len--)
749  {
750  if (ca->count_by_prefix_length[len])
751  vlib_cli_output (vm, "%=20d%=16lld",
752  len, ca->count_by_prefix_length[len]);
753  }
754  continue;
755  }
756 
757  if (!matching)
758  {
759  ip6_fib_table_show_all(fib, vm);
760  }
761  else
762  {
763  ip6_fib_table_show_one(fib, vm, &matching_address, mask_len, detail);
764  }
765  }
766 
767  return 0;
768 }
769 
770 /*?
771  * This command displays the IPv6 FIB Tables (VRF Tables) and the route
772  * entries for each table.
773  *
774  * @note This command will run for a long time when the FIB tables are
775  * comprised of millions of entries. For those senarios, consider displaying
776  * in summary mode.
777  *
778  * @cliexpar
779  * @parblock
780  * Example of how to display all the IPv6 FIB tables:
781  * @cliexstart{show ip6 fib}
782  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
783  * @::/0
784  * unicast-ip6-chain
785  * [@0]: dpo-load-balance: [index:5 buckets:1 uRPF:5 to:[0:0]]
786  * [0] [@0]: dpo-drop ip6
787  * fe80::/10
788  * unicast-ip6-chain
789  * [@0]: dpo-load-balance: [index:10 buckets:1 uRPF:10 to:[0:0]]
790  * [0] [@2]: dpo-receive
791  * ff02::1/128
792  * unicast-ip6-chain
793  * [@0]: dpo-load-balance: [index:8 buckets:1 uRPF:8 to:[0:0]]
794  * [0] [@2]: dpo-receive
795  * ff02::2/128
796  * unicast-ip6-chain
797  * [@0]: dpo-load-balance: [index:7 buckets:1 uRPF:7 to:[0:0]]
798  * [0] [@2]: dpo-receive
799  * ff02::16/128
800  * unicast-ip6-chain
801  * [@0]: dpo-load-balance: [index:9 buckets:1 uRPF:9 to:[0:0]]
802  * [0] [@2]: dpo-receive
803  * ff02::1:ff00:0/104
804  * unicast-ip6-chain
805  * [@0]: dpo-load-balance: [index:6 buckets:1 uRPF:6 to:[0:0]]
806  * [0] [@2]: dpo-receive
807  * ipv6-VRF:8, fib_index 1, flow hash: src dst sport dport proto
808  * @::/0
809  * unicast-ip6-chain
810  * [@0]: dpo-load-balance: [index:21 buckets:1 uRPF:20 to:[0:0]]
811  * [0] [@0]: dpo-drop ip6
812  * @::a:1:1:0:4/126
813  * unicast-ip6-chain
814  * [@0]: dpo-load-balance: [index:27 buckets:1 uRPF:26 to:[0:0]]
815  * [0] [@4]: ipv6-glean: af_packet0
816  * @::a:1:1:0:7/128
817  * unicast-ip6-chain
818  * [@0]: dpo-load-balance: [index:28 buckets:1 uRPF:27 to:[0:0]]
819  * [0] [@2]: dpo-receive: @::a:1:1:0:7 on af_packet0
820  * fe80::/10
821  * unicast-ip6-chain
822  * [@0]: dpo-load-balance: [index:26 buckets:1 uRPF:25 to:[0:0]]
823  * [0] [@2]: dpo-receive
824  * fe80::fe:3eff:fe3e:9222/128
825  * unicast-ip6-chain
826  * [@0]: dpo-load-balance: [index:29 buckets:1 uRPF:28 to:[0:0]]
827  * [0] [@2]: dpo-receive: fe80::fe:3eff:fe3e:9222 on af_packet0
828  * ff02::1/128
829  * unicast-ip6-chain
830  * [@0]: dpo-load-balance: [index:24 buckets:1 uRPF:23 to:[0:0]]
831  * [0] [@2]: dpo-receive
832  * ff02::2/128
833  * unicast-ip6-chain
834  * [@0]: dpo-load-balance: [index:23 buckets:1 uRPF:22 to:[0:0]]
835  * [0] [@2]: dpo-receive
836  * ff02::16/128
837  * unicast-ip6-chain
838  * [@0]: dpo-load-balance: [index:25 buckets:1 uRPF:24 to:[0:0]]
839  * [0] [@2]: dpo-receive
840  * ff02::1:ff00:0/104
841  * unicast-ip6-chain
842  * [@0]: dpo-load-balance: [index:22 buckets:1 uRPF:21 to:[0:0]]
843  * [0] [@2]: dpo-receive
844  * @cliexend
845  *
846  * Example of how to display a summary of all IPv6 FIB tables:
847  * @cliexstart{show ip6 fib summary}
848  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
849  * Prefix length Count
850  * 128 3
851  * 104 1
852  * 10 1
853  * 0 1
854  * ipv6-VRF:8, fib_index 1, flow hash: src dst sport dport proto
855  * Prefix length Count
856  * 128 5
857  * 126 1
858  * 104 1
859  * 10 1
860  * 0 1
861  * @cliexend
862  * @endparblock
863  ?*/
864 /* *INDENT-OFF* */
865 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
866  .path = "show ip6 fib",
867  .short_help = "show ip6 fib [summary] [table <table-id>] [index <fib-id>] [<ip6-addr>[/<width>]] [detail]",
868  .function = ip6_show_fib,
869 };
870 /* *INDENT-ON* */
871 
872 static clib_error_t *
874 {
875  uword heapsize = 0;
876  u32 nbuckets = 0;
877 
879  {
880  if (unformat (input, "hash-buckets %d", &nbuckets))
881  ;
882  else if (unformat (input, "heap-size %U",
883  unformat_memory_size, &heapsize))
884  ;
885  else
886  return clib_error_return (0, "unknown input '%U'",
887  format_unformat_error, input);
888  }
889 
890  ip6_fib_table_nbuckets = nbuckets;
891  ip6_fib_table_size = heapsize;
892 
893  return 0;
894 }
895 
897 
898 static clib_error_t *
900 {
901  if (ip6_fib_table_nbuckets == 0)
903 
905 
906  if (ip6_fib_table_size == 0)
908 
909  clib_bihash_init_24_8 (&(ip6_fib_table[IP6_FIB_TABLE_FWDING].ip6_hash),
910  "ip6 FIB fwding table",
912  clib_bihash_init_24_8 (&ip6_fib_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash,
913  "ip6 FIB non-fwding table",
915 
916  return (NULL);
917 }
918 
920 {
921  .runs_before = VLIB_INITS("ip6_lookup_init"),
922 };
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:211
u8 * format_fib_entry(u8 *s, va_list *args)
Definition: fib_entry.c:130
enum fib_source_t_ fib_source_t
The different sources that can create a route.
#define vec_foreach_index(var, v)
Iterate over vector indices.
Continue on to the next entry.
Definition: fib_table.h:916
#define hash_set(h, key, value)
Definition: hash.h:255
void vlib_worker_wait_one_loop(void)
Wait until each of the workers has been once around the track.
Definition: threads.c:1673
fib_protocol_t ft_proto
Which protocol this table serves.
Definition: fib_table.h:76
The table that stores ALL routes learned by the DP.
Definition: ip6_fib.h:50
static u32 ip6_fib_table_fwding_lookup(u32 fib_index, const ip6_address_t *dst)
Definition: ip6_fib.h:115
ip6_fib_t * v6_fibs
Definition: ip6.h:118
#define hash_unset(h, key)
Definition: hash.h:261
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
uword ip6_fib_table_size
Definition: ip6_fib.c:27
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
#define IP6_FIB_DEFAULT_HASH_MEMORY_SIZE
Definition: ip6_fib.h:32
#define FIB_ENTRY_FORMAT_DETAIL
Definition: fib_entry.h:360
unsigned long u64
Definition: types.h:89
static fib_table_walk_rc_t ip6_fib_table_show_walk(fib_node_index_t fib_entry_index, void *arg)
Definition: ip6_fib.c:551
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u8 * format_ip6_fib_table_memory(u8 *s, va_list *args)
Definition: ip6_fib.c:600
#define clib_bitmap_foreach(i, ai)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
enum fib_table_flags_t_ fib_table_flags_t
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
vl_api_address_t src
Definition: gre.api:54
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
vlib_main_t * vm
Definition: in2out_ed.c:1580
#define IP6_FIB_DEFAULT_HASH_NUM_BUCKETS
Definition: ip6_fib.h:31
u16 mask
Definition: flow_types.api:52
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:251
vhost_vring_addr_t addr
Definition: vhost_user.h:111
static void ip6_fib_table_show_all(ip6_fib_t *fib, vlib_main_t *vm)
Definition: ip6_fib.c:562
u8 * prefix_lengths_in_search_order
Definition: ip6_fib.h:65
unsigned char u8
Definition: types.h:56
static void vnet_ip6_fib_init(u32 fib_index)
Definition: ip6_fib.c:30
fib_node_index_t ip6_fib_table_lookup_exact_match(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:229
clib_bihash_24_8_t ip6_hash
Definition: ip6_fib.h:61
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u32 ft_epoch
Epoch - number of resyncs performed.
Definition: fib_table.h:117
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:424
static uword ip6_destination_matches_route(const ip6_main_t *im, const ip6_address_t *key, const ip6_address_t *dest, uword dest_length)
Definition: ip6.h:189
description fragment has unexpected format
Definition: map.api:433
fib_prefix_t * i6w_sub_trees
Definition: ip6_fib.c:440
Aggregate type for a prefix.
Definition: fib_types.h:202
#define clib_error_return(e, args...)
Definition: error.h:99
A representation of a single IP6 table.
Definition: ip6_fib.h:58
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:206
static clib_error_t * ip6_fib_init(vlib_main_t *vm)
Definition: ip6_fib.c:899
static u32 create_fib_with_table_id(u32 table_id, fib_source_t src, fib_table_flags_t flags, u8 *desc)
Definition: ip6_fib.c:64
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1644
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_fib.c:353
u32 * ft_locks
per-source number of locks on the table
Definition: fib_table.h:86
Definition: fib_entry.h:112
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
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
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:367
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:225
u8 * format_fib_table_flags(u8 *s, va_list *args)
Definition: fib_table.c:1357
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
vec_header_t h
Definition: buffer.c:322
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
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:398
u32 ft_total_route_counts
Total route counters.
Definition: fib_table.h:112
ip6_main_t ip6_main
Definition: ip6_forward.c:2785
u32 index
Definition: ip6.h:70
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
Definition: ip_flow_hash.h:29
vl_api_address_t dst
Definition: gre.api:55
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:505
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:102
Stop the walk completely.
Definition: fib_table.h:924
void ip6_fib_table_entry_remove(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:283
Context when walking the IPv6 table.
Definition: ip6_fib.c:434
u8 len
Definition: ip_types.api:103
uword * fib_index_by_table_id
Definition: ip6.h:137
unformat_function_t unformat_ip6_address
Definition: format.h:89
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:245
ip6_address_t fib_masks[129]
Definition: ip6.h:124
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:405
fib_node_index_t ft_index
Index into FIB vector.
Definition: fib_table.h:97
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
Definition: init.h:226
void ip6_fib_table_destroy(u32 fib_index)
Definition: ip6_fib.c:127
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
This table stores the routes that are used to forward traffic.
Definition: ip6_fib.h:43
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:92
u8 mask_width
Definition: dhcp.api:204
fib_prefix_t i6w_root
Definition: ip6_fib.c:439
u32 ft_flow_hash_config
flow hash configuration
Definition: fib_table.h:102
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
enum fib_table_walk_rc_t_ fib_table_walk_rc_t
return code controlling how a table walk proceeds
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
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:895
u32 ip6_fib_table_create_and_lock(fib_source_t src, fib_table_flags_t flags, u8 *desc)
Definition: ip6_fib.c:119
Definition: ip6.h:61
u8 * ft_desc
Table description.
Definition: fib_table.h:122
fib_table_flags_t ft_flags
Table flags.
Definition: fib_table.h:81
const dpo_id_t * ip6_ll_dpo_get(void)
The IP6 link-local DPO represents the lookup of a packet in the link-local IPv6 FIB.
Definition: ip6_ll_dpo.c:34
Definition: fib_entry.h:115
static void compute_prefix_lengths_in_search_order(ip6_fib_table_instance_t *table)
Definition: ip6_fib.c:255
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
fib_node_index_t * entries
Definition: ip6_fib.c:547
fib_table_walk_fn_t i6w_fn
Definition: ip6_fib.c:437
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:930
static int ip6_fib_walk_cb(clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: ip6_fib.c:444
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:1319
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
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:324
u8 value
Definition: qos.api:54
#define IP6_FIB_NUM_TABLES
Definition: ip6_fib.h:53
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:330
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
manual_print typedef address
Definition: ip_types.api:96
u8 * format_fib_source(u8 *s, va_list *args)
Definition: fib_source.c:66
i32 dst_address_length_refcounts[129]
Definition: ip6_fib.h:66
static void ip6_fib_table_show_one(ip6_fib_t *fib, vlib_main_t *vm, ip6_address_t *address, u32 mask_len, int detail)
Definition: ip6_fib.c:585
static int count_routes_in_fib_at_prefix_length(clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: ip6_fib.c:620
Do no traverse down this sub-tree.
Definition: fib_table.h:920
#define vec_elt(v, i)
Get vector value at index i.
typedef key
Definition: ipsec_types.api:86
#define FIB_ENTRY_FORMAT_BRIEF
Definition: fib_entry.h:359
struct ip6_fib_show_ctx_t_ ip6_fib_show_ctx_t
u32 ip6_fib_table_fwding_lookup_with_if_index(ip6_main_t *im, u32 sw_if_index, const ip6_address_t *dst)
Definition: ip6_fib.c:344
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:188
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * ip6_config(vlib_main_t *vm, unformat_input_t *input)
Definition: ip6_fib.c:873
static clib_error_t * ip6_show_fib(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip6_fib.c:637
static uword max_log2(uword x)
Definition: clib.h:209
u64 uword
Definition: types.h:112
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1055
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:314
The default route source.
Definition: fib_source.h:131
u32 table_id
Definition: wireguard.api:102
uword * non_empty_dst_address_length_bitmap
Definition: ip6_fib.h:64
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:29
struct ip6_fib_walk_ctx_t_ ip6_fib_walk_ctx_t
Context when walking the IPv6 table.
unformat_function_t unformat_memory_size
Definition: format.h:295
u32 * ft_src_route_counts
Per-source route counters.
Definition: fib_table.h:107
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
u8 * format_fib_table_name(u8 *s, va_list *ap)
Format the description/name of the table.
Definition: fib_table.c:1343
#define FIB_ENTRY_FORMAT_DETAIL2
Definition: fib_entry.h:361
#define vec_foreach(var, vec)
Vector iterator.
Special sources.
Definition: fib_source.h:42
fib_node_index_t ip6_fib_table_lookup(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:183
u32 table_id
Definition: ip6.h:67
void fib_table_assert_empty(const fib_table_t *fib_table)
Debug function.
Definition: fib_entry.c:1739
u8 * format_ip_flow_hash_config(u8 *s, va_list *args)
Definition: lookup.c:118
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
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:528
struct fib_table_t_ * fibs
Definition: ip6.h:115
u32 * fib_index_by_sw_if_index
Definition: ip6.h:127
#define VLIB_INITS(...)
Definition: init.h:357
u32 ip6_fib_table_nbuckets
Definition: ip6_fib.c:26
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
A protocol Independent FIB table.
Definition: fib_table.h:71
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127