summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2017-11-29 00:59:31 -0800
committerDamjan Marion <dmarion.lists@gmail.com>2017-11-29 11:17:08 +0000
commitc87aafad759f92ae630fec52079a08ace607410b (patch)
tree36d534722eccc9ea03144eb42bf6104bf1dd294e /src
parent72454dd4c5196594b366883bbf732c9e067c64ec (diff)
Include allocated table memory in 'sh fib mem' output
DBGvpp# sh fib mem FIB memory Tables: SAFI Number Bytes IPv4 unicast 2 673066 IPv6 unicast 2 1054608 MPLS 1 4194312 IPv4 multicast 2 2322 IPv6 multicast 2 ??? Nodes: Name Size in-use /allocated totals Entry 96 20 / 20 1920/1920 Entry Source 32 0 / 0 0/0 Entry Path-Extensions 60 0 / 0 0/0 multicast-Entry 192 12 / 12 2304/2304 Path-list 40 28 / 28 1120/1120 uRPF-list 16 20 / 20 320/320 Path 72 28 / 28 2016/2016 Node-list elements 20 28 / 28 560/560 Node-list heads 8 30 / 30 240/240 Change-Id: I8c8f6f1c87502a40265bf4f302d0daef111a4a4e Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src')
-rw-r--r--src/vnet/fib/fib_node.c35
-rw-r--r--src/vnet/fib/fib_table.c10
-rw-r--r--src/vnet/fib/fib_table.h5
-rw-r--r--src/vnet/fib/ip4_fib.c81
-rw-r--r--src/vnet/fib/ip4_fib.h1
-rw-r--r--src/vnet/fib/ip6_fib.c12
-rw-r--r--src/vnet/fib/ip6_fib.h2
-rw-r--r--src/vnet/fib/mpls_fib.c12
-rw-r--r--src/vnet/fib/mpls_fib.h2
-rw-r--r--src/vnet/ip/ip4_mtrie.c8
-rw-r--r--src/vnet/ip/ip4_mtrie.h5
-rw-r--r--src/vnet/mfib/ip4_mfib.c70
-rw-r--r--src/vnet/mfib/ip4_mfib.h11
-rw-r--r--src/vnet/mfib/ip6_mfib.c30
-rw-r--r--src/vnet/mfib/ip6_mfib.h5
-rw-r--r--src/vnet/mfib/mfib_table.c9
-rw-r--r--src/vnet/mfib/mfib_table.h4
17 files changed, 271 insertions, 31 deletions
diff --git a/src/vnet/fib/fib_node.c b/src/vnet/fib/fib_node.c
index 54c300aec1e..d2e3f04de27 100644
--- a/src/vnet/fib/fib_node.c
+++ b/src/vnet/fib/fib_node.c
@@ -15,6 +15,8 @@
#include <vnet/fib/fib_node.h>
#include <vnet/fib/fib_node_list.h>
+#include <vnet/fib/fib_table.h>
+#include <vnet/mfib/mfib_table.h>
/*
* The per-type vector of virtual function tables
@@ -234,6 +236,11 @@ fib_memory_show (vlib_main_t * vm,
fib_node_vft_t *vft;
vlib_cli_output (vm, "FIB memory");
+ vlib_cli_output (vm, " Tables:");
+ vlib_cli_output (vm, "%=30s %=6s %=8s", "SAFI", "Number", "Bytes");
+ vlib_cli_output (vm, "%U", format_fib_table_memory);
+ vlib_cli_output (vm, "%U", format_mfib_table_memory);
+ vlib_cli_output (vm, " Nodes:");
vlib_cli_output (vm, "%=30s %=5s %=8s/%=9s totals",
"Name","Size", "in-use", "allocated");
@@ -255,15 +262,25 @@ fib_memory_show (vlib_main_t * vm,
*
* @cliexpar
* @cliexstart{show fib memory}
- * FIB memory
- * Name Size in-use /allocated totals
- * Entry 120 11 / 11 1320/1320
- * Entry Source 32 11 / 11 352/352
- * Entry Path-Extensions 44 0 / 0 0/0
- * Path-list 40 11 / 11 440/440
- * Path 88 11 / 11 968/968
- * Node-list elements 20 11 / 11 220/220
- * Node-list heads 8 13 / 13 104/104
+ *FIB memory
+ * Tables:
+ * SAFI Number Bytes
+ * IPv4 unicast 2 673066
+ * IPv6 unicast 2 1054608
+ * MPLS 1 4194312
+ * IPv4 multicast 2 2322
+ * IPv6 multicast 2 ???
+ * Nodes:
+ * Name Size in-use /allocated totals
+ * Entry 96 20 / 20 1920/1920
+ * Entry Source 32 0 / 0 0/0
+ * Entry Path-Extensions 60 0 / 0 0/0
+ * multicast-Entry 192 12 / 12 2304/2304
+ * Path-list 40 28 / 28 1120/1120
+ * uRPF-list 16 20 / 20 320/320
+ * Path 72 28 / 28 2016/2016
+ * Node-list elements 20 28 / 28 560/560
+ * Node-list heads 8 30 / 30 240/240
* @cliexend
?*/
VLIB_CLI_COMMAND (show_fib_memory, static) = {
diff --git a/src/vnet/fib/fib_table.c b/src/vnet/fib/fib_table.c
index 4dd6e7c5421..80e5a0fe1a0 100644
--- a/src/vnet/fib/fib_table.c
+++ b/src/vnet/fib/fib_table.c
@@ -1296,3 +1296,13 @@ fib_table_flush (u32 fib_index,
vec_free(ctx.ftf_entries);
}
+
+u8 *
+format_fib_table_memory (u8 *s, va_list *args)
+{
+ s = format(s, "%U", format_ip4_fib_table_memory);
+ s = format(s, "%U", format_ip6_fib_table_memory);
+ s = format(s, "%U", format_mpls_fib_table_memory);
+
+ return (s);
+}
diff --git a/src/vnet/fib/fib_table.h b/src/vnet/fib/fib_table.h
index d2522aa50c8..8a0c73968fb 100644
--- a/src/vnet/fib/fib_table.h
+++ b/src/vnet/fib/fib_table.h
@@ -808,4 +808,9 @@ extern void fib_table_walk(u32 fib_index,
fib_table_walk_fn_t fn,
void *ctx);
+/**
+ * @brief format (display) the memory used by the FIB tables
+ */
+extern u8 *format_fib_table_memory(u8 *s, va_list *args);
+
#endif
diff --git a/src/vnet/fib/ip4_fib.c b/src/vnet/fib/ip4_fib.c
index 36cf6e73629..45f197444e4 100644
--- a/src/vnet/fib/ip4_fib.c
+++ b/src/vnet/fib/ip4_fib.c
@@ -481,6 +481,43 @@ ip4_fib_table_show_one (ip4_fib_t *fib,
FIB_ENTRY_FORMAT_DETAIL));
}
+u8 *
+format_ip4_fib_table_memory (u8 * s, va_list * args)
+{
+ fib_table_t *fib_table;
+ u64 total_memory;
+
+ total_memory = 0;
+
+ pool_foreach (fib_table, ip4_main.fibs,
+ ({
+ ip4_fib_t *fib;
+ uword fib_size;
+ int i;
+
+ fib = pool_elt_at_index(ip4_main.v4_fibs, fib_table->ft_index);
+ fib_size = ip4_fib_mtrie_memory_usage(&fib->mtrie);
+
+ for (i = 0; i < ARRAY_LEN (fib->fib_entry_by_dst_address); i++)
+ {
+ uword * hash = fib->fib_entry_by_dst_address[i];
+
+ if (NULL != hash)
+ {
+ fib_size += hash_bytes(hash);
+ }
+ }
+
+ total_memory += fib_size;
+ }));
+
+ s = format(s, "%=30s %=6d %=8ld\n",
+ "IPv4 unicast",
+ pool_elts(ip4_main.fibs), total_memory);
+
+ return (s);
+}
+
static clib_error_t *
ip4_show_fib (vlib_main_t * vm,
unformat_input_t * input,
@@ -488,15 +525,17 @@ ip4_show_fib (vlib_main_t * vm,
{
ip4_main_t * im4 = &ip4_main;
fib_table_t * fib_table;
- int verbose, matching, mtrie;
+ u64 total_mtrie_memory, total_hash_memory;
+ int verbose, matching, mtrie, memory;
ip4_address_t matching_address;
u32 matching_mask = 32;
int i, table_id = -1, fib_index = ~0;
int detail = 0;
verbose = 1;
- matching = 0;
- mtrie = 0;
+ matching = mtrie = memory = 0;
+ total_hash_memory = total_mtrie_memory = 0;
+
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "brief") || unformat (input, "summary")
@@ -509,6 +548,10 @@ ip4_show_fib (vlib_main_t * vm,
else if (unformat (input, "mtrie"))
mtrie = 1;
+ else if (unformat (input, "mem") ||
+ unformat (input, "memory"))
+ memory = 1;
+
else if (unformat (input, "%U/%d",
unformat_ip4_address, &matching_address, &matching_mask))
matching = 1;
@@ -535,6 +578,32 @@ ip4_show_fib (vlib_main_t * vm,
if (fib_index != ~0 && fib_index != (int)fib->index)
continue;
+ if (memory)
+ {
+ uword mtrie_size, hash_size;
+
+ mtrie_size = ip4_fib_mtrie_memory_usage(&fib->mtrie);
+ hash_size = 0;
+
+ for (i = 0; i < ARRAY_LEN (fib->fib_entry_by_dst_address); i++)
+ {
+ uword * hash = fib->fib_entry_by_dst_address[i];
+ if (NULL != hash)
+ {
+ hash_size += hash_bytes(hash);
+ }
+ }
+ if (verbose)
+ vlib_cli_output (vm, "%U mtrie:%d hash:%d",
+ format_fib_table_name, fib->index,
+ FIB_PROTOCOL_IP4,
+ mtrie_size,
+ hash_size);
+ total_mtrie_memory += mtrie_size;
+ total_hash_memory += hash_size;
+ continue;
+ }
+
s = format(s, "%U, fib_index:%d, flow hash:[%U] locks:[",
format_fib_table_name, fib->index,
FIB_PROTOCOL_IP4,
@@ -584,6 +653,12 @@ ip4_show_fib (vlib_main_t * vm,
}
}));
+ if (memory)
+ vlib_cli_output (vm, "totals: mtrie:%ld hash:%ld all:%ld",
+ total_mtrie_memory,
+ total_hash_memory,
+ total_mtrie_memory + total_hash_memory);
+
return 0;
}
diff --git a/src/vnet/fib/ip4_fib.h b/src/vnet/fib/ip4_fib.h
index 495b45ccab4..438eb2405bf 100644
--- a/src/vnet/fib/ip4_fib.h
+++ b/src/vnet/fib/ip4_fib.h
@@ -131,6 +131,7 @@ extern u32 ip4_fib_table_find_or_create_and_lock(u32 table_id,
fib_source_t src);
extern u32 ip4_fib_table_create_and_lock(fib_source_t src);
+extern u8 *format_ip4_fib_table_memory(u8 * s, va_list * args);
static inline
u32 ip4_fib_index_from_table_id (u32 table_id)
diff --git a/src/vnet/fib/ip6_fib.c b/src/vnet/fib/ip6_fib.c
index f37ae0d2f45..3400987018f 100644
--- a/src/vnet/fib/ip6_fib.c
+++ b/src/vnet/fib/ip6_fib.c
@@ -524,6 +524,18 @@ ip6_fib_table_show_one (ip6_fib_t *fib,
FIB_ENTRY_FORMAT_DETAIL));
}
+u8 *
+format_ip6_fib_table_memory (u8 * s, va_list * args)
+{
+ s = format(s, "%=30s %=6d %=8ld\n",
+ "IPv6 unicast",
+ pool_elts(ip6_main.fibs),
+ mheap_bytes(ip6_main.ip6_table[IP6_FIB_TABLE_NON_FWDING].ip6_hash.mheap) +
+ mheap_bytes(ip6_main.ip6_table[IP6_FIB_TABLE_FWDING].ip6_hash.mheap));
+
+ return (s);
+}
+
typedef struct {
u32 fib_index;
u64 count_by_prefix_length[129];
diff --git a/src/vnet/fib/ip6_fib.h b/src/vnet/fib/ip6_fib.h
index 9728eecca8b..eda53628b01 100644
--- a/src/vnet/fib/ip6_fib.h
+++ b/src/vnet/fib/ip6_fib.h
@@ -148,6 +148,8 @@ extern u32 ip6_fib_table_find_or_create_and_lock(u32 table_id,
fib_source_t src);
extern u32 ip6_fib_table_create_and_lock(fib_source_t src);
+extern u8 *format_ip6_fib_table_memory(u8 * s, va_list * args);
+
static inline ip6_fib_t *
ip6_fib_get (fib_node_index_t index)
{
diff --git a/src/vnet/fib/mpls_fib.c b/src/vnet/fib/mpls_fib.c
index 4eeef7abb73..15931203122 100644
--- a/src/vnet/fib/mpls_fib.c
+++ b/src/vnet/fib/mpls_fib.c
@@ -359,6 +359,18 @@ mpls_fib_table_walk (mpls_fib_t *mpls_fib,
}));
}
+u8 *
+format_mpls_fib_table_memory (u8 * s, va_list * args)
+{
+ u64 n_tables, mem;
+
+ n_tables = pool_elts(mpls_main.fibs);
+ mem = n_tables * sizeof(mpls_fib_t);
+ s = format(s, "%=30s %=6ld %=8ld\n", "MPLS", n_tables, mem);
+
+ return (s);
+}
+
static void
mpls_fib_table_show_all (const mpls_fib_t *mpls_fib,
vlib_main_t * vm)
diff --git a/src/vnet/fib/mpls_fib.h b/src/vnet/fib/mpls_fib.h
index 29cd1d20dab..9e0c7d76ff8 100644
--- a/src/vnet/fib/mpls_fib.h
+++ b/src/vnet/fib/mpls_fib.h
@@ -105,6 +105,8 @@ extern void mpls_fib_table_walk(mpls_fib_t *fib,
fib_table_walk_fn_t fn,
void *ctx);
+extern u8 *format_mpls_fib_table_memory(u8 * s, va_list * args);
+
/**
* @brief
* Lookup a label and EOS bit in the MPLS_FIB table to retrieve the
diff --git a/src/vnet/ip/ip4_mtrie.c b/src/vnet/ip/ip4_mtrie.c
index f114da01b77..5b78cbec1ea 100644
--- a/src/vnet/ip/ip4_mtrie.c
+++ b/src/vnet/ip/ip4_mtrie.c
@@ -683,8 +683,8 @@ mtrie_ply_memory_usage (ip4_fib_mtrie_t * m, ip4_fib_mtrie_8_ply_t * p)
}
/* Returns number of bytes of memory used by mtrie. */
-static uword
-mtrie_memory_usage (ip4_fib_mtrie_t * m)
+uword
+ip4_fib_mtrie_memory_usage (ip4_fib_mtrie_t * m)
{
uword bytes, i;
@@ -771,7 +771,9 @@ format_ip4_fib_mtrie (u8 * s, va_list * va)
s = format (s, "%d plies, memory usage %U\n",
pool_elts (ip4_ply_pool),
- format_memory_size, mtrie_memory_usage (m));
+ format_memory_size, ip4_fib_mtrie_memory_usage (m));
+ s = format (s, "root-ply");
+ p = &m->root_ply;
if (verbose)
{
diff --git a/src/vnet/ip/ip4_mtrie.h b/src/vnet/ip/ip4_mtrie.h
index be262c2c84d..34b97dc1a9d 100644
--- a/src/vnet/ip/ip4_mtrie.h
+++ b/src/vnet/ip/ip4_mtrie.h
@@ -162,6 +162,11 @@ void ip4_fib_mtrie_route_del (ip4_fib_mtrie_t * m,
u32 cover_address_length, u32 cover_adj_index);
/**
+ * @brief return the memory used by the table
+ */
+uword ip4_fib_mtrie_memory_usage (ip4_fib_mtrie_t * m);
+
+/**
* @brief Format/display the contents of the mtrie
*/
format_function_t format_ip4_fib_mtrie;
diff --git a/src/vnet/mfib/ip4_mfib.c b/src/vnet/mfib/ip4_mfib.c
index b2482580678..7040fa71764 100644
--- a/src/vnet/mfib/ip4_mfib.c
+++ b/src/vnet/mfib/ip4_mfib.c
@@ -305,6 +305,42 @@ ip4_mfib_table_walk (ip4_mfib_t *mfib,
}
}
+u8 *
+format_ip4_mfib_table_memory (u8 * s, va_list * args)
+{
+ mfib_table_t *mfib_table;
+ u64 total_memory;
+
+ total_memory = 0;
+
+ pool_foreach (mfib_table, ip4_main.mfibs,
+ ({
+ ip4_mfib_t *mfib = &mfib_table->v4;
+ uword mfib_size;
+ int i;
+
+ mfib_size = 0;
+
+ for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++)
+ {
+ uword * hash = mfib->fib_entry_by_dst_address[i];
+
+ if (NULL != hash)
+ {
+ mfib_size += hash_bytes(hash);
+ }
+ }
+
+ total_memory += mfib_size;
+ }));
+
+ s = format(s, "%=30s %=6d %=8ld\n",
+ "IPv4 multicast",
+ pool_elts(ip4_main.mfibs), total_memory);
+
+ return (s);
+}
+
static void
ip4_mfib_table_show_all (ip4_mfib_t *mfib,
vlib_main_t * vm)
@@ -363,20 +399,23 @@ ip4_show_mfib (vlib_main_t * vm,
{
ip4_main_t * im4 = &ip4_main;
mfib_table_t *mfib_table;
- int verbose, matching;
+ int verbose, matching, memory;
ip4_address_t grp, src = {{0}};
u32 mask = 32;
+ u64 total_hash_memory;
int i, table_id = -1, fib_index = ~0;
verbose = 1;
- matching = 0;
+ memory = matching = 0;
+ total_hash_memory = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "brief") || unformat (input, "summary")
|| unformat (input, "sum"))
verbose = 0;
-
+ else if (unformat (input, "mem") || unformat (input, "memory"))
+ memory = 1;
else if (unformat (input, "%U %U",
unformat_ip4_address, &src,
unformat_ip4_address, &grp))
@@ -412,6 +451,29 @@ ip4_show_mfib (vlib_main_t * vm,
if (fib_index != ~0 && fib_index != (int)mfib->index)
continue;
+ if (memory)
+ {
+ uword hash_size;
+
+ hash_size = 0;
+
+ for (i = 0; i < ARRAY_LEN (mfib->fib_entry_by_dst_address); i++)
+ {
+ uword * hash = mfib->fib_entry_by_dst_address[i];
+ if (NULL != hash)
+ {
+ hash_size += hash_bytes(hash);
+ }
+ }
+ if (verbose)
+ vlib_cli_output (vm, "%U hash:%d",
+ format_mfib_table_name, mfib->index,
+ FIB_PROTOCOL_IP4,
+ hash_size);
+ total_hash_memory += hash_size;
+ continue;
+ }
+
vlib_cli_output (vm, "%U, fib_index %d",
format_mfib_table_name, mfib->index, FIB_PROTOCOL_IP4,
mfib->index);
@@ -439,6 +501,8 @@ ip4_show_mfib (vlib_main_t * vm,
ip4_mfib_table_show_one(mfib, vm, &src, &grp, mask);
}
}));
+ if (memory)
+ vlib_cli_output (vm, "totals: hash:%ld", total_hash_memory);
return 0;
}
diff --git a/src/vnet/mfib/ip4_mfib.h b/src/vnet/mfib/ip4_mfib.h
index e31fb744b9b..7767d795cad 100644
--- a/src/vnet/mfib/ip4_mfib.h
+++ b/src/vnet/mfib/ip4_mfib.h
@@ -98,8 +98,13 @@ extern u32 ip4_mfib_table_get_index_for_sw_if_index(u32 sw_if_index);
* @param fn The function to invoke on each entry visited
* @param ctx A context passed in the visit function
*/
-extern void ip4_mfib_table_walk (ip4_mfib_t *mfib,
- mfib_table_walk_fn_t fn,
- void *ctx);
+extern void ip4_mfib_table_walk(ip4_mfib_t *mfib,
+ mfib_table_walk_fn_t fn,
+ void *ctx);
+
+/**
+ * @brief format (display) the memory usage for IP4 mfibs
+ */
+extern u8 * format_ip4_mfib_table_memory(u8 * s, va_list * args);
#endif
diff --git a/src/vnet/mfib/ip6_mfib.c b/src/vnet/mfib/ip6_mfib.c
index e4861330654..1c1f5db71f7 100644
--- a/src/vnet/mfib/ip6_mfib.c
+++ b/src/vnet/mfib/ip6_mfib.c
@@ -472,6 +472,16 @@ ip6_mfib_module_init (vlib_main_t * vm)
VLIB_INIT_FUNCTION(ip6_mfib_module_init);
+u8 *
+format_ip6_mfib_table_memory (u8 * s, va_list * args)
+{
+ s = format(s, "%=30s %=6d %=8s\n",
+ "IPv6 multicast",
+ pool_elts(ip6_main.mfibs), "???");
+
+ return (s);
+}
+
static void
ip6_mfib_table_show_one (ip6_mfib_t *mfib,
vlib_main_t * vm,
@@ -566,7 +576,7 @@ ip6_show_mfib (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
- ip6_main_t * im4 = &ip6_main;
+ ip6_main_t * im6 = &ip6_main;
mfib_table_t *mfib_table;
int verbose, matching;
ip6_address_t grp, src = {{0}};
@@ -608,7 +618,7 @@ ip6_show_mfib (vlib_main_t * vm,
break;
}
- pool_foreach (mfib_table, im4->mfibs,
+ pool_foreach (mfib_table, im6->mfibs,
({
ip6_mfib_t *mfib = &mfib_table->v6;
@@ -649,7 +659,7 @@ ip6_show_mfib (vlib_main_t * vm,
}
/*
- * This command displays the IPv4 MulticasrFIB Tables (VRF Tables) and
+ * This command displays the IPv6 MulticasrFIB Tables (VRF Tables) and
* the route entries for each table.
*
* @note This command will run for a long time when the FIB tables are
@@ -657,9 +667,9 @@ ip6_show_mfib (vlib_main_t * vm,
* a single table or summary mode.
*
* @cliexpar
- * Example of how to display all the IPv4 Multicast FIB tables:
+ * Example of how to display all the IPv6 Multicast FIB tables:
* @cliexstart{show ip fib}
- * ipv4-VRF:0, fib_index 0
+ * ipv6-VRF:0, fib_index 0
* (*, 0.0.0.0/0): flags:D,
* Interfaces:
* multicast-ip6-chain
@@ -671,18 +681,18 @@ ip6_show_mfib (vlib_main_t * vm,
* test-eth0: Accept,
* multicast-ip6-chain
* [@2]: dpo-replicate: [index:1 buckets:2 to:[0:0]]
- * [0] [@1]: ipv4-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
- * [1] [@1]: ipv4-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
+ * [0] [@1]: ipv6-mcast: test-eth1: IP6: d0:d1:d2:d3:d4:01 -> 01:00:05:00:00:00
+ * [1] [@1]: ipv6-mcast: test-eth2: IP6: d0:d1:d2:d3:d4:02 -> 01:00:05:00:00:00
*
* @cliexend
- * Example of how to display a summary of all IPv4 FIB tables:
+ * Example of how to display a summary of all IPv6 FIB tables:
* @cliexstart{show ip fib summary}
- * ipv4-VRF:0, fib_index 0, flow hash: src dst sport dport proto
+ * ipv6-VRF:0, fib_index 0, flow hash: src dst sport dport proto
* Prefix length Count
* 0 1
* 8 2
* 32 4
- * ipv4-VRF:7, fib_index 1, flow hash: src dst sport dport proto
+ * ipv6-VRF:7, fib_index 1, flow hash: src dst sport dport proto
* Prefix length Count
* 0 1
* 8 2
diff --git a/src/vnet/mfib/ip6_mfib.h b/src/vnet/mfib/ip6_mfib.h
index ea81b553cd5..5ebdd0a6ff4 100644
--- a/src/vnet/mfib/ip6_mfib.h
+++ b/src/vnet/mfib/ip6_mfib.h
@@ -117,5 +117,10 @@ extern void ip6_mfib_table_walk (ip6_mfib_t *mfib,
mfib_table_walk_fn_t fn,
void *ctx);
+/**
+ * @brief format (display) ipv6 MFIB mempry usage
+ */
+extern u8 *format_ip6_mfib_table_memory(u8 * s, va_list * args);
+
#endif
diff --git a/src/vnet/mfib/mfib_table.c b/src/vnet/mfib/mfib_table.c
index efeadefb2d6..dc51b7c6ce8 100644
--- a/src/vnet/mfib/mfib_table.c
+++ b/src/vnet/mfib/mfib_table.c
@@ -628,6 +628,15 @@ format_mfib_table_name (u8* s, va_list *ap)
return (s);
}
+u8 *
+format_mfib_table_memory (u8 *s, va_list *args)
+{
+ s = format(s, "%U", format_ip4_mfib_table_memory);
+ s = format(s, "%U", format_ip6_mfib_table_memory);
+
+ return (s);
+}
+
static clib_error_t *
mfib_module_init (vlib_main_t * vm)
{
diff --git a/src/vnet/mfib/mfib_table.h b/src/vnet/mfib/mfib_table.h
index 6a5810291fc..63af25b0151 100644
--- a/src/vnet/mfib/mfib_table.h
+++ b/src/vnet/mfib/mfib_table.h
@@ -420,5 +420,9 @@ extern void mfib_table_walk(u32 fib_index,
fib_protocol_t proto,
mfib_table_walk_fn_t fn,
void *ctx);
+/**
+ * @brief format (display) the memory usage for mfibs
+ */
+extern u8 * format_mfib_table_memory(u8 * s, va_list * args);
#endif