FD.io VPP  v17.07-30-g839fa73
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 {
156  mfib_table_t *mfib_table;
157  mfib_prefix_t pfx = {
159  };
160  const fib_route_path_t path_for_us = {
162  .frp_addr = zero_addr,
163  .frp_sw_if_index = 0xffffffff,
164  .frp_fib_index = ~0,
165  .frp_weight = 0,
166  .frp_flags = FIB_ROUTE_PATH_LOCAL,
167  };
168 
170  memset(mfib_table, 0, sizeof(*mfib_table));
171 
172  mfib_table->mft_proto = FIB_PROTOCOL_IP6;
173  mfib_table->mft_index =
174  mfib_table->v6.index =
175  (mfib_table - ip6_main.mfibs);
176 
178  table_id,
179  mfib_table->mft_index);
180 
181  mfib_table->mft_table_id =
182  mfib_table->v6.table_id =
183  table_id;
184 
186 
187  mfib_table->v6.rhead =
188  clib_mem_alloc_aligned (sizeof(*mfib_table->v6.rhead),
190  rn_inithead0(mfib_table->v6.rhead, 8);
191 
192  /*
193  * add the special entries into the new FIB
194  */
196  &all_zeros,
200 
201  /*
202  * Add each of the specials
203  */
205  ({
207  &pfx,
209  &path_for_us,
211  }));
212 
213  return (mfib_table->mft_index);
214 }
215 
216 void
218 {
219  mfib_table_t *mfib_table = (mfib_table_t*)mfib;
220  fib_node_index_t mfei;
221  mfib_prefix_t pfx = {
223  };
224  const fib_route_path_t path_for_us = {
226  .frp_addr = zero_addr,
227  .frp_sw_if_index = 0xffffffff,
228  .frp_fib_index = ~0,
229  .frp_weight = 0,
230  .frp_flags = FIB_ROUTE_PATH_LOCAL,
231  };
232 
233  /*
234  * remove all the specials we added when the table was created.
235  */
237  {
239  &pfx,
241  &path_for_us);
242  });
243 
244  mfei = mfib_table_lookup_exact_match(mfib_table->mft_index, &all_zeros);
246 
247  /*
248  * validate no more routes.
249  */
250  ASSERT(0 == mfib_table->mft_total_route_counts);
251  ASSERT(~0 != mfib_table->mft_table_id);
252 
254  clib_mem_free(mfib_table->v6.rhead);
255  pool_put(ip6_main.mfibs, mfib_table);
256 }
257 
258 void
259 ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
260 {
261  const fib_route_path_t path = {
263  .frp_addr = zero_addr,
264  .frp_sw_if_index = sw_if_index,
265  .frp_fib_index = ~0,
266  .frp_weight = 0,
267  };
268  mfib_prefix_t pfx = {
270  };
271  u32 mfib_index;
272 
274  mfib_index = ip6_mfib_table_get_index_for_sw_if_index(sw_if_index);
275 
276  if (is_enable)
277  {
279  {
280  mfib_table_entry_path_update(mfib_index,
281  &pfx,
283  &path,
285  });
286  }
287  else
288  {
290  {
291  mfib_table_entry_path_remove(mfib_index,
292  &pfx,
294  &path);
295  });
296  }
297 }
298 
299 u32
301 {
302  u32 index;
303 
304  index = ip6_mfib_index_from_table_id(table_id);
305  if (~0 == index)
306  return ip6_create_mfib_with_table_id(table_id);
308 
309  return (index);
310 }
311 
312 u32
314 {
315  if (sw_if_index >= vec_len(ip6_main.mfib_index_by_sw_if_index))
316  {
317  /*
318  * This is the case for interfaces that are not yet mapped to
319  * a IP table
320  */
321  return (~0);
322  }
323  return (ip6_main.mfib_index_by_sw_if_index[sw_if_index]);
324 }
325 
326 #define IP6_MFIB_MK_KEY(_grp, _src, _key) \
327 { \
328  (_key)->key[0] = 33; \
329  memcpy((_key)->key+1, _grp, 16); \
330  memcpy((_key)->key+17, _src, 16); \
331 }
332 
333 #define IP6_MFIB_MK_KEY_MASK(_grp, _src, _len, _key) \
334 { \
335  IP6_MFIB_MK_KEY(_grp, _src, _key); \
336  \
337  (_key)->mask[0] = 33; \
338  if (_len <= 128) \
339  { \
340  memcpy((_key)->mask+1, &ip6_main.fib_masks[_len], 16); \
341  memset((_key)->mask+17, 0, 16); \
342  } \
343  else \
344  { \
345  ASSERT(_len == 256); \
346  memcpy((_key)->mask+1, &ip6_main.fib_masks[128], 16); \
347  memcpy((_key)->mask+17, &ip6_main.fib_masks[128], 16); \
348  } \
349 }
350 
351 /*
352  * ip6_fib_table_lookup_exact_match
353  *
354  * Exact match prefix lookup
355  */
358  const ip6_address_t *grp,
359  const ip6_address_t *src,
360  u32 len)
361 {
362  ip6_mfib_node_t *i6mn;
364 
365  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
366 
367  i6mn = (ip6_mfib_node_t*) rn_lookup(key.key, key.mask,
368  (struct radix_node_head *)mfib->rhead);
369 
370  if (NULL == i6mn)
371  {
372  return (INDEX_INVALID);
373  }
374 
375  return (i6mn->i6mn_entry);
376 }
377 
378 /*
379  * ip6_fib_table_lookup
380  *
381  * Longest prefix match
382  */
385  const ip6_address_t *src,
386  const ip6_address_t *grp,
387  u32 len)
388 {
389  ip6_mfib_node_t *i6mn;
391 
392  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
393 
394  i6mn = (ip6_mfib_node_t*) rn_search_m(key.key,
395  mfib->rhead->rnh_treetop,
396  key.mask);
397 
398  ASSERT(NULL != i6mn);
399 
400  return (i6mn->i6mn_entry);
401 }
402 
403 /*
404  * ip6_fib_table_lookup
405  *
406  * Longest prefix match no mask
407  */
410  const ip6_address_t *src,
411  const ip6_address_t *grp)
412 {
413  ip6_mfib_node_t *i6mn;
415 
416  IP6_MFIB_MK_KEY(grp, src, &key);
417 
418  i6mn = (ip6_mfib_node_t*) rn_match(key.key,
419  (struct radix_node_head *)mfib->rhead); // const cast
420 
421  ASSERT(NULL != i6mn);
422 
423  return (i6mn->i6mn_entry);
424 }
425 
426 void
428  const ip6_address_t *grp,
429  const ip6_address_t *src,
430  u32 len,
431  fib_node_index_t mfib_entry_index)
432 {
433  ip6_mfib_node_t *i6mn = clib_mem_alloc(sizeof(*i6mn));
434 
435  memset(i6mn->i6mn_nodes, 0, sizeof(i6mn->i6mn_nodes));
436 
437  IP6_MFIB_MK_KEY_MASK(grp, src, len, &i6mn->i6mn_key);
438  i6mn->i6mn_entry = mfib_entry_index;
439 
440  if (NULL == rn_addroute(i6mn->i6mn_key.key,
441  i6mn->i6mn_key.mask,
442  mfib->rhead,
443  i6mn->i6mn_nodes))
444  {
445  ASSERT(0);
446  }
447 }
448 
449 void
451  const ip6_address_t *grp,
452  const ip6_address_t *src,
453  u32 len)
454 {
455  ip6_mfib_node_t *i6mn;
457 
458  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
459 
460  i6mn = (ip6_mfib_node_t*) rn_delete(key.key, key.mask, mfib->rhead);
461 
462  clib_mem_free(i6mn);
463 }
464 
465 static clib_error_t *
467 {
468  return (NULL);
469 }
470 
472 
473 static void
475  vlib_main_t * vm,
476  ip6_address_t *src,
477  ip6_address_t *grp,
478  u32 mask_len)
479 {
480  vlib_cli_output(vm, "%U",
482  ip6_mfib_table_lookup(mfib, src, grp, mask_len),
484 }
485 
486 typedef struct ip6_mfib_show_ctx_t_ {
489 
490 
491 static int
493 {
494  ip6_mfib_show_ctx_t *ctx = arg;
495 
496  vec_add1(ctx->entries, mfei);
497 
498  return (0);
499 }
500 
501 static void
503  vlib_main_t * vm)
504 {
505  fib_node_index_t *mfib_entry_index;
506  ip6_mfib_show_ctx_t ctx = {
507  .entries = NULL,
508  };
509 
510  ip6_mfib_table_walk(mfib,
512  &ctx);
513 
515 
516  vec_foreach(mfib_entry_index, ctx.entries)
517  {
518  vlib_cli_output(vm, "%U",
520  *mfib_entry_index,
522  }
523 
524  vec_free(ctx.entries);
525 }
526 
528 {
530  void *user_ctx;
532 
533 static int
535  void *arg)
536 {
537  ip6_mfib_radix_walk_ctx_t *ctx = arg;
538  ip6_mfib_node_t *i6mn;
539 
540  i6mn = (ip6_mfib_node_t*) rn;
541 
542  ctx->user_fn(i6mn->i6mn_entry, ctx->user_ctx);
543 
544  return (0);
545 }
546 
547 void
550  void *ctx)
551 {
552  ip6_mfib_radix_walk_ctx_t rn_ctx = {
553  .user_fn = fn,
554  .user_ctx = ctx,
555  };
556 
557  rn_walktree(mfib->rhead,
559  &rn_ctx);
560 }
561 
562 static clib_error_t *
564  unformat_input_t * input,
565  vlib_cli_command_t * cmd)
566 {
567  ip6_main_t * im4 = &ip6_main;
568  mfib_table_t *mfib_table;
569  int verbose, matching;
570  ip6_address_t grp, src = {{0}};
571  u32 mask = 32;
572  int table_id = -1, fib_index = ~0;
573 
574  verbose = 1;
575  matching = 0;
576 
578  {
579  if (unformat (input, "brief") || unformat (input, "summary")
580  || unformat (input, "sum"))
581  verbose = 0;
582 
583  else if (unformat (input, "%U %U",
584  unformat_ip6_address, &src,
585  unformat_ip6_address, &grp))
586  {
587  matching = 1;
588  mask = 256;
589  }
590  else if (unformat (input, "%U/%d", unformat_ip6_address, &grp, &mask))
591  {
592  memset(&src, 0, sizeof(src));
593  matching = 1;
594  }
595  else if (unformat (input, "%U", unformat_ip6_address, &grp))
596  {
597  memset(&src, 0, sizeof(src));
598  matching = 1;
599  mask = 128;
600  }
601  else if (unformat (input, "table %d", &table_id))
602  ;
603  else if (unformat (input, "index %d", &fib_index))
604  ;
605  else
606  break;
607  }
608 
609  pool_foreach (mfib_table, im4->mfibs,
610  ({
611  ip6_mfib_t *mfib = &mfib_table->v6;
612 
613  if (table_id >= 0 && table_id != (int)mfib->table_id)
614  continue;
615  if (fib_index != ~0 && fib_index != (int)mfib->index)
616  continue;
617 
618  vlib_cli_output (vm, "%U, fib_index %d",
619  format_mfib_table_name, mfib->index, FIB_PROTOCOL_IP6,
620  mfib->index);
621 
622  /* Show summary? */
623  if (! verbose)
624  {
625  /* vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count"); */
626  /* for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) */
627  /* { */
628  /* uword * hash = mfib->fib_entry_by_dst_address[i]; */
629  /* uword n_elts = hash_elts (hash); */
630  /* if (n_elts > 0) */
631  /* vlib_cli_output (vm, "%20d%16d", i, n_elts); */
632  /* } */
633  continue;
634  }
635 
636  if (!matching)
637  {
638  ip6_mfib_table_show_all(mfib, vm);
639  }
640  else
641  {
642  ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask);
643  }
644  }));
645 
646  return 0;
647 }
648 
649 /*
650  * This command displays the IPv4 MulticasrFIB Tables (VRF Tables) and
651  * the route entries for each table.
652  *
653  * @note This command will run for a long time when the FIB tables are
654  * comprised of millions of entries. For those senarios, consider displaying
655  * a single table or summary mode.
656  *
657  * @cliexpar
658  * Example of how to display all the IPv4 Multicast FIB tables:
659  * @cliexstart{show ip fib}
660  * ipv4-VRF:0, fib_index 0
661  * (*, 0.0.0.0/0): flags:D,
662  * Interfaces:
663  * multicast-ip6-chain
664  * [@1]: dpo-drop ip6
665  * (*, 232.1.1.1/32):
666  * Interfaces:
667  * test-eth1: Forward,
668  * test-eth2: Forward,
669  * test-eth0: Accept,
670  * multicast-ip6-chain
671  * [@2]: dpo-replicate: [index:1 buckets:2 to:[0:0]]
672  * [0] [@1]: ipv4-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
673  * [1] [@1]: ipv4-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
674  *
675  * @cliexend
676  * Example of how to display a summary of all IPv4 FIB tables:
677  * @cliexstart{show ip fib summary}
678  * ipv4-VRF:0, fib_index 0, flow hash: src dst sport dport proto
679  * Prefix length Count
680  * 0 1
681  * 8 2
682  * 32 4
683  * ipv4-VRF:7, fib_index 1, flow hash: src dst sport dport proto
684  * Prefix length Count
685  * 0 1
686  * 8 2
687  * 24 2
688  * 32 4
689  * @cliexend
690  */
691 /* *INDENT-OFF* */
692 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
693  .path = "show ip6 mfib",
694  .short_help = "show ip mfib [summary] [table <table-id>] [index <fib-id>] [<grp-addr>[/<mask>]] [<grp-addr>] [<src-addr> <grp-addr>]",
695  .function = ip6_show_mfib,
696 };
697 /* *INDENT-ON* */
u32 ip6_mfib_table_find_or_create_and_lock(u32 table_id)
Get or create an IPv4 fib.
Definition: ip6_mfib.c:300
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
#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
fib_protocol_t frp_proto
The protocol of the address below.
Definition: fib_types.h:341
ip46_address_t fp_src_addr
Definition: mfib_types.h:47
#define hash_set(h, key, value)
Definition: hash.h:254
enum ip6_mfib_special_type_t_ ip6_mfib_special_type_t
#define hash_unset(h, key)
Definition: hash.h:260
u32 * mfib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip6.h:166
A representation of a path as described by a route producer.
Definition: fib_types.h:336
fib_node_index_t * entries
Definition: ip6_mfib.c:487
struct ip6_mfib_key_t_ ip6_mfib_key_t
Key and mask for radix.
ip6_mfib_t v6
Definition: mfib_table.h:39
#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: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:384
#define IP6_MFIB_MK_KEY_MASK(_grp, _src, _len, _key)
Definition: ip6_mfib.c:333
u32 mft_total_route_counts
Total route counters.
Definition: mfib_table.h:65
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
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:409
void ip6_mfib_table_destroy(ip6_mfib_t *mfib)
Definition: ip6_mfib.c:217
#define MFIB_ENTRY_FORMAT_BRIEF
Definition: mfib_entry.h:87
struct radix_node * rn_search_m(const void *v_arg, struct radix_node *head, const void *m_arg)
Definition: radix.c:149
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:563
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
#define MFIB_RPF_ID_NONE
Definition: fib_types.h:317
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define IP6_MFIB_MK_KEY(_grp, _src, _key)
Definition: ip6_mfib.c:326
fib_node_index_t mft_index
Index into FIB vector.
Definition: mfib_table.h:60
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
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:427
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:548
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:529
uword * mfib_index_by_table_id
Hash table mapping table id to multicast fib index.
Definition: ip6.h:177
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:241
int mfib_entry_cmp_for_sort(void *i1, void *i2)
Definition: mfib_entry.c:1058
u8 ims_byte
The last byte of the mcast address.
Definition: ip6_mfib.c:80
Definition: ip6.h:76
struct radix_node i6mn_nodes[2]
Definition: ip6_mfib.c:44
static u32 ip6_create_mfib_with_table_id(u32 table_id)
Definition: ip6_mfib.c:154
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:474
unformat_function_t unformat_ip6_address
Definition: format.h:94
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:169
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:259
u32 ip6_mfib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_mfib.c:313
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:502
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
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:340
static int ip6_mfib_table_collect_entries(fib_node_index_t mfei, void *arg)
Definition: ip6_mfib.c:492
struct radix_node_head * rhead
Definition: ip6.h:88
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
u32 index
Definition: ip6.h:82
Aggregrate type for a prefix.
Definition: mfib_types.h:24
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static clib_error_t * ip6_mfib_module_init(vlib_main_t *vm)
Definition: ip6_mfib.c:466
ip6_main_t ip6_main
Definition: ip6_forward.c:2926
struct ip6_mfib_node_t_ ip6_mfib_node_t
An object that is inserted into the radix tree.
u8 ims_scope
The scope of the address.
Definition: ip6_mfib.c:84
u32 table_id
Definition: ip6.h:79
static void clib_mem_free(void *p)
Definition: mem.h:176
static u32 ip6_mfib_index_from_table_id(u32 table_id)
Definition: ip6_mfib.h:87
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip6.h:157
fib_protocol_t mft_proto
Which protocol this table serves.
Definition: mfib_table.h:45
struct ip6_mfib_special_t_ ip6_mfib_special_t
u32 mft_table_id
Table ID (hash key) for this FIB.
Definition: mfib_table.h:55
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:109
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:357
A for-us/local path.
Definition: fib_types.h:284
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
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:960
void mfib_table_lock(u32 fib_index, fib_protocol_t proto)
Release a reference counting lock on the table.
Definition: mfib_table.c:489
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:450
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:367
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:117
A protocol Independent IP multicast FIB table.
Definition: mfib_table.h:29
#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:67
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:680
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:348
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:534
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169