FD.io VPP  v17.04-9-g99c0734
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,
199 
200  /*
201  * Add each of the specials
202  */
204  ({
206  &pfx,
208  &path_for_us,
210  }));
211 
212  return (mfib_table->mft_index);
213 }
214 
215 void
217 {
218  mfib_table_t *mfib_table = (mfib_table_t*)mfib;
219  fib_node_index_t mfei;
220  mfib_prefix_t pfx = {
222  };
223  const fib_route_path_t path_for_us = {
225  .frp_addr = zero_addr,
226  .frp_sw_if_index = 0xffffffff,
227  .frp_fib_index = ~0,
228  .frp_weight = 0,
229  .frp_flags = FIB_ROUTE_PATH_LOCAL,
230  };
231 
232  /*
233  * remove all the specials we added when the table was created.
234  */
236  {
238  &pfx,
240  &path_for_us);
241  });
242 
243  mfei = mfib_table_lookup_exact_match(mfib_table->mft_index, &all_zeros);
245 
246  /*
247  * validate no more routes.
248  */
249  ASSERT(0 == mfib_table->mft_total_route_counts);
250  ASSERT(~0 != mfib_table->mft_table_id);
251 
253  clib_mem_free(mfib_table->v6.rhead);
254  pool_put(ip6_main.mfibs, mfib_table);
255 }
256 
257 void
258 ip6_mfib_interface_enable_disable (u32 sw_if_index, int is_enable)
259 {
260  const fib_route_path_t path = {
262  .frp_addr = zero_addr,
263  .frp_sw_if_index = sw_if_index,
264  .frp_fib_index = ~0,
265  .frp_weight = 0,
266  };
267  mfib_prefix_t pfx = {
269  };
270  u32 mfib_index;
271 
273  mfib_index = ip6_mfib_table_get_index_for_sw_if_index(sw_if_index);
274 
275  if (is_enable)
276  {
278  {
279  mfib_table_entry_path_update(mfib_index,
280  &pfx,
282  &path,
284  });
285  }
286  else
287  {
289  {
290  mfib_table_entry_path_remove(mfib_index,
291  &pfx,
293  &path);
294  });
295  }
296 }
297 
298 u32
300 {
301  u32 index;
302 
303  index = ip6_mfib_index_from_table_id(table_id);
304  if (~0 == index)
305  return ip6_create_mfib_with_table_id(table_id);
307 
308  return (index);
309 }
310 
311 u32
313 {
314  if (sw_if_index >= vec_len(ip6_main.mfib_index_by_sw_if_index))
315  {
316  /*
317  * This is the case for interfaces that are not yet mapped to
318  * a IP table
319  */
320  return (~0);
321  }
322  return (ip6_main.mfib_index_by_sw_if_index[sw_if_index]);
323 }
324 
325 #define IP6_MFIB_MK_KEY(_grp, _src, _key) \
326 { \
327  (_key)->key[0] = 33; \
328  memcpy((_key)->key+1, _grp, 16); \
329  memcpy((_key)->key+17, _src, 16); \
330 }
331 
332 #define IP6_MFIB_MK_KEY_MASK(_grp, _src, _len, _key) \
333 { \
334  IP6_MFIB_MK_KEY(_grp, _src, _key); \
335  \
336  (_key)->mask[0] = 33; \
337  if (_len <= 128) \
338  { \
339  memcpy((_key)->mask+1, &ip6_main.fib_masks[_len], 16); \
340  memset((_key)->mask+17, 0, 16); \
341  } \
342  else \
343  { \
344  ASSERT(_len == 256); \
345  memcpy((_key)->mask+1, &ip6_main.fib_masks[128], 16); \
346  memcpy((_key)->mask+17, &ip6_main.fib_masks[128], 16); \
347  } \
348 }
349 
350 /*
351  * ip6_fib_table_lookup_exact_match
352  *
353  * Exact match prefix lookup
354  */
357  const ip6_address_t *grp,
358  const ip6_address_t *src,
359  u32 len)
360 {
361  ip6_mfib_node_t *i6mn;
363 
364  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
365 
366  i6mn = (ip6_mfib_node_t*) rn_lookup(key.key, key.mask,
367  (struct radix_node_head *)mfib->rhead);
368 
369  if (NULL == i6mn)
370  {
371  return (INDEX_INVALID);
372  }
373 
374  return (i6mn->i6mn_entry);
375 }
376 
377 /*
378  * ip6_fib_table_lookup
379  *
380  * Longest prefix match
381  */
384  const ip6_address_t *src,
385  const ip6_address_t *grp,
386  u32 len)
387 {
388  ip6_mfib_node_t *i6mn;
390 
391  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
392 
393  i6mn = (ip6_mfib_node_t*) rn_search_m(key.key,
394  mfib->rhead->rnh_treetop,
395  key.mask);
396 
397  ASSERT(NULL != i6mn);
398 
399  return (i6mn->i6mn_entry);
400 }
401 
402 /*
403  * ip6_fib_table_lookup
404  *
405  * Longest prefix match no mask
406  */
409  const ip6_address_t *src,
410  const ip6_address_t *grp)
411 {
412  ip6_mfib_node_t *i6mn;
414 
415  IP6_MFIB_MK_KEY(grp, src, &key);
416 
417  i6mn = (ip6_mfib_node_t*) rn_match(key.key,
418  (struct radix_node_head *)mfib->rhead); // const cast
419 
420  ASSERT(NULL != i6mn);
421 
422  return (i6mn->i6mn_entry);
423 }
424 
425 void
427  const ip6_address_t *grp,
428  const ip6_address_t *src,
429  u32 len,
430  fib_node_index_t mfib_entry_index)
431 {
432  ip6_mfib_node_t *i6mn = clib_mem_alloc(sizeof(*i6mn));
433 
434  memset(i6mn->i6mn_nodes, 0, sizeof(i6mn->i6mn_nodes));
435 
436  IP6_MFIB_MK_KEY_MASK(grp, src, len, &i6mn->i6mn_key);
437  i6mn->i6mn_entry = mfib_entry_index;
438 
439  if (NULL == rn_addroute(i6mn->i6mn_key.key,
440  i6mn->i6mn_key.mask,
441  mfib->rhead,
442  i6mn->i6mn_nodes))
443  {
444  ASSERT(0);
445  }
446 }
447 
448 void
450  const ip6_address_t *grp,
451  const ip6_address_t *src,
452  u32 len)
453 {
454  ip6_mfib_node_t *i6mn;
456 
457  IP6_MFIB_MK_KEY_MASK(grp, src, len, &key);
458 
459  i6mn = (ip6_mfib_node_t*) rn_delete(key.key, key.mask, mfib->rhead);
460 
461  clib_mem_free(i6mn);
462 }
463 
464 static clib_error_t *
466 {
467  return (NULL);
468 }
469 
471 
472 static void
474  vlib_main_t * vm,
475  ip6_address_t *src,
476  ip6_address_t *grp,
477  u32 mask_len)
478 {
479  vlib_cli_output(vm, "%U",
481  ip6_mfib_table_lookup(mfib, src, grp, mask_len),
483 }
484 
485 typedef struct ip6_mfib_show_ctx_t_ {
488 
489 
490 static int
492 {
493  ip6_mfib_show_ctx_t *ctx = arg;
494 
495  vec_add1(ctx->entries, mfei);
496 
497  return (0);
498 }
499 
500 static void
502  vlib_main_t * vm)
503 {
504  fib_node_index_t *mfib_entry_index;
505  ip6_mfib_show_ctx_t ctx = {
506  .entries = NULL,
507  };
508 
509  ip6_mfib_table_walk(mfib,
511  &ctx);
512 
514 
515  vec_foreach(mfib_entry_index, ctx.entries)
516  {
517  vlib_cli_output(vm, "%U",
519  *mfib_entry_index,
521  }
522 
523  vec_free(ctx.entries);
524 }
525 
527 {
529  void *user_ctx;
531 
532 static int
534  void *arg)
535 {
536  ip6_mfib_radix_walk_ctx_t *ctx = arg;
537  ip6_mfib_node_t *i6mn;
538 
539  i6mn = (ip6_mfib_node_t*) rn;
540 
541  ctx->user_fn(i6mn->i6mn_entry, ctx->user_ctx);
542 
543  return (0);
544 }
545 
546 void
549  void *ctx)
550 {
551  ip6_mfib_radix_walk_ctx_t rn_ctx = {
552  .user_fn = fn,
553  .user_ctx = ctx,
554  };
555 
556  rn_walktree(mfib->rhead,
558  &rn_ctx);
559 }
560 
561 static clib_error_t *
563  unformat_input_t * input,
564  vlib_cli_command_t * cmd)
565 {
566  ip6_main_t * im4 = &ip6_main;
567  mfib_table_t *mfib_table;
568  int verbose, matching;
569  ip6_address_t grp, src = {{0}};
570  u32 mask = 32;
571  int table_id = -1, fib_index = ~0;
572 
573  verbose = 1;
574  matching = 0;
575 
577  {
578  if (unformat (input, "brief") || unformat (input, "summary")
579  || unformat (input, "sum"))
580  verbose = 0;
581 
582  else if (unformat (input, "%U %U",
583  unformat_ip6_address, &src,
584  unformat_ip6_address, &grp))
585  {
586  matching = 1;
587  mask = 64;
588  }
589  else if (unformat (input, "%U", unformat_ip6_address, &grp))
590  {
591  matching = 1;
592  mask = 32;
593  }
594  else if (unformat (input, "%U/%d",
595  unformat_ip6_address, &grp, &mask))
596  matching = 1;
597  else if (unformat (input, "table %d", &table_id))
598  ;
599  else if (unformat (input, "index %d", &fib_index))
600  ;
601  else
602  break;
603  }
604 
605  pool_foreach (mfib_table, im4->mfibs,
606  ({
607  ip6_mfib_t *mfib = &mfib_table->v6;
608 
609  if (table_id >= 0 && table_id != (int)mfib->table_id)
610  continue;
611  if (fib_index != ~0 && fib_index != (int)mfib->index)
612  continue;
613 
614  vlib_cli_output (vm, "%U, fib_index %d",
615  format_mfib_table_name, mfib->index, FIB_PROTOCOL_IP6,
616  mfib->index);
617 
618  /* Show summary? */
619  if (! verbose)
620  {
621  /* vlib_cli_output (vm, "%=20s%=16s", "Prefix length", "Count"); */
622  /* for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++) */
623  /* { */
624  /* uword * hash = mfib->fib_entry_by_dst_address[i]; */
625  /* uword n_elts = hash_elts (hash); */
626  /* if (n_elts > 0) */
627  /* vlib_cli_output (vm, "%20d%16d", i, n_elts); */
628  /* } */
629  continue;
630  }
631 
632  if (!matching)
633  {
634  ip6_mfib_table_show_all(mfib, vm);
635  }
636  else
637  {
638  ip6_mfib_table_show_one(mfib, vm, &src, &grp, mask);
639  }
640  }));
641 
642  return 0;
643 }
644 
645 /*
646  * This command displays the IPv4 MulticasrFIB Tables (VRF Tables) and
647  * the route entries for each table.
648  *
649  * @note This command will run for a long time when the FIB tables are
650  * comprised of millions of entries. For those senarios, consider displaying
651  * a single table or summary mode.
652  *
653  * @cliexpar
654  * Example of how to display all the IPv4 Multicast FIB tables:
655  * @cliexstart{show ip fib}
656  * ipv4-VRF:0, fib_index 0
657  * (*, 0.0.0.0/0): flags:D,
658  * Interfaces:
659  * multicast-ip6-chain
660  * [@1]: dpo-drop ip6
661  * (*, 232.1.1.1/32):
662  * Interfaces:
663  * test-eth1: Forward,
664  * test-eth2: Forward,
665  * test-eth0: Accept,
666  * multicast-ip6-chain
667  * [@2]: dpo-replicate: [index:1 buckets:2 to:[0:0]]
668  * [0] [@1]: ipv4-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
669  * [1] [@1]: ipv4-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
670  *
671  * @cliexend
672  * Example of how to display a summary of all IPv4 FIB tables:
673  * @cliexstart{show ip fib summary}
674  * ipv4-VRF:0, fib_index 0, flow hash: src dst sport dport proto
675  * Prefix length Count
676  * 0 1
677  * 8 2
678  * 32 4
679  * ipv4-VRF:7, fib_index 1, flow hash: src dst sport dport proto
680  * Prefix length Count
681  * 0 1
682  * 8 2
683  * 24 2
684  * 32 4
685  * @cliexend
686  */
687 /* *INDENT-OFF* */
688 VLIB_CLI_COMMAND (ip6_show_fib_command, static) = {
689  .path = "show ip6 mfib",
690  .short_help = "show ip mfib [summary] [table <table-id>] [index <fib-id>] [<grp-addr>[/<mask>]] [<grp-addr>] [<src-addr> <grp-addr>]",
691  .function = ip6_show_mfib,
692 };
693 /* *INDENT-ON* */
u32 ip6_mfib_table_find_or_create_and_lock(u32 table_id)
Get or create an IPv4 fib.
Definition: ip6_mfib.c:299
#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:84
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:313
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:308
fib_node_index_t * entries
Definition: ip6_mfib.c:486
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:383
#define IP6_MFIB_MK_KEY_MASK(_grp, _src, _len, _key)
Definition: ip6_mfib.c:332
u32 mft_total_route_counts
Total route counters.
Definition: mfib_table.h:65
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:408
void ip6_mfib_table_destroy(ip6_mfib_t *mfib)
Definition: ip6_mfib.c:216
#define MFIB_ENTRY_FORMAT_BRIEF
Definition: mfib_entry.h:83
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:562
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define IP6_MFIB_MK_KEY(_grp, _src, _key)
Definition: ip6_mfib.c:325
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:374
fib_node_index_t mfib_table_entry_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, 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 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:216
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:426
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:547
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:528
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:987
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 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:473
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:258
u32 ip6_mfib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: ip6_mfib.c:312
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:501
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:276
u8 * format_mfib_entry(u8 *s, va_list *args)
Definition: mfib_entry.c:127
#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:491
struct radix_node_head * rhead
Definition: ip6.h:91
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
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)
unsigned int u32
Definition: types.h:88
static clib_error_t * ip6_mfib_module_init(vlib_main_t *vm)
Definition: ip6_mfib.c:465
ip6_main_t ip6_main
Definition: ip6_forward.c:2846
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:82
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:356
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:483
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:449
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:366
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:247
#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:577
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:354
Key and mask for radix.
Definition: ip6_mfib.c:31
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
static int ip6_mfib_table_radix_walk(struct radix_node *rn, void *arg)
Definition: ip6_mfib.c:533
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169