FD.io VPP  v17.10-9-gd594711
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 static void
477  vlib_main_t * vm,
478  ip6_address_t *src,
479  ip6_address_t *grp,
480  u32 mask_len)
481 {
482  vlib_cli_output(vm, "%U",
484  ip6_mfib_table_lookup(mfib, src, grp, mask_len),
486 }
487 
488 typedef struct ip6_mfib_show_ctx_t_ {
491 
492 
493 static int
495 {
496  ip6_mfib_show_ctx_t *ctx = arg;
497 
498  vec_add1(ctx->entries, mfei);
499 
500  return (0);
501 }
502 
503 static void
505  vlib_main_t * vm)
506 {
507  fib_node_index_t *mfib_entry_index;
509  .entries = NULL,
510  };
511 
512  ip6_mfib_table_walk(mfib,
514  &ctx);
515 
517 
518  vec_foreach(mfib_entry_index, ctx.entries)
519  {
520  vlib_cli_output(vm, "%U",
522  *mfib_entry_index,
524  }
525 
526  vec_free(ctx.entries);
527 }
528 
530 {
532  void *user_ctx;
534 
535 static int
537  void *arg)
538 {
540  ip6_mfib_node_t *i6mn;
541 
542  i6mn = (ip6_mfib_node_t*) rn;
543 
544  ctx->user_fn(i6mn->i6mn_entry, ctx->user_ctx);
545 
546  return (0);
547 }
548 
549 void
552  void *ctx)
553 {
554  ip6_mfib_radix_walk_ctx_t rn_ctx = {
555  .user_fn = fn,
556  .user_ctx = ctx,
557  };
558 
559  rn_walktree(mfib->rhead,
561  &rn_ctx);
562 }
563 
564 static clib_error_t *
566  unformat_input_t * input,
567  vlib_cli_command_t * cmd)
568 {
569  ip6_main_t * im4 = &ip6_main;
570  mfib_table_t *mfib_table;
571  int verbose, matching;
572  ip6_address_t grp, src = {{0}};
573  u32 mask = 32;
574  int table_id = -1, fib_index = ~0;
575 
576  verbose = 1;
577  matching = 0;
578 
580  {
581  if (unformat (input, "brief") || unformat (input, "summary")
582  || unformat (input, "sum"))
583  verbose = 0;
584 
585  else if (unformat (input, "%U %U",
586  unformat_ip6_address, &src,
587  unformat_ip6_address, &grp))
588  {
589  matching = 1;
590  mask = 256;
591  }
592  else if (unformat (input, "%U/%d", unformat_ip6_address, &grp, &mask))
593  {
594  memset(&src, 0, sizeof(src));
595  matching = 1;
596  }
597  else if (unformat (input, "%U", unformat_ip6_address, &grp))
598  {
599  memset(&src, 0, sizeof(src));
600  matching = 1;
601  mask = 128;
602  }
603  else if (unformat (input, "table %d", &table_id))
604  ;
605  else if (unformat (input, "index %d", &fib_index))
606  ;
607  else
608  break;
609  }
610 
611  pool_foreach (mfib_table, im4->mfibs,
612  ({
613  ip6_mfib_t *mfib = &mfib_table->v6;
614 
615  if (table_id >= 0 && table_id != (int)mfib->table_id)
616  continue;
617  if (fib_index != ~0 && fib_index != (int)mfib->index)
618  continue;
619 
620  vlib_cli_output (vm, "%U, fib_index %d",
621  format_mfib_table_name, mfib->index, FIB_PROTOCOL_IP6,
622  mfib->index);
623 
624  /* Show summary? */
625  if (! verbose)
626  {
627  /* vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count"); */
628  /* for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) */
629  /* { */
630  /* uword * hash = mfib->fib_entry_by_dst_address[i]; */
631  /* uword n_elts = hash_elts (hash); */
632  /* if (n_elts > 0) */
633  /* vlib_cli_output (vm, "%20d%16d", i, n_elts); */
634  /* } */
635  continue;
636  }
637 
638  if (!matching)
639  {
640  ip6_mfib_table_show_all(mfib, vm);
641  }
642  else
643  {
644  ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask);
645  }
646  }));
647 
648  return 0;
649 }
650 
651 /*
652  * This command displays the IPv4 MulticasrFIB Tables (VRF Tables) and
653  * the route entries for each table.
654  *
655  * @note This command will run for a long time when the FIB tables are
656  * comprised of millions of entries. For those senarios, consider displaying
657  * a single table or summary mode.
658  *
659  * @cliexpar
660  * Example of how to display all the IPv4 Multicast FIB tables:
661  * @cliexstart{show ip fib}
662  * ipv4-VRF:0, fib_index 0
663  * (*, 0.0.0.0/0): flags:D,
664  * Interfaces:
665  * multicast-ip6-chain
666  * [@1]: dpo-drop ip6
667  * (*, 232.1.1.1/32):
668  * Interfaces:
669  * test-eth1: Forward,
670  * test-eth2: Forward,
671  * test-eth0: Accept,
672  * multicast-ip6-chain
673  * [@2]: dpo-replicate: [index:1 buckets:2 to:[0:0]]
674  * [0] [@1]: ipv4-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
675  * [1] [@1]: ipv4-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
676  *
677  * @cliexend
678  * Example of how to display a summary of all IPv4 FIB tables:
679  * @cliexstart{show ip fib summary}
680  * ipv4-VRF:0, fib_index 0, flow hash: src dst sport dport proto
681  * Prefix length Count
682  * 0 1
683  * 8 2
684  * 32 4
685  * ipv4-VRF:7, fib_index 1, flow hash: src dst sport dport proto
686  * Prefix length Count
687  * 0 1
688  * 8 2
689  * 24 2
690  * 32 4
691  * @cliexend
692  */
693 /* *INDENT-OFF* */
694 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
695  .path = "show ip6 mfib",
696  .short_help = "show ip mfib [summary] [table <table-id>] [index <fib-id>] [<grp-addr>[/<mask>]] [<grp-addr>] [<src-addr> <grp-addr>]",
697  .function = ip6_show_mfib,
698 };
699 /* *INDENT-ON* */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:432
#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: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:176
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:489
struct ip6_mfib_key_t_ ip6_mfib_key_t
Key and mask for radix.
ip6_mfib_t v6
Definition: mfib_table.h:45
#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:518
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:71
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:411
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:341
void ip6_mfib_table_destroy(ip6_mfib_t *mfib)
Definition: ip6_mfib.c:218
#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
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:565
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:437
#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:328
fib_node_index_t mft_index
Index into FIB vector.
Definition: mfib_table.h:66
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: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:550
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:531
uword * mfib_index_by_table_id
Hash table mapping table id to multicast fib index.
Definition: ip6.h:187
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:270
int mfib_entry_cmp_for_sort(void *i1, void *i2)
Definition: mfib_entry.c:1067
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:76
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:476
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: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:504
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:283
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:336
static int ip6_mfib_table_collect_entries(fib_node_index_t mfei, void *arg)
Definition: ip6_mfib.c:494
struct radix_node_head * rhead
Definition: ip6.h:88
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: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:468
ip6_main_t ip6_main
Definition: ip6_forward.c:3043
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:95
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: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:167
fib_protocol_t mft_proto
Which protocol this table serves.
Definition: mfib_table.h:51
struct ip6_mfib_special_t_ ip6_mfib_special_t
u32 mft_table_id
Table ID (hash key) for this FIB.
Definition: mfib_table.h:61
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: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:956
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:411
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: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:358
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:536
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169