FD.io VPP  v20.09-64-g4f7b92f0a
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 
23 static void
25 {
26  fib_prefix_t pfx = {
28  .fp_len = 0,
29  .fp_addr = {
30  .ip6 = {
31  { 0, 0, },
32  },
33  }
34  };
35 
36  /*
37  * Add the default route.
38  */
40  &pfx,
43 
44  /*
45  * all link local via the link local lookup DPO
46  */
47  pfx.fp_addr.ip6.as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL);
48  pfx.fp_addr.ip6.as_u64[1] = 0;
49  pfx.fp_len = 10;
51  &pfx,
54  ip6_ll_dpo_get());
55 }
56 
57 static u32
61  u8 *desc)
62 {
63  fib_table_t *fib_table;
64  ip6_fib_t *v6_fib;
65 
66  pool_get(ip6_main.fibs, fib_table);
68 
69  clib_memset(fib_table, 0, sizeof(*fib_table));
70  clib_memset(v6_fib, 0, sizeof(*v6_fib));
71 
72  ASSERT((fib_table - ip6_main.fibs) ==
73  (v6_fib - ip6_main.v6_fibs));
74 
75  fib_table->ft_proto = FIB_PROTOCOL_IP6;
76  fib_table->ft_index =
77  v6_fib->index =
78  (fib_table - ip6_main.fibs);
79 
80  hash_set(ip6_main.fib_index_by_table_id, table_id, fib_table->ft_index);
81 
82  fib_table->ft_table_id =
83  v6_fib->table_id =
84  table_id;
86  fib_table->ft_flags = flags;
87  fib_table->ft_desc = desc;
88 
89  vnet_ip6_fib_init(fib_table->ft_index);
90  fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP6, src);
91 
92  return (fib_table->ft_index);
93 }
94 
95 u32
98 {
99  uword * p;
100 
101  p = hash_get (ip6_main.fib_index_by_table_id, table_id);
102  if (NULL == p)
103  return create_fib_with_table_id(table_id, src,
105  NULL);
106 
107  fib_table_lock(p[0], FIB_PROTOCOL_IP6, src);
108 
109  return (p[0]);
110 }
111 
112 u32
115  u8 *desc)
116 {
117  return (create_fib_with_table_id(~0, src, flags, desc));
118 }
119 
120 void
122 {
123  /*
124  * all link local first ...
125  */
126  fib_prefix_t pfx = {
128  .fp_len = 10,
129  .fp_addr = {
130  .ip6 = {
131  .as_u8 = {
132  [0] = 0xFE,
133  [1] = 0x80,
134  },
135  },
136  }
137  };
138  fib_table_entry_delete(fib_index,
139  &pfx,
141 
142  /*
143  * ... then the default route.
144  */
145  pfx.fp_addr.ip6.as_u64[0] = 0;
146  pfx.fp_len = 00;
148  &pfx,
150 
151  fib_table_t *fib_table = fib_table_get(fib_index, FIB_PROTOCOL_IP6);
152  fib_source_t source;
153 
154  /*
155  * validate no more routes.
156  */
157 #if CLIB_DEBUG > 0
158  if (0 != fib_table->ft_total_route_counts)
159  fib_table_assert_empty(fib_table);
160 #endif
161 
162  vec_foreach_index(source, fib_table->ft_src_route_counts)
163  {
164  ASSERT(0 == fib_table->ft_src_route_counts[source]);
165  }
166 
167  if (~0 != fib_table->ft_table_id)
168  {
170  }
171  vec_free(fib_table->ft_src_route_counts);
173  pool_put(ip6_main.fibs, fib_table);
174 }
175 
178  const ip6_address_t *addr,
179  u32 len)
180 {
183  int i, n_p, rv;
184  u64 fib;
185 
188 
189  kv.key[0] = addr->as_u64[0];
190  kv.key[1] = addr->as_u64[1];
191  fib = ((u64)((fib_index))<<32);
192 
193  /*
194  * start search from a mask length same length or shorter.
195  * we don't want matches longer than the mask passed
196  */
197  i = 0;
198  while (i < n_p && table->prefix_lengths_in_search_order[i] > len)
199  {
200  i++;
201  }
202 
203  for (; i < n_p; i++)
204  {
205  int dst_address_length = table->prefix_lengths_in_search_order[i];
206  ip6_address_t * mask = &ip6_main.fib_masks[dst_address_length];
207 
208  ASSERT(dst_address_length >= 0 && dst_address_length <= 128);
209  //As lengths are decreasing, masks are increasingly specific.
210  kv.key[0] &= mask->as_u64[0];
211  kv.key[1] &= mask->as_u64[1];
212  kv.key[2] = fib | dst_address_length;
213 
214  rv = clib_bihash_search_inline_2_24_8(&table->ip6_hash, &kv, &value);
215  if (rv == 0)
216  return value.value;
217  }
218 
219  return (FIB_NODE_INDEX_INVALID);
220 }
221 
224  const ip6_address_t *addr,
225  u32 len)
226 {
229  ip6_address_t *mask;
230  u64 fib;
231  int rv;
232 
234  mask = &ip6_main.fib_masks[len];
235  fib = ((u64)((fib_index))<<32);
236 
237  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
238  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
239  kv.key[2] = fib | len;
240 
241  rv = clib_bihash_search_inline_2_24_8(&table->ip6_hash, &kv, &value);
242  if (rv == 0)
243  return value.value;
244 
245  return (FIB_NODE_INDEX_INVALID);
246 }
247 
248 static void
250 {
251  u8 *old, *prefix_lengths_in_search_order = NULL;
252  int i;
253 
254  /*
255  * build the list in a scratch space then cutover so the workers
256  * can continue uninterrupted.
257  */
258  old = table->prefix_lengths_in_search_order;
259 
260  /* Note: bitmap reversed so this is in fact a longest prefix match */
262  ({
263  int dst_address_length = 128 - i;
264  vec_add1(prefix_lengths_in_search_order, dst_address_length);
265  }));
266 
267  table->prefix_lengths_in_search_order = prefix_lengths_in_search_order;
268 
269  /*
270  * let the workers go once round the track before we free the old set
271  */
273  vec_free(old);
274 }
275 
276 void
278  const ip6_address_t *addr,
279  u32 len)
280 {
283  ip6_address_t *mask;
284  u64 fib;
285 
287  mask = &ip6_main.fib_masks[len];
288  fib = ((u64)((fib_index))<<32);
289 
290  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
291  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
292  kv.key[2] = fib | len;
293 
294  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 0);
295 
296  /* refcount accounting */
297  ASSERT (table->dst_address_length_refcounts[len] > 0);
298  if (--table->dst_address_length_refcounts[len] == 0)
299  {
302  128 - len, 0);
304  }
305 }
306 
307 void
309  const ip6_address_t *addr,
310  u32 len,
311  fib_node_index_t fib_entry_index)
312 {
315  ip6_address_t *mask;
316  u64 fib;
317 
319  mask = &ip6_main.fib_masks[len];
320  fib = ((u64)((fib_index))<<32);
321 
322  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
323  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
324  kv.key[2] = fib | len;
325  kv.value = fib_entry_index;
326 
327  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 1);
328 
329  if (0 == table->dst_address_length_refcounts[len]++)
330  {
333  128 - len, 1);
335  }
336 }
337 
340  const ip6_address_t * dst)
341 {
342  u32 fib_index = vec_elt (im->fib_index_by_sw_if_index, sw_if_index);
343  return ip6_fib_table_fwding_lookup(fib_index, dst);
344 }
345 
346 u32
348 {
349  if (sw_if_index >= vec_len(ip6_main.fib_index_by_sw_if_index))
350  {
351  /*
352  * This is the case for interfaces that are not yet mapped to
353  * a IP table
354  */
355  return (~0);
356  }
357  return (ip6_main.fib_index_by_sw_if_index[sw_if_index]);
358 }
359 
360 void
362  const ip6_address_t *addr,
363  u32 len,
364  const dpo_id_t *dpo)
365 {
368  ip6_address_t *mask;
369  u64 fib;
370 
372  mask = &ip6_main.fib_masks[len];
373  fib = ((u64)((fib_index))<<32);
374 
375  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
376  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
377  kv.key[2] = fib | len;
378  kv.value = dpo->dpoi_index;
379 
380  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 1);
381 
382  if (0 == table->dst_address_length_refcounts[len]++)
383  {
386  128 - len, 1);
388  }
389 }
390 
391 void
393  const ip6_address_t *addr,
394  u32 len,
395  const dpo_id_t *dpo)
396 {
399  ip6_address_t *mask;
400  u64 fib;
401 
403  mask = &ip6_main.fib_masks[len];
404  fib = ((u64)((fib_index))<<32);
405 
406  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
407  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
408  kv.key[2] = fib | len;
409  kv.value = dpo->dpoi_index;
410 
411  clib_bihash_add_del_24_8(&table->ip6_hash, &kv, 0);
412 
413  /* refcount accounting */
414  ASSERT (table->dst_address_length_refcounts[len] > 0);
415  if (--table->dst_address_length_refcounts[len] == 0)
416  {
419  128 - len, 0);
421  }
422 }
423 
424 /**
425  * @brief Context when walking the IPv6 table. Since all VRFs are in the
426  * same hash table, we need to filter only those we need as we walk
427  */
428 typedef struct ip6_fib_walk_ctx_t_
429 {
432  void *i6w_ctx;
436 
437 static int
439  void *arg)
440 {
441  ip6_fib_walk_ctx_t *ctx = arg;
442  ip6_address_t key;
443 
444  if ((kvp->key[2] >> 32) == ctx->i6w_fib_index)
445  {
446  key.as_u64[0] = kvp->key[0];
447  key.as_u64[1] = kvp->key[1];
448 
450  &key,
451  &ctx->i6w_root.fp_addr.ip6,
452  ctx->i6w_root.fp_len))
453  {
454  const fib_prefix_t *sub_tree;
455  int skip = 0;
456 
457  /*
458  * exclude sub-trees the walk does not want to explore
459  */
460  vec_foreach(sub_tree, ctx->i6w_sub_trees)
461  {
463  &key,
464  &sub_tree->fp_addr.ip6,
465  sub_tree->fp_len))
466  {
467  skip = 1;
468  break;
469  }
470  }
471 
472  if (!skip)
473  {
474  switch (ctx->i6w_fn(kvp->value, ctx->i6w_ctx))
475  {
477  break;
479  fib_prefix_t pfx = {
481  .fp_len = kvp->key[2] & 0xffffffff,
482  .fp_addr.ip6 = key,
483  };
484  vec_add1(ctx->i6w_sub_trees, pfx);
485  break;
486  }
487  case FIB_TABLE_WALK_STOP:
488  goto done;
489  }
490  }
491  }
492  }
493 done:
494 
495  return (1);
496 }
497 
498 void
501  void *arg)
502 {
504  .i6w_fib_index = fib_index,
505  .i6w_fn = fn,
506  .i6w_ctx = arg,
507  .i6w_root = {
508  .fp_proto = FIB_PROTOCOL_IP6,
509  },
510  .i6w_sub_trees = NULL,
511  };
512 
513  clib_bihash_foreach_key_value_pair_24_8(
516  &ctx);
517 
518  vec_free(ctx.i6w_sub_trees);
519 }
520 
521 void
523  const fib_prefix_t *root,
525  void *arg)
526 {
528  .i6w_fib_index = fib_index,
529  .i6w_fn = fn,
530  .i6w_ctx = arg,
531  .i6w_root = *root,
532  };
533 
534  clib_bihash_foreach_key_value_pair_24_8(
537  &ctx);
538 }
539 
540 typedef struct ip6_fib_show_ctx_t_ {
543 
544 static fib_table_walk_rc_t
546  void *arg)
547 {
548  ip6_fib_show_ctx_t *ctx = arg;
549 
550  vec_add1(ctx->entries, fib_entry_index);
551 
552  return (FIB_TABLE_WALK_CONTINUE);
553 }
554 
555 static void
557  vlib_main_t * vm)
558 {
559  fib_node_index_t *fib_entry_index;
561  .entries = NULL,
562  };
563 
566 
567  vec_foreach(fib_entry_index, ctx.entries)
568  {
569  vlib_cli_output(vm, "%U",
571  *fib_entry_index,
573  }
574 
575  vec_free(ctx.entries);
576 }
577 
578 static void
580  vlib_main_t * vm,
581  ip6_address_t *address,
582  u32 mask_len,
583  int detail)
584 {
585  vlib_cli_output(vm, "%U",
587  ip6_fib_table_lookup(fib->index, address, mask_len),
588  (detail ?
591 }
592 
593 u8 *
594 format_ip6_fib_table_memory (u8 * s, va_list * args)
595 {
596  uword bytes_inuse;
597 
598  bytes_inuse = (alloc_arena_next(&(ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash)) +
599  alloc_arena_next(&(ip6_main.ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash)));
600 
601  s = format(s, "%=30s %=6d %=12ld\n",
602  "IPv6 unicast",
604  bytes_inuse);
605  return (s);
606 }
607 
608 typedef struct {
610  u64 count_by_prefix_length[129];
612 
613 static int
615  void *arg)
616 {
618  int mask_width;
619 
620  if ((kvp->key[2]>>32) != ap->fib_index)
621  return (BIHASH_WALK_CONTINUE);
622 
623  mask_width = kvp->key[2] & 0xFF;
624 
626 
627  return (BIHASH_WALK_CONTINUE);
628 }
629 
630 static clib_error_t *
632  unformat_input_t * input,
633  vlib_cli_command_t * cmd)
634 {
636  ip6_main_t * im6 = &ip6_main;
637  fib_table_t *fib_table;
638  ip6_fib_t * fib;
639  int verbose, matching;
640  ip6_address_t matching_address;
641  u32 mask_len = 128;
642  int table_id = -1, fib_index = ~0;
643  int detail = 0;
644  int hash = 0;
645 
646  verbose = 1;
647  matching = 0;
648 
650  {
651  if (unformat (input, "brief") ||
652  unformat (input, "summary") ||
653  unformat (input, "sum"))
654  verbose = 0;
655 
656  else if (unformat (input, "detail") ||
657  unformat (input, "det"))
658  detail = 1;
659 
660  else if (unformat (input, "hash") ||
661  unformat (input, "mem") ||
662  unformat (input, "memory"))
663  hash = 1;
664 
665  else if (unformat (input, "%U/%d",
666  unformat_ip6_address, &matching_address, &mask_len))
667  matching = 1;
668 
669  else if (unformat (input, "%U", unformat_ip6_address, &matching_address))
670  matching = 1;
671 
672  else if (unformat (input, "table %d", &table_id))
673  ;
674  else if (unformat (input, "index %d", &fib_index))
675  ;
676  else
677  break;
678  }
679 
680  if (hash)
681  {
682  vlib_cli_output (vm, "IPv6 Non-Forwarding Hash Table:\n%U\n",
683  BV (format_bihash),
685  detail);
686  vlib_cli_output (vm, "IPv6 Forwarding Hash Table:\n%U\n",
687  BV (format_bihash),
689  detail);
690  return (NULL);
691  }
692 
693  pool_foreach (fib_table, im6->fibs,
694  ({
695  fib_source_t source;
696  u8 *s = NULL;
697 
698  fib = pool_elt_at_index(im6->v6_fibs, fib_table->ft_index);
699  if (table_id >= 0 && table_id != (int)fib->table_id)
700  continue;
701  if (fib_index != ~0 && fib_index != (int)fib->index)
702  continue;
703  if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
704  continue;
705 
706  s = format(s, "%U, fib_index:%d, flow hash:[%U] epoch:%d flags:%U locks:[",
707  format_fib_table_name, fib->index,
708  FIB_PROTOCOL_IP6,
709  fib->index,
710  format_ip_flow_hash_config,
711  fib_table->ft_flow_hash_config,
712  fib_table->ft_epoch,
713  format_fib_table_flags, fib_table->ft_flags);
714 
715  vec_foreach_index(source, fib_table->ft_locks)
716  {
717  if (0 != fib_table->ft_locks[source])
718  {
719  s = format(s, "%U:%d, ",
720  format_fib_source, source,
721  fib_table->ft_locks[source]);
722  }
723  }
724  s = format (s, "]");
725  vlib_cli_output (vm, "%v", s);
726  vec_free(s);
727 
728  /* Show summary? */
729  if (! verbose)
730  {
731  clib_bihash_24_8_t * h = &im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash;
732  int len;
733 
734  vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count");
735 
736  clib_memset (ca, 0, sizeof(*ca));
737  ca->fib_index = fib->index;
738 
739  clib_bihash_foreach_key_value_pair_24_8
741 
742  for (len = 128; len >= 0; len--)
743  {
744  if (ca->count_by_prefix_length[len])
745  vlib_cli_output (vm, "%=20d%=16lld",
746  len, ca->count_by_prefix_length[len]);
747  }
748  continue;
749  }
750 
751  if (!matching)
752  {
753  ip6_fib_table_show_all(fib, vm);
754  }
755  else
756  {
757  ip6_fib_table_show_one(fib, vm, &matching_address, mask_len, detail);
758  }
759  }));
760 
761  return 0;
762 }
763 
764 /*?
765  * This command displays the IPv6 FIB Tables (VRF Tables) and the route
766  * entries for each table.
767  *
768  * @note This command will run for a long time when the FIB tables are
769  * comprised of millions of entries. For those senarios, consider displaying
770  * in summary mode.
771  *
772  * @cliexpar
773  * @parblock
774  * Example of how to display all the IPv6 FIB tables:
775  * @cliexstart{show ip6 fib}
776  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
777  * @::/0
778  * unicast-ip6-chain
779  * [@0]: dpo-load-balance: [index:5 buckets:1 uRPF:5 to:[0:0]]
780  * [0] [@0]: dpo-drop ip6
781  * fe80::/10
782  * unicast-ip6-chain
783  * [@0]: dpo-load-balance: [index:10 buckets:1 uRPF:10 to:[0:0]]
784  * [0] [@2]: dpo-receive
785  * ff02::1/128
786  * unicast-ip6-chain
787  * [@0]: dpo-load-balance: [index:8 buckets:1 uRPF:8 to:[0:0]]
788  * [0] [@2]: dpo-receive
789  * ff02::2/128
790  * unicast-ip6-chain
791  * [@0]: dpo-load-balance: [index:7 buckets:1 uRPF:7 to:[0:0]]
792  * [0] [@2]: dpo-receive
793  * ff02::16/128
794  * unicast-ip6-chain
795  * [@0]: dpo-load-balance: [index:9 buckets:1 uRPF:9 to:[0:0]]
796  * [0] [@2]: dpo-receive
797  * ff02::1:ff00:0/104
798  * unicast-ip6-chain
799  * [@0]: dpo-load-balance: [index:6 buckets:1 uRPF:6 to:[0:0]]
800  * [0] [@2]: dpo-receive
801  * ipv6-VRF:8, fib_index 1, flow hash: src dst sport dport proto
802  * @::/0
803  * unicast-ip6-chain
804  * [@0]: dpo-load-balance: [index:21 buckets:1 uRPF:20 to:[0:0]]
805  * [0] [@0]: dpo-drop ip6
806  * @::a:1:1:0:4/126
807  * unicast-ip6-chain
808  * [@0]: dpo-load-balance: [index:27 buckets:1 uRPF:26 to:[0:0]]
809  * [0] [@4]: ipv6-glean: af_packet0
810  * @::a:1:1:0:7/128
811  * unicast-ip6-chain
812  * [@0]: dpo-load-balance: [index:28 buckets:1 uRPF:27 to:[0:0]]
813  * [0] [@2]: dpo-receive: @::a:1:1:0:7 on af_packet0
814  * fe80::/10
815  * unicast-ip6-chain
816  * [@0]: dpo-load-balance: [index:26 buckets:1 uRPF:25 to:[0:0]]
817  * [0] [@2]: dpo-receive
818  * fe80::fe:3eff:fe3e:9222/128
819  * unicast-ip6-chain
820  * [@0]: dpo-load-balance: [index:29 buckets:1 uRPF:28 to:[0:0]]
821  * [0] [@2]: dpo-receive: fe80::fe:3eff:fe3e:9222 on af_packet0
822  * ff02::1/128
823  * unicast-ip6-chain
824  * [@0]: dpo-load-balance: [index:24 buckets:1 uRPF:23 to:[0:0]]
825  * [0] [@2]: dpo-receive
826  * ff02::2/128
827  * unicast-ip6-chain
828  * [@0]: dpo-load-balance: [index:23 buckets:1 uRPF:22 to:[0:0]]
829  * [0] [@2]: dpo-receive
830  * ff02::16/128
831  * unicast-ip6-chain
832  * [@0]: dpo-load-balance: [index:25 buckets:1 uRPF:24 to:[0:0]]
833  * [0] [@2]: dpo-receive
834  * ff02::1:ff00:0/104
835  * unicast-ip6-chain
836  * [@0]: dpo-load-balance: [index:22 buckets:1 uRPF:21 to:[0:0]]
837  * [0] [@2]: dpo-receive
838  * @cliexend
839  *
840  * Example of how to display a summary of all IPv6 FIB tables:
841  * @cliexstart{show ip6 fib summary}
842  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
843  * Prefix length Count
844  * 128 3
845  * 104 1
846  * 10 1
847  * 0 1
848  * ipv6-VRF:8, fib_index 1, flow hash: src dst sport dport proto
849  * Prefix length Count
850  * 128 5
851  * 126 1
852  * 104 1
853  * 10 1
854  * 0 1
855  * @cliexend
856  * @endparblock
857  ?*/
858 /* *INDENT-OFF* */
859 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
860  .path = "show ip6 fib",
861  .short_help = "show ip6 fib [summary] [table <table-id>] [index <fib-id>] [<ip6-addr>[/<width>]] [detail]",
862  .function = ip6_show_fib,
863 };
864 /* *INDENT-ON* */
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
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:1666
fib_protocol_t ft_proto
Which protocol this table serves.
Definition: fib_table.h:76
static u32 ip6_fib_table_fwding_lookup(u32 fib_index, const ip6_address_t *dst)
Definition: ip6_fib.h:67
ip6_fib_t * v6_fibs
Definition: ip6.h:187
#define hash_unset(h, key)
Definition: hash.h:261
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
The table that stores ALL routes learned by the DP.
Definition: ip6.h:136
#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:545
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:594
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:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
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:252
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:556
u8 * prefix_lengths_in_search_order
Definition: ip6.h:151
unsigned char u8
Definition: types.h:56
static void vnet_ip6_fib_init(u32 fib_index)
Definition: ip6_fib.c:24
fib_node_index_t ip6_fib_table_lookup_exact_match(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:223
clib_bihash_24_8_t ip6_hash
Definition: ip6.h:147
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
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:265
fib_prefix_t * i6w_sub_trees
Definition: ip6_fib.c:434
Aggregate type for a prefix.
Definition: fib_types.h:203
A representation of a single IP6 table.
Definition: ip6.h:144
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:207
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:58
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1623
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_fib.c:347
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 clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
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:361
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
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:302
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:392
u32 ft_total_route_counts
Total route counters.
Definition: fib_table.h:112
ip6_main_t ip6_main
Definition: ip6_forward.c:2781
u32 index
Definition: ip6.h:80
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:499
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
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:277
Context when walking the IPv6 table.
Definition: ip6_fib.c:428
u8 len
Definition: ip_types.api:92
uword * fib_index_by_table_id
Definition: ip6.h:206
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:246
ip6_address_t fib_masks[129]
Definition: ip6.h:193
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
void ip6_fib_table_destroy(u32 fib_index)
Definition: ip6_fib.c:121
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
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:433
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:886
u32 ip6_fib_table_create_and_lock(fib_source_t src, fib_table_flags_t flags, u8 *desc)
Definition: ip6_fib.c:113
Definition: ip6.h:71
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
This table stores the routes that are used to forward traffic.
Definition: ip6.h:129
static void compute_prefix_lengths_in_search_order(ip6_fib_table_instance_t *table)
Definition: ip6_fib.c:249
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
fib_node_index_t * entries
Definition: ip6_fib.c:541
fib_table_walk_fn_t i6w_fn
Definition: ip6_fib.c:431
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:438
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:1310
#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 pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:331
#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:85
i32 dst_address_length_refcounts[129]
Definition: ip6.h:152
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:579
static int count_routes_in_fib_at_prefix_length(clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: ip6_fib.c:614
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
Definition: lookup.h:70
ip6_fib_table_instance_t ip6_table[IP6_FIB_NUM_TABLES]
The two FIB tables; fwding and non-fwding.
Definition: ip6.h:174
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:85
#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:338
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:186
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * ip6_show_fib(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip6_fib.c:631
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:308
The default route source.
Definition: fib_source.h:131
u32 table_id
Definition: wireguard.api:100
uword * non_empty_dst_address_length_bitmap
Definition: ip6.h:150
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.
u32 * ft_src_route_counts
Per-source route counters.
Definition: fib_table.h:107
#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:177
u32 table_id
Definition: ip6.h:77
void fib_table_assert_empty(const fib_table_t *fib_table)
Debug function.
Definition: fib_entry.c:1718
#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:522
struct fib_table_t_ * fibs
Definition: ip6.h:184
u32 * fib_index_by_sw_if_index
Definition: ip6.h:196
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
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:171
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:128