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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <vnet/fib/fib_node.h>
17 #include <vnet/fib/fib_node_list.h>
18 #include <vnet/fib/fib_table.h>
19 #include <vnet/mfib/mfib_table.h>
22 * The per-type vector of virtual function tables
24 static fib_node_vft_t *fn_vfts;
27 * The last registered new type
29 static fib_node_type_t last_new_type = FIB_NODE_TYPE_LAST;
34 static const char *fn_type_names[] = FIB_NODE_TYPES;
37 fib_node_type_get_name (fib_node_type_t type)
39 if (type < FIB_NODE_TYPE_LAST)
40 return (fn_type_names[type]);
43 if (NULL != fn_vfts[type].fnv_format)
55 * fib_node_register_type
57 * Register the function table for a given type
60 fib_node_register_type (fib_node_type_t type,
61 const fib_node_vft_t *vft)
64 * assert that one only registration is made per-node type
66 if (vec_len(fn_vfts) > type)
67 ASSERT(NULL == fn_vfts[type].fnv_get);
70 * Assert that we are getting each of the required functions
72 ASSERT(NULL != vft->fnv_get);
73 ASSERT(NULL != vft->fnv_last_lock);
75 vec_validate(fn_vfts, type);
80 fib_node_register_new_type (const fib_node_vft_t *vft)
82 fib_node_type_t new_type;
84 new_type = ++last_new_type;
86 fib_node_register_type(new_type, vft);
92 fib_node_format (fib_node_ptr_t *fnp, u8*s)
94 return (format(s, "{%s:%d}", fn_type_names[fnp->fnp_type], fnp->fnp_index));
98 fib_node_child_add (fib_node_type_t parent_type,
99 fib_node_index_t parent_index,
100 fib_node_type_t type,
101 fib_node_index_t index)
105 parent = fn_vfts[parent_type].fnv_get(parent_index);
108 * return the index of the sibling in the child list
110 fib_node_lock(parent);
112 if (FIB_NODE_INDEX_INVALID == parent->fn_children)
114 parent->fn_children = fib_node_list_create();
117 return (fib_node_list_push_front(parent->fn_children,
123 fib_node_child_remove (fib_node_type_t parent_type,
124 fib_node_index_t parent_index,
125 fib_node_index_t sibling_index)
129 parent = fn_vfts[parent_type].fnv_get(parent_index);
131 fib_node_list_remove(parent->fn_children, sibling_index);
133 if (0 == fib_node_list_get_size(parent->fn_children))
135 fib_node_list_destroy(&parent->fn_children);
138 fib_node_unlock(parent);
142 fib_node_get_n_children (fib_node_type_t parent_type,
143 fib_node_index_t parent_index)
147 parent = fn_vfts[parent_type].fnv_get(parent_index);
149 return (fib_node_list_get_size(parent->fn_children));
153 fib_node_back_walk_rc_t
154 fib_node_back_walk_one (fib_node_ptr_t *ptr,
155 fib_node_back_walk_ctx_t *ctx)
159 node = fn_vfts[ptr->fnp_type].fnv_get(ptr->fnp_index);
161 return (fn_vfts[ptr->fnp_type].fnv_back_walk(node, ctx));
165 fib_node_ptr_format_one_child (fib_node_ptr_t *ptr,
170 *s = fib_node_format(ptr, *s);
176 fib_node_children_format (fib_node_list_t list,
179 fib_node_list_walk(list, fib_node_ptr_format_one_child, (void*)&s);
185 fib_node_init (fib_node_t *node,
186 fib_node_type_t type)
189 * The node's type. used to retrieve the VFT.
191 node->fn_type = type;
193 node->fn_children = FIB_NODE_INDEX_INVALID;
197 fib_node_deinit (fib_node_t *node)
199 fib_node_list_destroy(&node->fn_children);
203 fib_node_lock (fib_node_t *node)
209 fib_node_unlock (fib_node_t *node)
213 if (0 == node->fn_locks)
215 fn_vfts[node->fn_type].fnv_last_lock(node);
220 fib_show_memory_usage (const char *name,
225 vlib_cli_output (vlib_get_main(), "%=30s %=5d %=8d/%=9d %d/%d ",
227 in_use_elts, allocd_elts,
228 in_use_elts*size_elt, allocd_elts*size_elt);
231 static clib_error_t *
232 fib_memory_show (vlib_main_t * vm,
233 unformat_input_t * input,
234 vlib_cli_command_t * cmd)
238 vlib_cli_output (vm, "FIB memory");
239 vlib_cli_output (vm, " Tables:");
240 vlib_cli_output (vm, "%=30s %=6s %=8s", "SAFI", "Number", "Bytes");
241 vlib_cli_output (vm, "%U", format_fib_table_memory);
242 vlib_cli_output (vm, "%U", format_mfib_table_memory);
243 vlib_cli_output (vm, " Nodes:");
244 vlib_cli_output (vm, "%=30s %=5s %=8s/%=9s totals",
245 "Name","Size", "in-use", "allocated");
247 vec_foreach(vft, fn_vfts)
249 if (NULL != vft->fnv_mem_show)
253 fib_node_list_memory_show();
260 * The '<em>sh fib memory </em>' command displays the memory usage for each
264 * @cliexstart{show fib memory}
268 * IPv4 unicast 2 673066
269 * IPv6 unicast 2 1054608
271 * IPv4 multicast 2 2322
272 * IPv6 multicast 2 ???
274 * Name Size in-use /allocated totals
275 * Entry 96 20 / 20 1920/1920
276 * Entry Source 32 0 / 0 0/0
277 * Entry Path-Extensions 60 0 / 0 0/0
278 * multicast-Entry 192 12 / 12 2304/2304
279 * Path-list 40 28 / 28 1120/1120
280 * uRPF-list 16 20 / 20 320/320
281 * Path 72 28 / 28 2016/2016
282 * Node-list elements 20 28 / 28 560/560
283 * Node-list heads 8 30 / 30 240/240
286 VLIB_CLI_COMMAND (show_fib_memory, static) = {
287 .path = "show fib memory",
288 .function = fib_memory_show,
289 .short_help = "show fib memory",