FD.io VPP  v19.04.1-1-ge4a0f9f
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 = 0,
145  .frp_flags = FIB_ROUTE_PATH_LOCAL,
146  };
147 
149  clib_memset(mfib_table, 0, sizeof(*mfib_table));
150 
151  mfib_table->mft_proto = FIB_PROTOCOL_IP6;
152  mfib_table->mft_index =
153  mfib_table->v6.index =
154  (mfib_table - ip6_main.mfibs);
155 
157  table_id,
158  mfib_table->mft_index);
159 
160  mfib_table->mft_table_id =
161  mfib_table->v6.table_id =
162  table_id;
163 
164  mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP6, src);
165 
166  /*
167  * add the special entries into the new FIB
168  */
170  &all_zeros,
174 
175  /*
176  * Add each of the specials
177  */
179  ({
181  &pfx,
183  &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 = 0,
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 = {
236  .frp_addr = zero_addr,
237  .frp_sw_if_index = sw_if_index,
238  .frp_fib_index = ~0,
239  .frp_weight = 0,
240  };
241  mfib_prefix_t pfx = {
243  };
244  u32 mfib_index;
245 
247  mfib_index = ip6_mfib_table_get_index_for_sw_if_index(sw_if_index);
248 
249  if (is_enable)
250  {
252  {
253  mfib_table_entry_path_update(mfib_index,
254  &pfx,
256  &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 {
331  ip6_mfib_key_t key, value;
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 {
355  ip6_mfib_key_t key, value;
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 {
421  ip6_mfib_key_t key, value;
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  s = format(s, "%=30s %=6d %=8s\n",
525  "IPv6 multicast",
526  pool_elts(ip6_main.mfibs), "???");
527 
528  return (s);
529 }
530 
531 static void
533  vlib_main_t * vm,
535  ip6_address_t *grp,
536  u32 mask_len,
537  u32 cover)
538 {
539  if (cover)
540  {
541  vlib_cli_output(vm, "%U",
543  ip6_mfib_table_get_less_specific(mfib, src, grp, mask_len),
545  }
546  else
547  {
548  vlib_cli_output(vm, "%U",
550  ip6_mfib_table_lookup(mfib, src, grp, mask_len),
552  }
553 }
554 
555 typedef struct ip6_mfib_show_ctx_t_ {
558 
559 
560 static int
562 {
563  ip6_mfib_show_ctx_t *ctx = arg;
564 
565  vec_add1(ctx->entries, mfei);
566 
567  return (0);
568 }
569 
570 static void
572  vlib_main_t * vm)
573 {
574  fib_node_index_t *mfib_entry_index;
576  .entries = NULL,
577  };
578 
579  ip6_mfib_table_walk(mfib,
581  &ctx);
582 
584 
585  vec_foreach(mfib_entry_index, ctx.entries)
586  {
587  vlib_cli_output(vm, "%U",
589  *mfib_entry_index,
591  }
592 
593  vec_free(ctx.entries);
594 }
595 
596 /**
597  * @brief Context when walking the IPv6 table. Since all VRFs are in the
598  * same hash table, we need to filter only those we need as we walk
599  */
600 typedef struct ip6_mfib_walk_ctx_t_
601 {
604  void *i6w_ctx;
606 
607 static int
609  void *arg)
610 {
611  ip6_mfib_walk_ctx_t *ctx = arg;
612 
613  if ((kvp->key[4] >> 32) == ctx->i6w_mfib_index)
614  {
615  return (ctx->i6w_fn(kvp->value, ctx->i6w_ctx));
616  }
617  return (FIB_TABLE_WALK_CONTINUE);
618 }
619 
620 void
623  void *arg)
624 {
626  .i6w_mfib_index = mfib->index,
627  .i6w_fn = fn,
628  .i6w_ctx = arg,
629  };
630 
631  clib_bihash_foreach_key_value_pair_40_8(
634  &ctx);
635 }
636 
637 static clib_error_t *
639  unformat_input_t * input,
640  vlib_cli_command_t * cmd)
641 {
642  ip6_main_t * im6 = &ip6_main;
643  mfib_table_t *mfib_table;
644  int verbose, matching;
645  ip6_address_t grp, src = {{0}};
646  u32 mask = 128, cover;
647  int table_id = -1, fib_index = ~0;
648 
649  verbose = 1;
650  matching = 0;
651  cover = 0;
652 
654  {
655  if (unformat (input, "brief") || unformat (input, "summary")
656  || unformat (input, "sum"))
657  verbose = 0;
658 
659  else if (unformat (input, "%U %U",
660  unformat_ip6_address, &src,
661  unformat_ip6_address, &grp))
662  {
663  matching = 1;
664  mask = 256;
665  }
666  else if (unformat (input, "%U/%d", unformat_ip6_address, &grp, &mask))
667  {
668  clib_memset(&src, 0, sizeof(src));
669  matching = 1;
670  }
671  else if (unformat (input, "%U", unformat_ip6_address, &grp))
672  {
673  clib_memset(&src, 0, sizeof(src));
674  matching = 1;
675  mask = 128;
676  }
677  else if (unformat (input, "table %d", &table_id))
678  ;
679  else if (unformat (input, "index %d", &fib_index))
680  ;
681  else if (unformat (input, "cover"))
682  cover = 1;
683  else
684  break;
685  }
686 
687  pool_foreach (mfib_table, im6->mfibs,
688  ({
689  ip6_mfib_t *mfib = &mfib_table->v6;
690 
691  if (table_id >= 0 && table_id != (int)mfib->table_id)
692  continue;
693  if (fib_index != ~0 && fib_index != (int)mfib->index)
694  continue;
695 
696  vlib_cli_output (vm, "%U, fib_index %d",
697  format_mfib_table_name, mfib->index, FIB_PROTOCOL_IP6,
698  mfib->index);
699 
700  /* Show summary? */
701  if (! verbose)
702  {
703  /* vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count"); */
704  /* for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) */
705  /* { */
706  /* uword * hash = mfib->fib_entry_by_dst_address[i]; */
707  /* uword n_elts = hash_elts (hash); */
708  /* if (n_elts > 0) */
709  /* vlib_cli_output (vm, "%20d%16d", i, n_elts); */
710  /* } */
711  continue;
712  }
713 
714  if (!matching)
715  {
716  ip6_mfib_table_show_all(mfib, vm);
717  }
718  else
719  {
720  ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask, cover);
721  }
722  }));
723 
724  return 0;
725 }
726 
727 /*
728  * This command displays the IPv6 MulticasrFIB Tables (VRF Tables) and
729  * the route entries for each table.
730  *
731  * @note This command will run for a long time when the FIB tables are
732  * comprised of millions of entries. For those senarios, consider displaying
733  * a single table or summary mode.
734  *
735  * @cliexpar
736  * Example of how to display all the IPv6 Multicast FIB tables:
737  * @cliexstart{show ip fib}
738  * ipv6-VRF:0, fib_index 0
739  * (*, 0.0.0.0/0): flags:D,
740  * Interfaces:
741  * multicast-ip6-chain
742  * [@1]: dpo-drop ip6
743  * (*, 232.1.1.1/32):
744  * Interfaces:
745  * test-eth1: Forward,
746  * test-eth2: Forward,
747  * test-eth0: Accept,
748  * multicast-ip6-chain
749  * [@2]: dpo-replicate: [index:1 buckets:2 to:[0:0]]
750  * [0] [@1]: ipv6-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
751  * [1] [@1]: ipv6-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
752  *
753  * @cliexend
754  * Example of how to display a summary of all IPv6 FIB tables:
755  * @cliexstart{show ip fib summary}
756  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
757  * Prefix length Count
758  * 0 1
759  * 8 2
760  * 32 4
761  * ipv6-VRF:7, fib_index 1, flow hash: src dst sport dport proto
762  * Prefix length Count
763  * 0 1
764  * 8 2
765  * 24 2
766  * 32 4
767  * @cliexend
768  */
769 /* *INDENT-OFF* */
770 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
771  .path = "show ip6 mfib",
772  .short_help = "show ip mfib [summary] [table <table-id>] [index <fib-id>] [<grp-addr>[/<mask>]] [<grp-addr>] [<src-addr> <grp-addr>]",
773  .function = ip6_show_mfib,
774 };
775 /* *INDENT-ON* */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
u32 sw_if_index
Definition: ipsec_gre.api:37
#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
Continue on to the next entry.
Definition: fib_table.h:868
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:197
A representation of a path as described by a route producer.
Definition: fib_types.h:470
fib_node_index_t * entries
Definition: ip6_mfib.c:556
ip6_mfib_t v6
Definition: mfib_table.h:50
#define NULL
Definition: clib.h:58
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:522
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
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
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
i32 dst_address_length_refcounts[257]
Definition: ip6.h:164
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
u32 mft_total_route_counts
Total route counters.
Definition: mfib_table.h:76
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:235
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:475
void ip6_mfib_table_destroy(ip6_mfib_t *mfib)
Definition: ip6_mfib.c:191
#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:608
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
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:638
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
#define MFIB_RPF_ID_NONE
Definition: fib_types.h:393
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
fib_node_index_t mft_index
Index into FIB vector.
Definition: mfib_table.h:71
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:464
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, mfib_itf_flags_t itf_flags)
Add n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:290
unsigned int u32
Definition: types.h:88
A represenation of a single IP6 mfib table.
Definition: ip6.h:156
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:208
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:96
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
int mfib_entry_cmp_for_sort(void *i1, void *i2)
Definition: mfib_entry.c:1185
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:682
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
u8 ims_byte
The last byte of the mcast address.
Definition: ip6_mfib.c:58
Definition: ip6.h:81
u8 len
Definition: ip_types.api:49
unformat_function_t unformat_ip6_address
Definition: format.h:91
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:230
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:571
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:312
u8 * format_mfib_entry(u8 *s, va_list *args)
Definition: mfib_entry.c:105
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
static int ip6_mfib_table_collect_entries(fib_node_index_t mfei, void *arg)
Definition: ip6_mfib.c:561
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:90
Aggregrate type for a prefix.
Definition: mfib_types.h:24
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
#define ASSERT(truth)
static clib_error_t * ip6_mfib_module_init(vlib_main_t *vm)
Definition: ip6_mfib.c:514
ip6_main_t ip6_main
Definition: ip6_forward.c:2680
u8 ims_scope
The scope of the address.
Definition: ip6_mfib.c:62
uword * non_empty_dst_address_length_bitmap
Definition: ip6.h:162
u16 * prefix_lengths_in_search_order
Definition: ip6.h:163
u32 table_id
Definition: ip6.h:87
mfib_table_walk_fn_t i6w_fn
Definition: ip6_mfib.c:603
static u32 ip6_mfib_index_from_table_id(u32 table_id)
Definition: ip6_mfib.h:95
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip6.h:188
fib_protocol_t mft_proto
Which protocol this table serves.
Definition: mfib_table.h:56
struct ip6_mfib_special_t_ ip6_mfib_special_t
u32 mft_table_id
Table ID (hash key) for this FIB.
Definition: mfib_table.h:66
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:332
#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:532
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:980
typedef key
Definition: ipsec.api:244
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:621
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
int(* 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:447
ip6_mfib_table_instance_t ip6_mtable
the single MFIB table
Definition: ip6.h:177
A protocol Independent IP multicast FIB table.
Definition: mfib_table.h:35
Context when walking the IPv6 table.
Definition: ip6_mfib.c:600
#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:329
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
#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:319
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
clib_bihash_40_8_t ip6_mhash
Definition: ip6.h:159
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:128