FD.io VPP  v18.07-rc0-415-g6c78436
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 static void
22 {
23  fib_prefix_t pfx = {
25  .fp_len = 0,
26  .fp_addr = {
27  .ip6 = {
28  { 0, 0, },
29  },
30  }
31  };
32 
33  /*
34  * Add the default route.
35  */
37  &pfx,
40 
41  /*
42  * all link local via the link local lookup DPO
43  */
44  pfx.fp_addr.ip6.as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL);
45  pfx.fp_addr.ip6.as_u64[1] = 0;
46  pfx.fp_len = 10;
48  &pfx,
51  ip6_ll_dpo_get());
52 }
53 
54 static u32
56  fib_source_t src,
58  u8 *desc)
59 {
60  fib_table_t *fib_table;
61  ip6_fib_t *v6_fib;
62 
63  pool_get(ip6_main.fibs, fib_table);
65 
66  memset(fib_table, 0, sizeof(*fib_table));
67  memset(v6_fib, 0, sizeof(*v6_fib));
68 
69  ASSERT((fib_table - ip6_main.fibs) ==
70  (v6_fib - ip6_main.v6_fibs));
71 
72  fib_table->ft_proto = FIB_PROTOCOL_IP6;
73  fib_table->ft_index =
74  v6_fib->index =
75  (fib_table - ip6_main.fibs);
76 
77  hash_set(ip6_main.fib_index_by_table_id, table_id, fib_table->ft_index);
78 
79  fib_table->ft_table_id =
80  v6_fib->table_id =
81  table_id;
83  fib_table->ft_flags = flags;
84  fib_table->ft_desc = desc;
85 
86  vnet_ip6_fib_init(fib_table->ft_index);
87  fib_table_lock(fib_table->ft_index, FIB_PROTOCOL_IP6, src);
88 
89  return (fib_table->ft_index);
90 }
91 
92 u32
94  fib_source_t src)
95 {
96  uword * p;
97 
98  p = hash_get (ip6_main.fib_index_by_table_id, table_id);
99  if (NULL == p)
100  return create_fib_with_table_id(table_id, src,
102  NULL);
103 
104  fib_table_lock(p[0], FIB_PROTOCOL_IP6, src);
105 
106  return (p[0]);
107 }
108 
109 u32
112  u8 *desc)
113 {
114  return (create_fib_with_table_id(~0, src, flags, desc));
115 }
116 
117 void
119 {
120  /*
121  * all link local first ...
122  */
123  fib_prefix_t pfx = {
125  .fp_len = 10,
126  .fp_addr = {
127  .ip6 = {
128  .as_u8 = {
129  [0] = 0xFE,
130  [1] = 0x80,
131  },
132  },
133  }
134  };
135  fib_table_entry_delete(fib_index,
136  &pfx,
138 
139  /*
140  * ... then the default route.
141  */
142  pfx.fp_addr.ip6.as_u64[0] = 0;
143  pfx.fp_len = 00;
145  &pfx,
147 
148  fib_table_t *fib_table = fib_table_get(fib_index, FIB_PROTOCOL_IP6);
149  fib_source_t source;
150 
151  /*
152  * validate no more routes.
153  */
154  ASSERT(0 == fib_table->ft_total_route_counts);
155  FOR_EACH_FIB_SOURCE(source)
156  {
157  ASSERT(0 == fib_table->ft_src_route_counts[source]);
158  }
159 
160  if (~0 != fib_table->ft_table_id)
161  {
163  }
165  pool_put(ip6_main.fibs, fib_table);
166 }
167 
170  const ip6_address_t *addr,
171  u32 len)
172 {
174  BVT(clib_bihash_kv) kv, value;
175  int i, n_p, rv;
176  u64 fib;
177 
180 
181  kv.key[0] = addr->as_u64[0];
182  kv.key[1] = addr->as_u64[1];
183  fib = ((u64)((fib_index))<<32);
184 
185  /*
186  * start search from a mask length same length or shorter.
187  * we don't want matches longer than the mask passed
188  */
189  i = 0;
190  while (i < n_p && table->prefix_lengths_in_search_order[i] > len)
191  {
192  i++;
193  }
194 
195  for (; i < n_p; i++)
196  {
197  int dst_address_length = table->prefix_lengths_in_search_order[i];
198  ip6_address_t * mask = &ip6_main.fib_masks[dst_address_length];
199 
200  ASSERT(dst_address_length >= 0 && dst_address_length <= 128);
201  //As lengths are decreasing, masks are increasingly specific.
202  kv.key[0] &= mask->as_u64[0];
203  kv.key[1] &= mask->as_u64[1];
204  kv.key[2] = fib | dst_address_length;
205 
206  rv = BV(clib_bihash_search_inline_2)(&table->ip6_hash, &kv, &value);
207  if (rv == 0)
208  return value.value;
209  }
210 
211  return (FIB_NODE_INDEX_INVALID);
212 }
213 
216  const ip6_address_t *addr,
217  u32 len)
218 {
220  BVT(clib_bihash_kv) kv, value;
221  ip6_address_t *mask;
222  u64 fib;
223  int rv;
224 
226  mask = &ip6_main.fib_masks[len];
227  fib = ((u64)((fib_index))<<32);
228 
229  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
230  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
231  kv.key[2] = fib | len;
232 
233  rv = BV(clib_bihash_search_inline_2)(&table->ip6_hash, &kv, &value);
234  if (rv == 0)
235  return value.value;
236 
237  return (FIB_NODE_INDEX_INVALID);
238 }
239 
240 static void
242 {
243  int i;
245  /* Note: bitmap reversed so this is in fact a longest prefix match */
247  ({
248  int dst_address_length = 128 - i;
249  vec_add1(table->prefix_lengths_in_search_order, dst_address_length);
250  }));
251 }
252 
253 void
255  const ip6_address_t *addr,
256  u32 len)
257 {
259  BVT(clib_bihash_kv) kv;
260  ip6_address_t *mask;
261  u64 fib;
262 
264  mask = &ip6_main.fib_masks[len];
265  fib = ((u64)((fib_index))<<32);
266 
267  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
268  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
269  kv.key[2] = fib | len;
270 
271  BV(clib_bihash_add_del)(&table->ip6_hash, &kv, 0);
272 
273  /* refcount accounting */
274  ASSERT (table->dst_address_length_refcounts[len] > 0);
275  if (--table->dst_address_length_refcounts[len] == 0)
276  {
279  128 - len, 0);
281  }
282 }
283 
284 void
286  const ip6_address_t *addr,
287  u32 len,
288  fib_node_index_t fib_entry_index)
289 {
291  BVT(clib_bihash_kv) kv;
292  ip6_address_t *mask;
293  u64 fib;
294 
296  mask = &ip6_main.fib_masks[len];
297  fib = ((u64)((fib_index))<<32);
298 
299  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
300  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
301  kv.key[2] = fib | len;
302  kv.value = fib_entry_index;
303 
304  BV(clib_bihash_add_del)(&table->ip6_hash, &kv, 1);
305 
306  table->dst_address_length_refcounts[len]++;
307 
310  128 - len, 1);
312 }
313 
315  u32 sw_if_index,
316  const ip6_address_t * dst)
317 {
318  u32 fib_index = vec_elt (im->fib_index_by_sw_if_index, sw_if_index);
319  return ip6_fib_table_fwding_lookup(im, fib_index, dst);
320 }
321 
322 u32
324 {
325  if (sw_if_index >= vec_len(ip6_main.fib_index_by_sw_if_index))
326  {
327  /*
328  * This is the case for interfaces that are not yet mapped to
329  * a IP table
330  */
331  return (~0);
332  }
333  return (ip6_main.fib_index_by_sw_if_index[sw_if_index]);
334 }
335 
336 void
338  const ip6_address_t *addr,
339  u32 len,
340  const dpo_id_t *dpo)
341 {
343  BVT(clib_bihash_kv) kv;
344  ip6_address_t *mask;
345  u64 fib;
346 
348  mask = &ip6_main.fib_masks[len];
349  fib = ((u64)((fib_index))<<32);
350 
351  kv.key[0] = addr->as_u64[0] & mask->as_u64[0];
352  kv.key[1] = addr->as_u64[1] & mask->as_u64[1];
353  kv.key[2] = fib | len;
354  kv.value = dpo->dpoi_index;
355 
356  BV(clib_bihash_add_del)(&table->ip6_hash, &kv, 1);
357 
358  table->dst_address_length_refcounts[len]++;
359 
362  128 - len, 1);
364 }
365 
366 void
368  const ip6_address_t *addr,
369  u32 len,
370  const dpo_id_t *dpo)
371 {
373  BVT(clib_bihash_kv) kv;
374  ip6_address_t *mask;
375  u64 fib;
376 
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  BV(clib_bihash_add_del)(&table->ip6_hash, &kv, 0);
387 
388  /* refcount accounting */
389  ASSERT (table->dst_address_length_refcounts[len] > 0);
390  if (--table->dst_address_length_refcounts[len] == 0)
391  {
394  128 - len, 0);
396  }
397 }
398 
399 /**
400  * @brief Context when walking the IPv6 table. Since all VRFs are in the
401  * same hash table, we need to filter only those we need as we walk
402  */
403 typedef struct ip6_fib_walk_ctx_t_
404 {
407  void *i6w_ctx;
411 
412 static int
414  void *arg)
415 {
416  ip6_fib_walk_ctx_t *ctx = arg;
417  ip6_address_t key;
418 
419  if ((kvp->key[2] >> 32) == ctx->i6w_fib_index)
420  {
421  key.as_u64[0] = kvp->key[0];
422  key.as_u64[1] = kvp->key[1];
423 
425  &key,
426  &ctx->i6w_root.fp_addr.ip6,
427  ctx->i6w_root.fp_len))
428  {
429  const fib_prefix_t *sub_tree;
430  int skip = 0;
431 
432  /*
433  * exclude sub-trees the walk does not want to explore
434  */
435  vec_foreach(sub_tree, ctx->i6w_sub_trees)
436  {
438  &key,
439  &sub_tree->fp_addr.ip6,
440  sub_tree->fp_len))
441  {
442  skip = 1;
443  break;
444  }
445  }
446 
447  if (!skip)
448  {
449  switch (ctx->i6w_fn(kvp->value, ctx->i6w_ctx))
450  {
452  break;
454  fib_prefix_t pfx = {
456  .fp_len = kvp->key[2] & 0xffffffff,
457  .fp_addr.ip6 = key,
458  };
459  vec_add1(ctx->i6w_sub_trees, pfx);
460  break;
461  }
462  case FIB_TABLE_WALK_STOP:
463  goto done;
464  }
465  }
466  }
467  }
468 done:
469 
470  return (1);
471 }
472 
473 void
476  void *arg)
477 {
479  .i6w_fib_index = fib_index,
480  .i6w_fn = fn,
481  .i6w_ctx = arg,
482  .i6w_root = {
483  .fp_proto = FIB_PROTOCOL_IP6,
484  },
485  .i6w_sub_trees = NULL,
486  };
487 
491  &ctx);
492 
493  vec_free(ctx.i6w_sub_trees);
494 }
495 
496 void
498  const fib_prefix_t *root,
500  void *arg)
501 {
503  .i6w_fib_index = fib_index,
504  .i6w_fn = fn,
505  .i6w_ctx = arg,
506  .i6w_root = *root,
507  };
508 
512  &ctx);
513 }
514 
515 typedef struct ip6_fib_show_ctx_t_ {
518 
519 static fib_table_walk_rc_t
521  void *arg)
522 {
523  ip6_fib_show_ctx_t *ctx = arg;
524 
525  vec_add1(ctx->entries, fib_entry_index);
526 
527  return (FIB_TABLE_WALK_CONTINUE);
528 }
529 
530 static void
532  vlib_main_t * vm)
533 {
534  fib_node_index_t *fib_entry_index;
536  .entries = NULL,
537  };
538 
541 
542  vec_foreach(fib_entry_index, ctx.entries)
543  {
544  vlib_cli_output(vm, "%U",
546  *fib_entry_index,
548  }
549 
550  vec_free(ctx.entries);
551 }
552 
553 static void
555  vlib_main_t * vm,
557  u32 mask_len,
558  int detail)
559 {
560  vlib_cli_output(vm, "%U",
562  ip6_fib_table_lookup(fib->index, address, mask_len),
563  (detail ?
566 }
567 
568 u8 *
569 format_ip6_fib_table_memory (u8 * s, va_list * args)
570 {
571  uword bytes_inuse;
572 
573  bytes_inuse =
574  ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash.alloc_arena_next
575  - ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash.alloc_arena;
576 
577  bytes_inuse +=
578  ip6_main.ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash.alloc_arena_next
579  - ip6_main.ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash.alloc_arena;
580 
581  s = format(s, "%=30s %=6d %=8ld\n",
582  "IPv6 unicast",
584  bytes_inuse);
585  return (s);
586 }
587 
588 typedef struct {
590  u64 count_by_prefix_length[129];
592 
593 static void
595  void *arg)
596 {
598  int mask_width;
599 
600  if ((kvp->key[2]>>32) != ap->fib_index)
601  return;
602 
603  mask_width = kvp->key[2] & 0xFF;
604 
606 }
607 
608 static clib_error_t *
610  unformat_input_t * input,
611  vlib_cli_command_t * cmd)
612 {
614  ip6_main_t * im6 = &ip6_main;
615  fib_table_t *fib_table;
616  ip6_fib_t * fib;
617  int verbose, matching;
618  ip6_address_t matching_address;
619  u32 mask_len = 128;
620  int table_id = -1, fib_index = ~0;
621  int detail = 0;
622 
623  verbose = 1;
624  matching = 0;
625 
627  {
628  if (unformat (input, "brief") ||
629  unformat (input, "summary") ||
630  unformat (input, "sum"))
631  verbose = 0;
632 
633  else if (unformat (input, "detail") ||
634  unformat (input, "det"))
635  detail = 1;
636 
637  else if (unformat (input, "%U/%d",
638  unformat_ip6_address, &matching_address, &mask_len))
639  matching = 1;
640 
641  else if (unformat (input, "%U", unformat_ip6_address, &matching_address))
642  matching = 1;
643 
644  else if (unformat (input, "table %d", &table_id))
645  ;
646  else if (unformat (input, "index %d", &fib_index))
647  ;
648  else
649  break;
650  }
651 
652  pool_foreach (fib_table, im6->fibs,
653  ({
654  fib_source_t source;
655  u8 *s = NULL;
656 
657  fib = pool_elt_at_index(im6->v6_fibs, fib_table->ft_index);
658  if (table_id >= 0 && table_id != (int)fib->table_id)
659  continue;
660  if (fib_index != ~0 && fib_index != (int)fib->index)
661  continue;
662  if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
663  continue;
664 
665  s = format(s, "%U, fib_index:%d, flow hash:[%U] locks:[",
666  format_fib_table_name, fib->index,
667  FIB_PROTOCOL_IP6,
668  fib->index,
669  format_ip_flow_hash_config,
670  fib_table->ft_flow_hash_config);
671  FOR_EACH_FIB_SOURCE(source)
672  {
673  if (0 != fib_table->ft_locks[source])
674  {
675  s = format(s, "%U:%d, ",
676  format_fib_source, source,
677  fib_table->ft_locks[source]);
678  }
679  }
680  s = format (s, "]");
681  vlib_cli_output (vm, "%v", s);
682  vec_free(s);
683 
684  /* Show summary? */
685  if (! verbose)
686  {
687  BVT(clib_bihash) * h = &im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash;
688  int len;
689 
690  vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count");
691 
692  memset (ca, 0, sizeof(*ca));
693  ca->fib_index = fib->index;
694 
697 
698  for (len = 128; len >= 0; len--)
699  {
700  if (ca->count_by_prefix_length[len])
701  vlib_cli_output (vm, "%=20d%=16lld",
702  len, ca->count_by_prefix_length[len]);
703  }
704  continue;
705  }
706 
707  if (!matching)
708  {
709  ip6_fib_table_show_all(fib, vm);
710  }
711  else
712  {
713  ip6_fib_table_show_one(fib, vm, &matching_address, mask_len, detail);
714  }
715  }));
716 
717  return 0;
718 }
719 
720 /*?
721  * This command displays the IPv6 FIB Tables (VRF Tables) and the route
722  * entries for each table.
723  *
724  * @note This command will run for a long time when the FIB tables are
725  * comprised of millions of entries. For those senarios, consider displaying
726  * in summary mode.
727  *
728  * @cliexpar
729  * @parblock
730  * Example of how to display all the IPv6 FIB tables:
731  * @cliexstart{show ip6 fib}
732  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
733  * @::/0
734  * unicast-ip6-chain
735  * [@0]: dpo-load-balance: [index:5 buckets:1 uRPF:5 to:[0:0]]
736  * [0] [@0]: dpo-drop ip6
737  * fe80::/10
738  * unicast-ip6-chain
739  * [@0]: dpo-load-balance: [index:10 buckets:1 uRPF:10 to:[0:0]]
740  * [0] [@2]: dpo-receive
741  * ff02::1/128
742  * unicast-ip6-chain
743  * [@0]: dpo-load-balance: [index:8 buckets:1 uRPF:8 to:[0:0]]
744  * [0] [@2]: dpo-receive
745  * ff02::2/128
746  * unicast-ip6-chain
747  * [@0]: dpo-load-balance: [index:7 buckets:1 uRPF:7 to:[0:0]]
748  * [0] [@2]: dpo-receive
749  * ff02::16/128
750  * unicast-ip6-chain
751  * [@0]: dpo-load-balance: [index:9 buckets:1 uRPF:9 to:[0:0]]
752  * [0] [@2]: dpo-receive
753  * ff02::1:ff00:0/104
754  * unicast-ip6-chain
755  * [@0]: dpo-load-balance: [index:6 buckets:1 uRPF:6 to:[0:0]]
756  * [0] [@2]: dpo-receive
757  * ipv6-VRF:8, fib_index 1, flow hash: src dst sport dport proto
758  * @::/0
759  * unicast-ip6-chain
760  * [@0]: dpo-load-balance: [index:21 buckets:1 uRPF:20 to:[0:0]]
761  * [0] [@0]: dpo-drop ip6
762  * @::a:1:1:0:4/126
763  * unicast-ip6-chain
764  * [@0]: dpo-load-balance: [index:27 buckets:1 uRPF:26 to:[0:0]]
765  * [0] [@4]: ipv6-glean: af_packet0
766  * @::a:1:1:0:7/128
767  * unicast-ip6-chain
768  * [@0]: dpo-load-balance: [index:28 buckets:1 uRPF:27 to:[0:0]]
769  * [0] [@2]: dpo-receive: @::a:1:1:0:7 on af_packet0
770  * fe80::/10
771  * unicast-ip6-chain
772  * [@0]: dpo-load-balance: [index:26 buckets:1 uRPF:25 to:[0:0]]
773  * [0] [@2]: dpo-receive
774  * fe80::fe:3eff:fe3e:9222/128
775  * unicast-ip6-chain
776  * [@0]: dpo-load-balance: [index:29 buckets:1 uRPF:28 to:[0:0]]
777  * [0] [@2]: dpo-receive: fe80::fe:3eff:fe3e:9222 on af_packet0
778  * ff02::1/128
779  * unicast-ip6-chain
780  * [@0]: dpo-load-balance: [index:24 buckets:1 uRPF:23 to:[0:0]]
781  * [0] [@2]: dpo-receive
782  * ff02::2/128
783  * unicast-ip6-chain
784  * [@0]: dpo-load-balance: [index:23 buckets:1 uRPF:22 to:[0:0]]
785  * [0] [@2]: dpo-receive
786  * ff02::16/128
787  * unicast-ip6-chain
788  * [@0]: dpo-load-balance: [index:25 buckets:1 uRPF:24 to:[0:0]]
789  * [0] [@2]: dpo-receive
790  * ff02::1:ff00:0/104
791  * unicast-ip6-chain
792  * [@0]: dpo-load-balance: [index:22 buckets:1 uRPF:21 to:[0:0]]
793  * [0] [@2]: dpo-receive
794  * @cliexend
795  *
796  * Example of how to display a summary of all IPv6 FIB tables:
797  * @cliexstart{show ip6 fib summary}
798  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
799  * Prefix length Count
800  * 128 3
801  * 104 1
802  * 10 1
803  * 0 1
804  * ipv6-VRF:8, fib_index 1, flow hash: src dst sport dport proto
805  * Prefix length Count
806  * 128 5
807  * 126 1
808  * 104 1
809  * 10 1
810  * 0 1
811  * @cliexend
812  * @endparblock
813  ?*/
814 /* *INDENT-OFF* */
815 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
816  .path = "show ip6 fib",
817  .short_help = "show ip6 fib [summary] [table <table-id>] [index <fib-id>] [<ip6-addr>[/<width>]] [detail]",
818  .function = ip6_show_fib,
819 };
820 /* *INDENT-ON* */
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:197
u8 * format_fib_entry(u8 *s, va_list *args)
Definition: fib_entry.c:104
Continue on to the next entry.
Definition: fib_table.h:857
typedef address
Definition: ip_types.api:34
#define hash_set(h, key, value)
Definition: hash.h:255
fib_protocol_t ft_proto
Which protocol this table serves.
Definition: fib_table.h:74
ip6_fib_t * v6_fibs
Definition: ip6.h:167
#define hash_unset(h, key)
Definition: hash.h:261
The table that stores ALL routes learned by the DP.
Definition: ip6.h:135
#define FIB_ENTRY_FORMAT_DETAIL
Definition: fib_entry.h:508
u64 as_u64[2]
Definition: ip6_packet.h:51
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:520
#define NULL
Definition: clib.h:55
u8 * format_ip6_fib_table_memory(u8 *s, va_list *args)
Definition: ip6_fib.c:569
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:523
int i
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
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static u32 ip6_fib_table_fwding_lookup(ip6_main_t *im, u32 fib_index, const ip6_address_t *dst)
Definition: ip6_fib.h:67
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
static void ip6_fib_table_show_all(ip6_fib_t *fib, vlib_main_t *vm)
Definition: ip6_fib.c:531
u8 * prefix_lengths_in_search_order
Definition: ip6.h:150
unsigned char u8
Definition: types.h:56
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void vnet_ip6_fib_init(u32 fib_index)
Definition: ip6_fib.c:21
fib_node_index_t ip6_fib_table_lookup_exact_match(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:215
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
int clib_bihash_add_del(clib_bihash *h, clib_bihash_kv *add_v, int is_add)
Add or delete a (key,value) pair from a bi-hash table.
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
static BVT(clib_bihash)
Definition: adj_nbr.c:26
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:242
fib_prefix_t * i6w_sub_trees
Definition: ip6_fib.c:409
Aggregrate type for a prefix.
Definition: fib_types.h:188
A represenation of a single IP6 table.
Definition: ip6.h:143
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:192
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:55
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1568
u32 ip6_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_fib.c:323
Definition: fib_entry.h:270
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
#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
enum fib_source_t_ fib_source_t
The different sources that can create a route.
void ip6_fib_table_fwding_dpo_update(u32 fib_index, const ip6_address_t *addr, u32 len, const dpo_id_t *dpo)
Definition: ip6_fib.c:337
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:211
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
void ip6_fib_table_fwding_dpo_remove(u32 fib_index, const ip6_address_t *addr, u32 len, const dpo_id_t *dpo)
Definition: ip6_fib.c:367
u32 ft_total_route_counts
Total route counters.
Definition: fib_table.h:109
u32 index
Definition: ip6.h:76
void ip6_fib_table_walk(u32 fib_index, fib_table_walk_fn_t fn, void *arg)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: ip6_fib.c:474
u32 ip6_fib_table_find_or_create_and_lock(u32 table_id, fib_source_t src)
Get or create an IPv6 fib.
Definition: ip6_fib.c:93
Stop the walk completely.
Definition: fib_table.h:865
void ip6_fib_table_entry_remove(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:254
Context when walking the IPv6 table.
Definition: ip6_fib.c:403
uword * fib_index_by_table_id
Definition: ip6.h:186
unformat_function_t unformat_ip6_address
Definition: format.h:97
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:188
ip6_address_t fib_masks[129]
Definition: ip6.h:173
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 clib_bihash_foreach_key_value_pair(clib_bihash *h, void *callback, void *arg)
Visit active (key,value) pairs in a bi-hash table.
fib_node_index_t ft_index
Index into FIB vector.
Definition: fib_table.h:94
void ip6_fib_table_destroy(u32 fib_index)
Definition: ip6_fib.c:118
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
vlib_main_t * vm
Definition: buffer.c:294
uint32_t mask_width(const boost::asio::ip::address &addr)
Get the prefix mask length of a host route from the boost address.
Definition: prefix.cpp:242
fib_prefix_t i6w_root
Definition: ip6_fib.c:408
u32 ft_flow_hash_config
flow hash configuration
Definition: fib_table.h:99
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:339
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
Definition: fib_table.c:853
u32 ip6_fib_table_create_and_lock(fib_source_t src, fib_table_flags_t flags, u8 *desc)
Definition: ip6_fib.c:110
#define FOR_EACH_FIB_SOURCE(_item)
Definition: fib_entry.h:180
Definition: ip6.h:67
u8 * ft_desc
Table description.
Definition: fib_table.h:114
fib_table_flags_t ft_flags
Table flags.
Definition: fib_table.h:79
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:273
This table stores the routes that are used to forward traffic.
Definition: ip6.h:128
static void compute_prefix_lengths_in_search_order(ip6_fib_table_instance_t *table)
Definition: ip6_fib.c:241
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:516
fib_table_walk_fn_t i6w_fn
Definition: ip6_fib.c:406
fib_table_walk_rc_t(* fib_table_walk_fn_t)(fib_node_index_t fei, void *ctx)
Call back function when walking entries in a FIB table.
Definition: fib_table.h:871
static int ip6_fib_walk_cb(clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: ip6_fib.c:413
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
Definition: fib_table.c:1257
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
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
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:296
#define ASSERT(truth)
int clib_bihash_search_inline_2(clib_bihash *h, clib_bihash_kv *search_key, clib_bihash_kv *valuep)
Search a bi-hash table.
ip6_main_t ip6_main
Definition: ip6_forward.c:2574
long ctx[MAX_CONNS]
Definition: main.c:126
The default route source.
Definition: fib_entry.h:133
i32 dst_address_length_refcounts[129]
Definition: ip6.h:151
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:554
u32 ft_src_route_counts[FIB_SOURCE_MAX]
Per-source route counters.
Definition: fib_table.h:104
#define IP_FLOW_HASH_DEFAULT
Default: 5-tuple without the "reverse" bit.
Definition: lookup.h:69
ip6_fib_table_instance_t ip6_table[IP6_FIB_NUM_TABLES]
The two FIB tables; fwding and non-fwding.
Definition: ip6.h:159
Do no traverse down this sub-tree.
Definition: fib_table.h:861
#define vec_elt(v, i)
Get vector value at index i.
#define FIB_ENTRY_FORMAT_BRIEF
Definition: fib_entry.h:507
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:314
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
#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:609
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:961
void ip6_fib_table_entry_insert(u32 fib_index, const ip6_address_t *addr, u32 len, fib_node_index_t fib_entry_index)
Definition: ip6_fib.c:285
static void count_routes_in_fib_at_prefix_length(BVT(clib_bihash_kv)*kvp, void *arg)
Definition: ip6_fib.c:594
uword * non_empty_dst_address_length_bitmap
Definition: ip6.h:149
Special sources.
Definition: fib_entry.h:40
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
struct ip6_fib_walk_ctx_t_ ip6_fib_walk_ctx_t
Context when walking the IPv6 table.
#define FIB_ENTRY_FORMAT_DETAIL2
Definition: fib_entry.h:509
#define vec_foreach(var, vec)
Vector iterator.
fib_node_index_t ip6_fib_table_lookup(u32 fib_index, const ip6_address_t *addr, u32 len)
Definition: ip6_fib.c:169
u32 table_id
Definition: ip6.h:73
vhost_vring_addr_t addr
Definition: vhost-user.h:83
u32 flags
Definition: vhost-user.h:77
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:62
void ip6_fib_table_sub_tree_walk(u32 fib_index, const fib_prefix_t *root, fib_table_walk_fn_t fn, void *arg)
Walk all entries in a sub-tree of the FIB table N.B: This is NOT safe to deletes. ...
Definition: ip6_fib.c:497
struct fib_table_t_ * fibs
Definition: ip6.h:164
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
u32 * fib_index_by_sw_if_index
Definition: ip6.h:176
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
A protocol Independent FIB table.
Definition: fib_table.h:69
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128