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