FD.io VPP  v21.01.1
Vector Packet Processing
ip6_mfib.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/mfib/ip6_mfib.h>
17 
18 #include <vnet/mfib/mfib_table.h>
19 #include <vnet/mfib/mfib_entry.h>
20 #include <vnet/fib/ip6_fib.h>
21 
23 
24 /**
25  * Key and mask for radix
26  */
28 
29 static const mfib_prefix_t all_zeros = {
30  /* (*,*) */
31  .fp_src_addr = {
32  .ip6.as_u64 = {0, 0},
33  },
34  .fp_grp_addr = {
35  .ip6.as_u64 = {0, 0},
36  },
37  .fp_len = 0,
38  .fp_proto = FIB_PROTOCOL_IP6,
39 };
40 
45 
46 typedef struct ip6_mfib_special_t_ {
47  /**
48  * @brief solicited or not
49  */
51 
52  /**
53  * @brief the Prefix length
54  */
56 
57  /**
58  * @brief The last byte of the mcast address
59  */
61  /**
62  * @brief The scope of the address
63  */
66 
67 static const ip6_mfib_special_t ip6_mfib_specials[] =
68 {
69  {
70  /*
71  * Add ff02::1:ff00:0/104 via local route for all tables.
72  * This is required for neighbor discovery to work.
73  */
75  .ims_len = 104,
76  },
77  {
78  /*
79  * all-routers multicast address
80  */
81  .ims_type = IP6_MFIB_SPECIAL_TYPE_NONE,
82  .ims_scope = IP6_MULTICAST_SCOPE_link_local,
83  .ims_byte = IP6_MULTICAST_GROUP_ID_all_routers,
84  .ims_len = 128,
85  },
86  {
87  /*
88  * all-nodes multicast address
89  */
90  .ims_type = IP6_MFIB_SPECIAL_TYPE_NONE,
91  .ims_scope = IP6_MULTICAST_SCOPE_link_local,
92  .ims_byte = IP6_MULTICAST_GROUP_ID_all_hosts,
93  .ims_len = 128,
94  },
95  {
96  /*
97  * Add all-mldv2 multicast address via local route for all tables
98  */
99  .ims_type = IP6_MFIB_SPECIAL_TYPE_NONE,
100  .ims_len = 128,
101  .ims_scope = IP6_MULTICAST_SCOPE_link_local,
102  .ims_byte = IP6_MULTICAST_GROUP_ID_mldv2_routers,
103  }
104 };
105 
106 #define FOR_EACH_IP6_SPECIAL(_pfx, _body) \
107 { \
108  const ip6_mfib_special_t *_spec; \
109  u8 _ii; \
110  for (_ii = 0; \
111  _ii < ARRAY_LEN(ip6_mfib_specials); \
112  _ii++) \
113  { \
114  _spec = &ip6_mfib_specials[_ii]; \
115  if (IP6_MFIB_SPECIAL_TYPE_SOLICITED == _spec->ims_type) \
116  { \
117  ip6_set_solicited_node_multicast_address( \
118  &(_pfx)->fp_grp_addr.ip6, 0); \
119  } \
120  else \
121  { \
122  ip6_set_reserved_multicast_address ( \
123  &(_pfx)->fp_grp_addr.ip6, \
124  _spec->ims_scope, \
125  _spec->ims_byte); \
126  } \
127  (_pfx)->fp_len = _spec->ims_len; \
128  do { _body; } while (0); \
129  } \
130 }
131 
132 
133 static u32
136 {
137  mfib_table_t *mfib_table;
138  mfib_prefix_t pfx = {
140  };
141  const fib_route_path_t path_for_us = {
143  .frp_addr = zero_addr,
144  .frp_sw_if_index = 0xffffffff,
145  .frp_fib_index = ~0,
146  .frp_weight = 1,
147  .frp_flags = FIB_ROUTE_PATH_LOCAL,
148  .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
149  };
150 
152  clib_memset(mfib_table, 0, sizeof(*mfib_table));
153 
154  mfib_table->mft_proto = FIB_PROTOCOL_IP6;
155  mfib_table->mft_index =
156  mfib_table->v6.index =
157  (mfib_table - ip6_main.mfibs);
158 
160  table_id,
161  mfib_table->mft_index);
162 
163  mfib_table->mft_table_id =
164  mfib_table->v6.table_id =
165  table_id;
166 
167  mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP6, src);
168 
169  /*
170  * add the special entries into the new FIB
171  */
173  &all_zeros,
177 
178  /*
179  * Add each of the specials
180  */
182  ({
184  &pfx,
186  &path_for_us);
187  }));
188 
189  return (mfib_table->mft_index);
190 }
191 
192 void
194 {
195  mfib_table_t *mfib_table = (mfib_table_t*)mfib;
196  fib_node_index_t mfei;
197  mfib_prefix_t pfx = {
199  };
200  const fib_route_path_t path_for_us = {
202  .frp_addr = zero_addr,
203  .frp_sw_if_index = 0xffffffff,
204  .frp_fib_index = ~0,
205  .frp_weight = 1,
206  .frp_flags = FIB_ROUTE_PATH_LOCAL,
207  };
208 
209  /*
210  * remove all the specials we added when the table was created.
211  */
213  {
215  &pfx,
217  &path_for_us);
218  });
219 
220  mfei = mfib_table_lookup_exact_match(mfib_table->mft_index, &all_zeros);
222 
223  /*
224  * validate no more routes.
225  */
226  ASSERT(0 == mfib_table->mft_total_route_counts);
227  ASSERT(~0 != mfib_table->mft_table_id);
228 
230  pool_put(ip6_main.mfibs, mfib_table);
231 }
232 
233 void
235 {
236  const fib_route_path_t path = {
237  .frp_proto = DPO_PROTO_IP6,
238  .frp_addr = zero_addr,
239  .frp_sw_if_index = sw_if_index,
240  .frp_fib_index = ~0,
241  .frp_weight = 1,
242  .frp_mitf_flags = MFIB_ITF_FLAG_ACCEPT,
243  };
244  mfib_prefix_t pfx = {
246  };
247  u32 mfib_index;
248 
250  mfib_index = ip6_mfib_table_get_index_for_sw_if_index(sw_if_index);
251 
252  if (is_enable)
253  {
255  {
256  mfib_table_entry_path_update(mfib_index,
257  &pfx,
259  &path);
260  });
261  }
262  else
263  {
265  {
266  mfib_table_entry_path_remove(mfib_index,
267  &pfx,
269  &path);
270  });
271  }
272 }
273 
274 u32
277 {
278  u32 index;
279 
280  index = ip6_mfib_index_from_table_id(table_id);
281  if (~0 == index)
282  return ip6_create_mfib_with_table_id(table_id, src);
283  mfib_table_lock(index, FIB_PROTOCOL_IP6, src);
284 
285  return (index);
286 }
287 
288 u32
290 {
291  if (sw_if_index >= vec_len(ip6_main.mfib_index_by_sw_if_index))
292  {
293  /*
294  * This is the case for interfaces that are not yet mapped to
295  * a IP table
296  */
297  return (~0);
298  }
299  return (ip6_main.mfib_index_by_sw_if_index[sw_if_index]);
300 }
301 
302 #define IPV6_MFIB_GRP_LEN(_len) \
303  (_len > 128 ? 128 : _len)
304 
305 #define IP6_MFIB_MK_KEY(_mfib, _grp, _src, _len, _key) \
306 { \
307  _key.key[0] = (_grp->as_u64[0] & \
308  ip6_main.fib_masks[IPV6_MFIB_GRP_LEN(_len)].as_u64[0]); \
309  _key.key[1] = (_grp->as_u64[1] & \
310  ip6_main.fib_masks[IPV6_MFIB_GRP_LEN(_len)].as_u64[1]); \
311  if (_len == 256) { \
312  _key.key[2] = _src->as_u64[0]; \
313  _key.key[3] = _src->as_u64[1]; \
314  } else { \
315  _key.key[2] = 0; \
316  _key.key[3] = 0; \
317  } \
318  _key.key[4] = _mfib->index; \
319  _key.key[4] = (_key.key[4] << 32) | len; \
320 }
321 
322 /*
323  * ip6_fib_table_lookup_exact_match
324  *
325  * Exact match prefix lookup
326  */
329  const ip6_address_t *grp,
330  const ip6_address_t *src,
331  u32 len)
332 {
334  int rv;
335 
336  IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
337 
338  rv = clib_bihash_search_inline_2_40_8(&ip6_mfib_table.ip6_mhash,
339  &key, &value);
340  if (rv == 0)
341  return value.value;
342 
343  return (FIB_NODE_INDEX_INVALID);
344 }
345 
346 /*
347  * ip6_fib_table_lookup
348  *
349  * Longest prefix match for the forwarding plane (no mask given)
350  */
353  const ip6_address_t *src,
354  const ip6_address_t *grp)
355 {
358  int i, n, len;
359  int rv;
360 
361  table = &ip6_mfib_table;
363 
364  for (i = 0; i < n; i++)
365  {
366  len = table->prefix_lengths_in_search_order[i];
367 
368  ASSERT(len >= 0 && len <= 256);
369  IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
370  rv = clib_bihash_search_inline_2_40_8(&table->ip6_mhash, &key, &value);
371  if (rv == 0)
372  return value.value;
373  }
374 
375  return (FIB_NODE_INDEX_INVALID);
376 }
377 
378 
381  const ip6_address_t *src,
382  const ip6_address_t *grp,
383  u32 len)
384 {
385  u32 mask_len;
386 
387  /*
388  * in the absence of a tree structure for the table that allows for an O(1)
389  * parent get, a cheeky way to find the cover is to LPM for the prefix with
390  * mask-1.
391  * there should always be a cover, though it may be the default route. the
392  * default route's cover is the default route.
393  */
394  if (len == 256)
395  {
396  /* go from (S,G) to (*,G*) */
397  mask_len = 128;
398  }
399  else if (len != 0)
400  {
401  mask_len = len - 1;
402  }
403  else
404  {
405  mask_len = len;
406  }
407 
408  return (ip6_mfib_table_lookup(mfib, src, grp, mask_len));
409 }
410 
411 /*
412  * ip6_fib_table_lookup
413  *
414  * Longest prefix match
415  */
418  const ip6_address_t *src,
419  const ip6_address_t *grp,
420  u32 len)
421 {
424  int i, n, rv;
425 
426  table = &ip6_mfib_table;
428 
429  /*
430  * start search from a mask length same length or shorter.
431  * we don't want matches longer than the mask passed
432  */
433  i = 0;
434  while (i < n && table->prefix_lengths_in_search_order[i] > len)
435  {
436  i++;
437  }
438 
439  for (; i < n; i++)
440  {
441  len = table->prefix_lengths_in_search_order[i];
442 
443  ASSERT(len <= 256);
444  IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
445 
446  rv = clib_bihash_search_inline_2_40_8(&table->ip6_mhash, &key, &value);
447  if (rv == 0)
448  return value.value;
449  }
450 
451  return (FIB_NODE_INDEX_INVALID);
452 }
453 
454 static void
456 {
457  int i;
459  /* Note: bitmap reversed so this is in fact a longest prefix match */
461  {
462  vec_add1(table->prefix_lengths_in_search_order, (256 - i));
463  }
464 }
465 
466 void
468  const ip6_address_t *grp,
469  const ip6_address_t *src,
470  u32 len,
471  fib_node_index_t mfib_entry_index)
472 {
475 
476  table = &ip6_mfib_table;
477  IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
478  key.value = mfib_entry_index;
479 
480  clib_bihash_add_del_40_8(&table->ip6_mhash, &key, 1);
481 
482  if (0 == table->dst_address_length_refcounts[len]++)
483  {
486  256 - len, 1);
488  }
489 }
490 
491 void
493  const ip6_address_t *grp,
494  const ip6_address_t *src,
495  u32 len)
496 {
499 
500  IP6_MFIB_MK_KEY(mfib, grp, src, len, key);
501 
502  table = &ip6_mfib_table;
503  clib_bihash_add_del_40_8(&table->ip6_mhash, &key, 0);
504 
505  ASSERT (table->dst_address_length_refcounts[len] > 0);
506  if (--table->dst_address_length_refcounts[len] == 0)
507  {
510  256 - len, 0);
512  }
513 }
514 
515 static clib_error_t *
517 {
518  return (NULL);
519 }
520 
522 
523 u8 *
524 format_ip6_mfib_table_memory (u8 * s, va_list * args)
525 {
526  u64 bytes_inuse;
527 
528  bytes_inuse = alloc_arena_next(&(ip6_mfib_table.ip6_mhash));
529 
530  s = format(s, "%=30s %=6d %=12ld\n",
531  "IPv6 multicast",
533  bytes_inuse);
534 
535  return (s);
536 }
537 
538 static void
540  vlib_main_t * vm,
541  ip6_address_t *src,
542  ip6_address_t *grp,
543  u32 mask_len,
544  u32 cover)
545 {
546  if (cover)
547  {
548  vlib_cli_output(vm, "%U",
550  ip6_mfib_table_get_less_specific(mfib, src, grp, mask_len),
552  }
553  else
554  {
555  vlib_cli_output(vm, "%U",
557  ip6_mfib_table_lookup(mfib, src, grp, mask_len),
559  }
560 }
561 
562 typedef struct ip6_mfib_show_ctx_t_ {
565 
566 
567 static walk_rc_t
569 {
570  ip6_mfib_show_ctx_t *ctx = arg;
571 
572  vec_add1(ctx->entries, mfei);
573 
574  return (WALK_CONTINUE);
575 }
576 
577 static void
579  vlib_main_t * vm)
580 {
581  fib_node_index_t *mfib_entry_index;
583  .entries = NULL,
584  };
585 
586  ip6_mfib_table_walk(mfib,
588  &ctx);
589 
591 
592  vec_foreach(mfib_entry_index, ctx.entries)
593  {
594  vlib_cli_output(vm, "%U",
596  *mfib_entry_index,
598  }
599 
600  vec_free(ctx.entries);
601 }
602 
603 /**
604  * @brief Context when walking the IPv6 table. Since all VRFs are in the
605  * same hash table, we need to filter only those we need as we walk
606  */
607 typedef struct ip6_mfib_walk_ctx_t_
608 {
611  void *i6w_ctx;
613 
614 static int
616  void *arg)
617 {
618  ip6_mfib_walk_ctx_t *ctx = arg;
619 
620  if ((kvp->key[4] >> 32) == ctx->i6w_mfib_index)
621  {
622  ctx->i6w_fn(kvp->value, ctx->i6w_ctx);
623  }
624  return (BIHASH_WALK_CONTINUE);
625 }
626 
627 void
630  void *arg)
631 {
633  .i6w_mfib_index = mfib->index,
634  .i6w_fn = fn,
635  .i6w_ctx = arg,
636  };
637 
638  clib_bihash_foreach_key_value_pair_40_8(
639  &ip6_mfib_table.ip6_mhash,
641  &ctx);
642 }
643 
644 static clib_error_t *
646  unformat_input_t * input,
647  vlib_cli_command_t * cmd)
648 {
649  ip6_main_t * im6 = &ip6_main;
650  mfib_table_t *mfib_table;
651  int verbose, matching;
652  ip6_address_t grp, src = {{0}};
653  u32 mask = 128, cover;
654  int table_id = -1, fib_index = ~0;
655 
656  verbose = 1;
657  matching = 0;
658  cover = 0;
659 
661  {
662  if (unformat (input, "brief") || unformat (input, "summary")
663  || unformat (input, "sum"))
664  verbose = 0;
665 
666  else if (unformat (input, "%U %U",
667  unformat_ip6_address, &src,
668  unformat_ip6_address, &grp))
669  {
670  matching = 1;
671  mask = 256;
672  }
673  else if (unformat (input, "%U/%d", unformat_ip6_address, &grp, &mask))
674  {
675  clib_memset(&src, 0, sizeof(src));
676  matching = 1;
677  }
678  else if (unformat (input, "%U", unformat_ip6_address, &grp))
679  {
680  clib_memset(&src, 0, sizeof(src));
681  matching = 1;
682  mask = 128;
683  }
684  else if (unformat (input, "table %d", &table_id))
685  ;
686  else if (unformat (input, "index %d", &fib_index))
687  ;
688  else if (unformat (input, "cover"))
689  cover = 1;
690  else
691  break;
692  }
693 
694  pool_foreach (mfib_table, im6->mfibs)
695  {
696  ip6_mfib_t *mfib = &mfib_table->v6;
697 
698  if (table_id >= 0 && table_id != (int)mfib->table_id)
699  continue;
700  if (fib_index != ~0 && fib_index != (int)mfib->index)
701  continue;
702 
703  vlib_cli_output (vm, "%U, fib_index %d",
705  mfib->index);
706 
707  /* Show summary? */
708  if (! verbose)
709  {
710  /* vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count"); */
711  /* for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) */
712  /* { */
713  /* uword * hash = mfib->fib_entry_by_dst_address[i]; */
714  /* uword n_elts = hash_elts (hash); */
715  /* if (n_elts > 0) */
716  /* vlib_cli_output (vm, "%20d%16d", i, n_elts); */
717  /* } */
718  continue;
719  }
720 
721  if (!matching)
722  {
723  ip6_mfib_table_show_all(mfib, vm);
724  }
725  else
726  {
727  ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask, cover);
728  }
729  }
730 
731  return 0;
732 }
733 
734 /*
735  * This command displays the IPv6 MulticasrFIB Tables (VRF Tables) and
736  * the route entries for each table.
737  *
738  * @note This command will run for a long time when the FIB tables are
739  * comprised of millions of entries. For those senarios, consider displaying
740  * a single table or summary mode.
741  *
742  * @cliexpar
743  * Example of how to display all the IPv6 Multicast FIB tables:
744  * @cliexstart{show ip fib}
745  * ipv6-VRF:0, fib_index 0
746  * (*, 0.0.0.0/0): flags:D,
747  * Interfaces:
748  * multicast-ip6-chain
749  * [@1]: dpo-drop ip6
750  * (*, 232.1.1.1/32):
751  * Interfaces:
752  * test-eth1: Forward,
753  * test-eth2: Forward,
754  * test-eth0: Accept,
755  * multicast-ip6-chain
756  * [@2]: dpo-replicate: [index:1 buckets:2 to:[0:0]]
757  * [0] [@1]: ipv6-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
758  * [1] [@1]: ipv6-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
759  *
760  * @cliexend
761  * Example of how to display a summary of all IPv6 FIB tables:
762  * @cliexstart{show ip fib summary}
763  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
764  * Prefix length Count
765  * 0 1
766  * 8 2
767  * 32 4
768  * ipv6-VRF:7, fib_index 1, flow hash: src dst sport dport proto
769  * Prefix length Count
770  * 0 1
771  * 8 2
772  * 24 2
773  * 32 4
774  * @cliexend
775  */
776 /* *INDENT-OFF* */
777 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
778  .path = "show ip6 mfib",
779  .short_help = "show ip mfib [summary] [table <table-id>] [index <fib-id>] [<grp-addr>[/<mask>]] [<grp-addr>] [<src-addr> <grp-addr>]",
780  .function = ip6_show_mfib,
781 };
782 /* *INDENT-ON* */
783 
784 static clib_error_t *
786 {
787  clib_bihash_init_40_8 (&ip6_mfib_table.ip6_mhash,
788  "ip6 mFIB table",
791 
792  return (NULL);
793 }
794 
796 {
797  .runs_before = VLIB_INITS("ip6_lookup_init"),
798 };
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
#define MFIB_ENTRY_FORMAT_DETAIL
Definition: mfib_entry.h:111
ip6_mfib_special_type_t ims_type
solicited or not
Definition: ip6_mfib.c:50
ip46_address_t fp_src_addr
Definition: mfib_types.h:47
#define hash_set(h, key, value)
Definition: hash.h:255
enum ip6_mfib_special_type_t_ ip6_mfib_special_type_t
#define hash_unset(h, key)
Definition: hash.h:261
u32 * mfib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip6.h:130
A representation of a path as described by a route producer.
Definition: fib_types.h:500
fib_node_index_t * entries
Definition: ip6_mfib.c:563
ip6_mfib_t v6
Definition: mfib_table.h:86
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
fib_node_index_t mfib_table_entry_path_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Add n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:325
unsigned long u64
Definition: types.h:89
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define clib_bitmap_foreach(i, ai)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
fib_node_index_t ip6_mfib_table_get_less_specific(const ip6_mfib_t *mfib, const ip6_address_t *src, const ip6_address_t *grp, u32 len)
Definition: ip6_mfib.c:380
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
fib_node_index_t ip6_mfib_table_lookup(const ip6_mfib_t *mfib, const ip6_address_t *src, const ip6_address_t *grp, u32 len)
Definition: ip6_mfib.c:417
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
i32 dst_address_length_refcounts[257]
Definition: ip6_mfib.h:54
fib_node_index_t ip6_mfib_table_fwd_lookup(const ip6_mfib_t *mfib, const ip6_address_t *src, const ip6_address_t *grp)
Definition: ip6_mfib.c:352
vlib_main_t * vm
Definition: in2out_ed.c:1580
u32 mft_total_route_counts
Total route counters.
Definition: mfib_table.h:122
fib_node_index_t mfib_table_entry_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, fib_rpf_id_t rpf_id, mfib_entry_flags_t entry_flags)
Add a new (with no replication) or lock an existing entry.
Definition: mfib_table.c:237
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:505
void ip6_mfib_table_destroy(ip6_mfib_t *mfib)
Definition: ip6_mfib.c:193
vl_api_fib_path_t path
Definition: mfib_types.api:44
u16 mask
Definition: flow_types.api:52
#define MFIB_ENTRY_FORMAT_BRIEF
Definition: mfib_entry.h:110
unsigned char u8
Definition: types.h:56
static int ip6_mfib_walk_cb(clib_bihash_kv_40_8_t *kvp, void *arg)
Definition: ip6_mfib.c:615
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
enum walk_rc_t_ walk_rc_t
Walk return code.
u32 ip6_mfib_table_find_or_create_and_lock(u32 table_id, mfib_source_t src)
Get or create an IPv4 fib.
Definition: ip6_mfib.c:275
clib_bihash_kv_40_8_t ip6_mfib_key_t
Key and mask for radix.
Definition: ip6_mfib.c:27
enum mfib_source_t_ mfib_source_t
Possible [control plane] sources of MFIB entries.
u8 ims_len
the Prefix length
Definition: ip6_mfib.c:55
static clib_error_t * ip6_show_mfib(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip6_mfib.c:645
#define MFIB_RPF_ID_NONE
Definition: fib_types.h:423
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
fib_node_index_t mft_index
Index into FIB vector.
Definition: mfib_table.h:117
void mfib_table_entry_delete_index(fib_node_index_t mfib_entry_index, mfib_source_t source)
Delete a FIB entry.
Definition: mfib_table.c:517
description fragment has unexpected format
Definition: map.api:433
unsigned int u32
Definition: types.h:88
A representation of a single IP6 mfib table.
Definition: ip6_mfib.h:46
void ip6_mfib_table_entry_insert(ip6_mfib_t *mfib, const ip6_address_t *grp, const ip6_address_t *src, u32 len, fib_node_index_t mfib_entry_index)
Definition: ip6_mfib.c:467
ip6_mfib_special_type_t_
Definition: ip6_mfib.c:41
struct ip6_mfib_show_ctx_t_ ip6_mfib_show_ctx_t
uword * mfib_index_by_table_id
Hash table mapping table id to multicast fib index.
Definition: ip6.h:141
u8 * format_ip6_mfib_table_memory(u8 *s, va_list *args)
format (display) ipv6 MFIB mempry usage
Definition: ip6_mfib.c:524
struct ip6_mfib_walk_ctx_t_ ip6_mfib_walk_ctx_t
Context when walking the IPv6 table.
long ctx[MAX_CONNS]
Definition: main.c:144
fib_node_index_t mfib_table_lookup_exact_match(u32 fib_index, const mfib_prefix_t *prefix)
Perfom an exact match in the non-forwarding table.
Definition: mfib_table.c:98
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
int mfib_entry_cmp_for_sort(void *i1, void *i2)
Definition: mfib_entry.c:1313
ip6_main_t ip6_main
Definition: ip6_forward.c:2785
void mfib_table_lock(u32 fib_index, fib_protocol_t proto, mfib_source_t source)
Release a reference counting lock on the table.
Definition: mfib_table.c:806
u8 ims_byte
The last byte of the mcast address.
Definition: ip6_mfib.c:60
Definition: ip6.h:73
u8 len
Definition: ip_types.api:103
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
void ip6_mfib_interface_enable_disable(u32 sw_if_index, int is_enable)
Add/remove the interface from the accepting list of the special MFIB entries.
Definition: ip6_mfib.c:234
u32 ip6_mfib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_mfib.c:289
static void ip6_mfib_table_show_all(ip6_mfib_t *mfib, vlib_main_t *vm)
Definition: ip6_mfib.c:578
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
u8 * format_mfib_entry(u8 *s, va_list *args)
Definition: mfib_entry.c:126
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static u32 ip6_create_mfib_with_table_id(u32 table_id, mfib_source_t src)
Definition: ip6_mfib.c:134
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
u32 index
Definition: ip6.h:82
Aggregate type for a prefix.
Definition: mfib_types.h:24
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
u8 value
Definition: qos.api:54
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
#define IP6_MFIB_DEFAULT_HASH_NUM_BUCKETS
The IPv4 Multicast-FIB.
Definition: ip6_mfib.h:39
static clib_error_t * ip6_mfib_module_init(vlib_main_t *vm)
Definition: ip6_mfib.c:516
u8 ims_scope
The scope of the address.
Definition: ip6_mfib.c:64
uword * non_empty_dst_address_length_bitmap
Definition: ip6_mfib.h:52
u16 * prefix_lengths_in_search_order
Definition: ip6_mfib.h:53
ip6_mfib_table_instance_t ip6_mfib_table
the single MFIB table
Definition: ip6_mfib.c:22
u32 table_id
Definition: ip6.h:79
mfib_table_walk_fn_t i6w_fn
Definition: ip6_mfib.c:610
static u32 ip6_mfib_index_from_table_id(u32 table_id)
Definition: ip6_mfib.h:124
walk_rc_t(* mfib_table_walk_fn_t)(fib_node_index_t fei, void *ctx)
Call back function when walking entries in a FIB table.
Definition: mfib_table.h:554
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip6.h:121
fib_protocol_t mft_proto
Which protocol this table serves.
Definition: mfib_table.h:92
struct ip6_mfib_special_t_ ip6_mfib_special_t
static walk_rc_t ip6_mfib_table_collect_entries(fib_node_index_t mfei, void *arg)
Definition: ip6_mfib.c:568
u32 mft_table_id
Table ID (hash key) for this FIB.
Definition: mfib_table.h:107
static clib_error_t * ip6_mfib_init(vlib_main_t *vm)
Definition: ip6_mfib.c:785
typedef key
Definition: ipsec_types.api:86
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
fib_node_index_t ip6_mfib_table_lookup_exact_match(const ip6_mfib_t *mfib, const ip6_address_t *grp, const ip6_address_t *src, u32 len)
Definition: ip6_mfib.c:328
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
A for-us/local path.
Definition: fib_types.h:344
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void ip6_mfib_table_show_one(ip6_mfib_t *mfib, vlib_main_t *vm, ip6_address_t *src, ip6_address_t *grp, u32 mask_len, u32 cover)
Definition: ip6_mfib.c:539
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1055
u32 table_id
Definition: wireguard.api:102
u32 index
Definition: flow_types.api:221
void ip6_mfib_table_walk(ip6_mfib_t *mfib, mfib_table_walk_fn_t fn, void *arg)
Walk the IP6 mfib table.
Definition: ip6_mfib.c:628
void ip6_mfib_table_entry_remove(ip6_mfib_t *mfib, const ip6_address_t *grp, const ip6_address_t *src, u32 len)
Definition: ip6_mfib.c:492
A protocol Independent IP multicast FIB table.
Definition: mfib_table.h:71
#define IP6_MFIB_DEFAULT_HASH_MEMORY_SIZE
Definition: ip6_mfib.h:40
Context when walking the IPv6 table.
Definition: ip6_mfib.c:607
#define vec_foreach(var, vec)
Vector iterator.
static void compute_prefix_lengths_in_search_order(ip6_mfib_table_instance_t *table)
Definition: ip6_mfib.c:455
void mfib_table_entry_path_remove(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:407
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
#define VLIB_INITS(...)
Definition: init.h:357
u8 * format_mfib_table_name(u8 *s, va_list *ap)
Format the description/name of the table.
Definition: mfib_table.c:868
#define FOR_EACH_IP6_SPECIAL(_pfx, _body)
Definition: ip6_mfib.c:106
#define IP6_MFIB_MK_KEY(_mfib, _grp, _src, _len, _key)
Definition: ip6_mfib.c:305
const ip46_address_t zero_addr
#include <vnet/feature/feature.h>
Definition: lookup.c:180
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
clib_bihash_40_8_t ip6_mhash
Definition: ip6_mfib.h:49
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:127