FD.io VPP  v18.07-rc0-415-g6c78436
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  * The number of bytes in an address/ask key in the radix tree
24  * First byte is the length in bytes.
25  */
26 #define IP6_MFIB_KEY_LEN 33
27 
28 /**
29  * Key and mask for radix
30  */
31 typedef struct ip6_mfib_key_t_
32 {
36 
37 /**
38  * An object that is inserted into the radix tree.
39  * Since it's in the tree and has pointers, it cannot realloc and so cannot
40  * come from a vlib pool.
41  */
42 typedef struct ip6_mfib_node_t_
43 {
44  struct radix_node i6mn_nodes[2];
48 
49 static const mfib_prefix_t all_zeros = {
50  /* (*,*) */
51  .fp_src_addr = {
52  .ip6.as_u64 = {0, 0},
53  },
54  .fp_grp_addr = {
55  .ip6.as_u64 = {0, 0},
56  },
57  .fp_len = 0,
58  .fp_proto = FIB_PROTOCOL_IP6,
59 };
60 
65 
66 typedef struct ip6_mfib_special_t_ {
67  /**
68  * @brief solicited or not
69  */
71 
72  /**
73  * @brief the Prefix length
74  */
76 
77  /**
78  * @brief The last byte of the mcast address
79  */
81  /**
82  * @brief The scope of the address
83  */
86 
87 static const ip6_mfib_special_t ip6_mfib_specials[] =
88 {
89  {
90  /*
91  * Add ff02::1:ff00:0/104 via local route for all tables.
92  * This is required for neighbor discovery to work.
93  */
95  .ims_len = 104,
96  },
97  {
98  /*
99  * all-routers multicast address
100  */
101  .ims_type = IP6_MFIB_SPECIAL_TYPE_NONE,
102  .ims_scope = IP6_MULTICAST_SCOPE_link_local,
103  .ims_byte = IP6_MULTICAST_GROUP_ID_all_routers,
104  .ims_len = 128,
105  },
106  {
107  /*
108  * all-nodes multicast address
109  */
110  .ims_type = IP6_MFIB_SPECIAL_TYPE_NONE,
111  .ims_scope = IP6_MULTICAST_SCOPE_link_local,
112  .ims_byte = IP6_MULTICAST_GROUP_ID_all_hosts,
113  .ims_len = 128,
114  },
115  {
116  /*
117  * Add all-mldv2 multicast address via local route for all tables
118  */
119  .ims_type = IP6_MFIB_SPECIAL_TYPE_NONE,
120  .ims_len = 128,
121  .ims_scope = IP6_MULTICAST_SCOPE_link_local,
122  .ims_byte = IP6_MULTICAST_GROUP_ID_mldv2_routers,
123  }
124 };
125 
126 #define FOR_EACH_IP6_SPECIAL(_pfx, _body) \
127 { \
128  const ip6_mfib_special_t *_spec; \
129  u8 _ii; \
130  for (_ii = 0; \
131  _ii < ARRAY_LEN(ip6_mfib_specials); \
132  _ii++) \
133  { \
134  _spec = &ip6_mfib_specials[_ii]; \
135  if (IP6_MFIB_SPECIAL_TYPE_SOLICITED == _spec->ims_type) \
136  { \
137  ip6_set_solicited_node_multicast_address( \
138  &(_pfx)->fp_grp_addr.ip6, 0); \
139  } \
140  else \
141  { \
142  ip6_set_reserved_multicast_address ( \
143  &(_pfx)->fp_grp_addr.ip6, \
144  _spec->ims_scope, \
145  _spec->ims_byte); \
146  } \
147  (_pfx)->fp_len = _spec->ims_len; \
148  do { _body; } while (0); \
149  } \
150 }
151 
152 
153 static u32
155  mfib_source_t src)
156 {
157  mfib_table_t *mfib_table;
158  mfib_prefix_t pfx = {
160  };
161  const fib_route_path_t path_for_us = {
163  .frp_addr = zero_addr,
164  .frp_sw_if_index = 0xffffffff,
165  .frp_fib_index = ~0,
166  .frp_weight = 0,
167  .frp_flags = FIB_ROUTE_PATH_LOCAL,
168  };
169 
171  memset(mfib_table, 0, sizeof(*mfib_table));
172 
173  mfib_table->mft_proto = FIB_PROTOCOL_IP6;
174  mfib_table->mft_index =
175  mfib_table->v6.index =
176  (mfib_table - ip6_main.mfibs);
177 
179  table_id,
180  mfib_table->mft_index);
181 
182  mfib_table->mft_table_id =
183  mfib_table->v6.table_id =
184  table_id;
185 
186  mfib_table_lock(mfib_table->mft_index, FIB_PROTOCOL_IP6, src);
187 
188  mfib_table->v6.rhead =
189  clib_mem_alloc_aligned (sizeof(*mfib_table->v6.rhead),
191  rn_inithead0(mfib_table->v6.rhead, 8);
192 
193  /*
194  * add the special entries into the new FIB
195  */
197  &all_zeros,
201 
202  /*
203  * Add each of the specials
204  */
206  ({
208  &pfx,
210  &path_for_us,
212  }));
213 
214  return (mfib_table->mft_index);
215 }
216 
217 void
219 {
220  mfib_table_t *mfib_table = (mfib_table_t*)mfib;
221  fib_node_index_t mfei;
222  mfib_prefix_t pfx = {
224  };
225  const fib_route_path_t path_for_us = {
227  .frp_addr = zero_addr,
228  .frp_sw_if_index = 0xffffffff,
229  .frp_fib_index = ~0,
230  .frp_weight = 0,
231  .frp_flags = FIB_ROUTE_PATH_LOCAL,
232  };
233 
234  /*
235  * remove all the specials we added when the table was created.
236  */
238  {
240  &pfx,
242  &path_for_us);
243  });
244 
245  mfei = mfib_table_lookup_exact_match(mfib_table->mft_index, &all_zeros);
247 
248  /*
249  * validate no more routes.
250  */
251  ASSERT(0 == mfib_table->mft_total_route_counts);
252  ASSERT(~0 != mfib_table->mft_table_id);
253 
255  clib_mem_free(mfib_table->v6.rhead);
256  pool_put(ip6_main.mfibs, mfib_table);
257 }
258 
259 void
260 ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
261 {
262  const fib_route_path_t path = {
264  .frp_addr = zero_addr,
265  .frp_sw_if_index = sw_if_index,
266  .frp_fib_index = ~0,
267  .frp_weight = 0,
268  };
269  mfib_prefix_t pfx = {
271  };
272  u32 mfib_index;
273 
275  mfib_index = ip6_mfib_table_get_index_for_sw_if_index(sw_if_index);
276 
277  if (is_enable)
278  {
280  {
281  mfib_table_entry_path_update(mfib_index,
282  &pfx,
284  &path,
286  });
287  }
288  else
289  {
291  {
292  mfib_table_entry_path_remove(mfib_index,
293  &pfx,
295  &path);
296  });
297  }
298 }
299 
300 u32
302  mfib_source_t src)
303 {
304  u32 index;
305 
306  index = ip6_mfib_index_from_table_id(table_id);
307  if (~0 == index)
308  return ip6_create_mfib_with_table_id(table_id, src);
309  mfib_table_lock(index, FIB_PROTOCOL_IP6, src);
310 
311  return (index);
312 }
313 
314 u32
316 {
317  if (sw_if_index >= vec_len(ip6_main.mfib_index_by_sw_if_index))
318  {
319  /*
320  * This is the case for interfaces that are not yet mapped to
321  * a IP table
322  */
323  return (~0);
324  }
325  return (ip6_main.mfib_index_by_sw_if_index[sw_if_index]);
326 }
327 
328 #define IP6_MFIB_MK_KEY(_grp, _src, _key) \
329 { \
330  (_key)->key[0] = 33; \
331  memcpy((_key)->key+1, _grp, 16); \
332  memcpy((_key)->key+17, _src, 16); \
333 }
334 
335 #define IP6_MFIB_MK_KEY_MASK(_grp, _src, _len, _key) \
336 { \
337  IP6_MFIB_MK_KEY(_grp, _src, _key); \
338  \
339  (_key)->mask[0] = 33; \
340  if (_len <= 128) \
341  { \
342  memcpy((_key)->mask+1, &ip6_main.fib_masks[_len], 16); \
343  memset((_key)->mask+17, 0, 16); \
344  } \
345  else \
346  { \
347  ASSERT(_len == 256); \
348  memcpy((_key)->mask+1, &ip6_main.fib_masks[128], 16); \
349  memcpy((_key)->mask+17, &ip6_main.fib_masks[128], 16); \
350  } \
351 }
352 
353 /*
354  * ip6_fib_table_lookup_exact_match
355  *
356  * Exact match prefix lookup
357  */
360  const ip6_address_t *grp,
361  const ip6_address_t *src,
362  u32 len)
363 {
364  ip6_mfib_node_t *i6mn;
366 
367  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
368 
369  i6mn = (ip6_mfib_node_t*) rn_lookup(key.key, key.mask,
370  (struct radix_node_head *)mfib->rhead);
371 
372  if (NULL == i6mn)
373  {
374  return (INDEX_INVALID);
375  }
376 
377  return (i6mn->i6mn_entry);
378 }
379 
380 /*
381  * ip6_fib_table_lookup
382  *
383  * Longest prefix match
384  */
387  const ip6_address_t *src,
388  const ip6_address_t *grp,
389  u32 len)
390 {
391  ip6_mfib_node_t *i6mn;
393 
394  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
395 
396  i6mn = (ip6_mfib_node_t*) rn_search_m(key.key,
397  mfib->rhead->rnh_treetop,
398  key.mask);
399 
400  ASSERT(NULL != i6mn);
401 
402  return (i6mn->i6mn_entry);
403 }
404 
405 /*
406  * ip6_fib_table_lookup
407  *
408  * Longest prefix match no mask
409  */
412  const ip6_address_t *src,
413  const ip6_address_t *grp)
414 {
415  ip6_mfib_node_t *i6mn;
417 
418  IP6_MFIB_MK_KEY(grp, src, &key);
419 
420  i6mn = (ip6_mfib_node_t*) rn_match(key.key,
421  (struct radix_node_head *)mfib->rhead); // const cast
422 
423  ASSERT(NULL != i6mn);
424 
425  return (i6mn->i6mn_entry);
426 }
427 
428 void
430  const ip6_address_t *grp,
431  const ip6_address_t *src,
432  u32 len,
433  fib_node_index_t mfib_entry_index)
434 {
435  ip6_mfib_node_t *i6mn = clib_mem_alloc(sizeof(*i6mn));
436 
437  memset(i6mn->i6mn_nodes, 0, sizeof(i6mn->i6mn_nodes));
438 
439  IP6_MFIB_MK_KEY_MASK(grp, src, len, &i6mn->i6mn_key);
440  i6mn->i6mn_entry = mfib_entry_index;
441 
442  if (NULL == rn_addroute(i6mn->i6mn_key.key,
443  i6mn->i6mn_key.mask,
444  mfib->rhead,
445  i6mn->i6mn_nodes))
446  {
447  ASSERT(0);
448  }
449 }
450 
451 void
453  const ip6_address_t *grp,
454  const ip6_address_t *src,
455  u32 len)
456 {
457  ip6_mfib_node_t *i6mn;
459 
460  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
461 
462  i6mn = (ip6_mfib_node_t*) rn_delete(key.key, key.mask, mfib->rhead);
463 
464  clib_mem_free(i6mn);
465 }
466 
467 static clib_error_t *
469 {
470  return (NULL);
471 }
472 
474 
475 u8 *
476 format_ip6_mfib_table_memory (u8 * s, va_list * args)
477 {
478  s = format(s, "%=30s %=6d %=8s\n",
479  "IPv6 multicast",
480  pool_elts(ip6_main.mfibs), "???");
481 
482  return (s);
483 }
484 
485 static void
487  vlib_main_t * vm,
488  ip6_address_t *src,
489  ip6_address_t *grp,
490  u32 mask_len)
491 {
492  vlib_cli_output(vm, "%U",
494  ip6_mfib_table_lookup(mfib, src, grp, mask_len),
496 }
497 
498 typedef struct ip6_mfib_show_ctx_t_ {
501 
502 
503 static int
505 {
506  ip6_mfib_show_ctx_t *ctx = arg;
507 
508  vec_add1(ctx->entries, mfei);
509 
510  return (0);
511 }
512 
513 static void
515  vlib_main_t * vm)
516 {
517  fib_node_index_t *mfib_entry_index;
519  .entries = NULL,
520  };
521 
522  ip6_mfib_table_walk(mfib,
524  &ctx);
525 
527 
528  vec_foreach(mfib_entry_index, ctx.entries)
529  {
530  vlib_cli_output(vm, "%U",
532  *mfib_entry_index,
534  }
535 
536  vec_free(ctx.entries);
537 }
538 
540 {
542  void *user_ctx;
544 
545 static int
547  void *arg)
548 {
550  ip6_mfib_node_t *i6mn;
551 
552  i6mn = (ip6_mfib_node_t*) rn;
553 
554  ctx->user_fn(i6mn->i6mn_entry, ctx->user_ctx);
555 
556  return (0);
557 }
558 
559 void
562  void *ctx)
563 {
564  ip6_mfib_radix_walk_ctx_t rn_ctx = {
565  .user_fn = fn,
566  .user_ctx = ctx,
567  };
568 
569  rn_walktree(mfib->rhead,
571  &rn_ctx);
572 }
573 
574 static clib_error_t *
576  unformat_input_t * input,
577  vlib_cli_command_t * cmd)
578 {
579  ip6_main_t * im6 = &ip6_main;
580  mfib_table_t *mfib_table;
581  int verbose, matching;
582  ip6_address_t grp, src = {{0}};
583  u32 mask = 32;
584  int table_id = -1, fib_index = ~0;
585 
586  verbose = 1;
587  matching = 0;
588 
590  {
591  if (unformat (input, "brief") || unformat (input, "summary")
592  || unformat (input, "sum"))
593  verbose = 0;
594 
595  else if (unformat (input, "%U %U",
596  unformat_ip6_address, &src,
597  unformat_ip6_address, &grp))
598  {
599  matching = 1;
600  mask = 256;
601  }
602  else if (unformat (input, "%U/%d", unformat_ip6_address, &grp, &mask))
603  {
604  memset(&src, 0, sizeof(src));
605  matching = 1;
606  }
607  else if (unformat (input, "%U", unformat_ip6_address, &grp))
608  {
609  memset(&src, 0, sizeof(src));
610  matching = 1;
611  mask = 128;
612  }
613  else if (unformat (input, "table %d", &table_id))
614  ;
615  else if (unformat (input, "index %d", &fib_index))
616  ;
617  else
618  break;
619  }
620 
621  pool_foreach (mfib_table, im6->mfibs,
622  ({
623  ip6_mfib_t *mfib = &mfib_table->v6;
624 
625  if (table_id >= 0 && table_id != (int)mfib->table_id)
626  continue;
627  if (fib_index != ~0 && fib_index != (int)mfib->index)
628  continue;
629 
630  vlib_cli_output (vm, "%U, fib_index %d",
631  format_mfib_table_name, mfib->index, FIB_PROTOCOL_IP6,
632  mfib->index);
633 
634  /* Show summary? */
635  if (! verbose)
636  {
637  /* vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count"); */
638  /* for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) */
639  /* { */
640  /* uword * hash = mfib->fib_entry_by_dst_address[i]; */
641  /* uword n_elts = hash_elts (hash); */
642  /* if (n_elts > 0) */
643  /* vlib_cli_output (vm, "%20d%16d", i, n_elts); */
644  /* } */
645  continue;
646  }
647 
648  if (!matching)
649  {
650  ip6_mfib_table_show_all(mfib, vm);
651  }
652  else
653  {
654  ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask);
655  }
656  }));
657 
658  return 0;
659 }
660 
661 /*
662  * This command displays the IPv6 MulticasrFIB Tables (VRF Tables) and
663  * the route entries for each table.
664  *
665  * @note This command will run for a long time when the FIB tables are
666  * comprised of millions of entries. For those senarios, consider displaying
667  * a single table or summary mode.
668  *
669  * @cliexpar
670  * Example of how to display all the IPv6 Multicast FIB tables:
671  * @cliexstart{show ip fib}
672  * ipv6-VRF:0, fib_index 0
673  * (*, 0.0.0.0/0): flags:D,
674  * Interfaces:
675  * multicast-ip6-chain
676  * [@1]: dpo-drop ip6
677  * (*, 232.1.1.1/32):
678  * Interfaces:
679  * test-eth1: Forward,
680  * test-eth2: Forward,
681  * test-eth0: Accept,
682  * multicast-ip6-chain
683  * [@2]: dpo-replicate: [index:1 buckets:2 to:[0:0]]
684  * [0] [@1]: ipv6-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
685  * [1] [@1]: ipv6-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
686  *
687  * @cliexend
688  * Example of how to display a summary of all IPv6 FIB tables:
689  * @cliexstart{show ip fib summary}
690  * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
691  * Prefix length Count
692  * 0 1
693  * 8 2
694  * 32 4
695  * ipv6-VRF:7, fib_index 1, flow hash: src dst sport dport proto
696  * Prefix length Count
697  * 0 1
698  * 8 2
699  * 24 2
700  * 32 4
701  * @cliexend
702  */
703 /* *INDENT-OFF* */
704 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
705  .path = "show ip6 mfib",
706  .short_help = "show ip mfib [summary] [table <table-id>] [index <fib-id>] [<grp-addr>[/<mask>]] [<grp-addr>] [<src-addr> <grp-addr>]",
707  .function = ip6_show_mfib,
708 };
709 /* *INDENT-ON* */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
#define MFIB_ENTRY_FORMAT_DETAIL
Definition: mfib_entry.h:88
ip6_mfib_special_type_t ims_type
solicited or not
Definition: ip6_mfib.c:70
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:179
A representation of a path as described by a route producer.
Definition: fib_types.h:455
fib_node_index_t * entries
Definition: ip6_mfib.c:499
struct ip6_mfib_key_t_ ip6_mfib_key_t
Key and mask for radix.
ip6_mfib_t v6
Definition: mfib_table.h:50
#define NULL
Definition: clib.h:55
ip6_mfib_key_t i6mn_key
Definition: ip6_mfib.c:45
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
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:386
#define IP6_MFIB_MK_KEY_MASK(_grp, _src, _len, _key)
Definition: ip6_mfib.c:335
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:165
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
fib_node_index_t ip6_mfib_table_lookup2(const ip6_mfib_t *mfib, const ip6_address_t *src, const ip6_address_t *grp)
Data-plane lookup function.
Definition: ip6_mfib.c:411
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:460
void ip6_mfib_table_destroy(ip6_mfib_t *mfib)
Definition: ip6_mfib.c:218
#define MFIB_ENTRY_FORMAT_BRIEF
Definition: mfib_entry.h:87
unsigned char u8
Definition: types.h:56
struct radix_node * rn_search_m(const void *v_arg, struct radix_node *head, const void *m_arg)
Definition: radix.c:149
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:301
enum mfib_source_t_ mfib_source_t
Possible [control plane] sources of MFIB entries.
u8 ims_len
the Prefix length
Definition: ip6_mfib.c:75
static clib_error_t * ip6_show_mfib(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip6_mfib.c:575
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
#define MFIB_RPF_ID_NONE
Definition: fib_types.h:378
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
#define IP6_MFIB_MK_KEY(_grp, _src, _key)
Definition: ip6_mfib.c:328
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:380
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:219
unsigned int u32
Definition: types.h:88
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:429
void ip6_mfib_table_walk(ip6_mfib_t *mfib, mfib_table_walk_fn_t fn, void *ctx)
Walk the IP6 mfib table.
Definition: ip6_mfib.c:560
ip6_mfib_special_type_t_
Definition: ip6_mfib.c:61
struct ip6_mfib_show_ctx_t_ ip6_mfib_show_ctx_t
mfib_table_walk_fn_t user_fn
Definition: ip6_mfib.c:541
uword * mfib_index_by_table_id
Hash table mapping table id to multicast fib index.
Definition: ip6.h:190
u8 * format_ip6_mfib_table_memory(u8 *s, va_list *args)
format (display) ipv6 MFIB mempry usage
Definition: ip6_mfib.c:476
struct radix_node * rn_lookup(const void *v_arg, const void *m_arg, struct radix_node_head *head)
Definition: radix.c:199
u8 mask[IP6_MFIB_KEY_LEN]
Definition: ip6_mfib.c:34
index_t i6mn_entry
Definition: ip6_mfib.c:46
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:94
struct _unformat_input_t unformat_input_t
struct radix_node * rnh_treetop
Definition: radix.h:98
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
int mfib_entry_cmp_for_sort(void *i1, void *i2)
Definition: mfib_entry.c:1078
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:587
u8 ims_byte
The last byte of the mcast address.
Definition: ip6_mfib.c:80
Definition: ip6.h:79
struct radix_node i6mn_nodes[2]
Definition: ip6_mfib.c:44
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)
Definition: ip6_mfib.c:486
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
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:260
u32 ip6_mfib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_mfib.c:315
int rn_walktree(struct radix_node_head *h, int(*f)(struct radix_node *, void *), void *w)
Definition: radix.c:985
static void ip6_mfib_table_show_all(ip6_mfib_t *mfib, vlib_main_t *vm)
Definition: ip6_mfib.c:514
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:294
u8 * format_mfib_entry(u8 *s, va_list *args)
Definition: mfib_entry.c:171
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
static int ip6_mfib_table_collect_entries(fib_node_index_t mfei, void *arg)
Definition: ip6_mfib.c:504
struct radix_node_head * rhead
Definition: ip6.h:91
static u32 ip6_create_mfib_with_table_id(u32 table_id, mfib_source_t src)
Definition: ip6_mfib.c:154
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
u32 index
Definition: ip6.h:85
Aggregrate type for a prefix.
Definition: mfib_types.h:24
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define ASSERT(truth)
static clib_error_t * ip6_mfib_module_init(vlib_main_t *vm)
Definition: ip6_mfib.c:468
ip6_main_t ip6_main
Definition: ip6_forward.c:2574
struct ip6_mfib_node_t_ ip6_mfib_node_t
An object that is inserted into the radix tree.
long ctx[MAX_CONNS]
Definition: main.c:126
u8 ims_scope
The scope of the address.
Definition: ip6_mfib.c:84
u32 table_id
Definition: ip6.h:82
static void clib_mem_free(void *p)
Definition: mem.h:179
static u32 ip6_mfib_index_from_table_id(u32 table_id)
Definition: ip6_mfib.h:88
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip6.h:170
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
struct radix_node * rn_delete(const void *v_arg, const void *netmask_arg, struct radix_node_head *head)
Definition: radix.c:944
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
struct ip6_mfib_radix_walk_ctx_t_ ip6_mfib_radix_walk_ctx_t
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:359
A for-us/local path.
Definition: fib_types.h:317
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
int rn_inithead0(struct radix_node_head *rnh, int off)
Definition: radix.c:1060
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:961
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:452
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:416
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:120
A protocol Independent IP multicast FIB table.
Definition: mfib_table.h:35
#define IP6_MFIB_KEY_LEN
The number of bytes in an address/ask key in the radix tree First byte is the length in bytes...
Definition: ip6_mfib.c:26
#define vec_foreach(var, vec)
Vector iterator.
u8 key[IP6_MFIB_KEY_LEN]
Definition: ip6_mfib.c:33
An object that is inserted into the radix tree.
Definition: ip6_mfib.c:42
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:251
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:62
struct radix_node * rn_addroute(const void *v_arg, const void *n_arg, struct radix_node_head *head, struct radix_node treenodes[2])
Definition: radix.c:602
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
struct radix_node * rn_match(const void *v_arg, struct radix_node_head *head)
Definition: radix.c:244
#define FOR_EACH_IP6_SPECIAL(_pfx, _body)
Definition: ip6_mfib.c:126
const ip46_address_t zero_addr
Definition: lookup.c:318
Key and mask for radix.
Definition: ip6_mfib.c:31
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static int ip6_mfib_table_radix_walk(struct radix_node *rn, void *arg)
Definition: ip6_mfib.c:546
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128