blob: ff72bcfde406bbef7eb29041fd99081a81c3ecf3 [file] [log] [blame]
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001/*
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/fib/fib_node.h>
17#include <vnet/fib/fib_node_list.h>
Neale Rannsc87aafa2017-11-29 00:59:31 -080018#include <vnet/fib/fib_table.h>
19#include <vnet/mfib/mfib_table.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010020
21/*
22 * The per-type vector of virtual function tables
23 */
24static fib_node_vft_t *fn_vfts;
25
26/**
27 * The last registered new type
28 */
29static fib_node_type_t last_new_type = FIB_NODE_TYPE_LAST;
30
31/*
32 * the node type names
33 */
Neale Ranns20089122021-12-02 17:07:14 +000034static const char *fn_type_builtin_names[] = FIB_NODE_TYPES;
35static const char **fn_type_names;
Neale Ranns0bfe5d82016-08-25 15:29:12 +010036
37const char*
38fib_node_type_get_name (fib_node_type_t type)
39{
Neale Ranns20089122021-12-02 17:07:14 +000040 if ((type < vec_len(fn_type_names)) &&
41 (NULL != fn_type_names[type]))
42 {
43 return (fn_type_names[type]);
44 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010045 else
46 {
Neale Ranns20089122021-12-02 17:07:14 +000047 return ("unknown");
Neale Ranns0bfe5d82016-08-25 15:29:12 +010048 }
49}
50
51/**
52 * fib_node_register_type
53 *
54 * Register the function table for a given type
55 */
Neale Ranns20089122021-12-02 17:07:14 +000056static void
57fib_node_register_type_i (fib_node_type_t type,
58 const char *name,
59 const fib_node_vft_t *vft)
Neale Ranns0bfe5d82016-08-25 15:29:12 +010060{
61 /*
62 * assert that one only registration is made per-node type
63 */
64 if (vec_len(fn_vfts) > type)
65 ASSERT(NULL == fn_vfts[type].fnv_get);
66
67 /*
68 * Assert that we are getting each of the required functions
69 */
70 ASSERT(NULL != vft->fnv_get);
71 ASSERT(NULL != vft->fnv_last_lock);
72
73 vec_validate(fn_vfts, type);
74 fn_vfts[type] = *vft;
Neale Ranns20089122021-12-02 17:07:14 +000075 vec_validate(fn_type_names, type);
76 fn_type_names[type] = name;
77}
78
79/**
80 * fib_node_register_type
81 *
82 * Register the function table for a given type
83 */
84void
85fib_node_register_type (fib_node_type_t type,
86 const fib_node_vft_t *vft)
87{
88 fib_node_register_type_i(type, fn_type_builtin_names[type], vft);
Neale Ranns0bfe5d82016-08-25 15:29:12 +010089}
90
91fib_node_type_t
Neale Ranns20089122021-12-02 17:07:14 +000092fib_node_register_new_type (const char *name,
93 const fib_node_vft_t *vft)
Neale Ranns0bfe5d82016-08-25 15:29:12 +010094{
95 fib_node_type_t new_type;
96
97 new_type = ++last_new_type;
98
Neale Ranns20089122021-12-02 17:07:14 +000099 fib_node_register_type_i(new_type, name, vft);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100100
101 return (new_type);
102}
103
104static u8*
105fib_node_format (fib_node_ptr_t *fnp, u8*s)
106{
107 return (format(s, "{%s:%d}", fn_type_names[fnp->fnp_type], fnp->fnp_index));
108}
109
110u32
111fib_node_child_add (fib_node_type_t parent_type,
112 fib_node_index_t parent_index,
113 fib_node_type_t type,
114 fib_node_index_t index)
115{
116 fib_node_t *parent;
117
118 parent = fn_vfts[parent_type].fnv_get(parent_index);
119
120 /*
121 * return the index of the sibling in the child list
122 */
123 fib_node_lock(parent);
124
125 if (FIB_NODE_INDEX_INVALID == parent->fn_children)
126 {
127 parent->fn_children = fib_node_list_create();
128 }
129
130 return (fib_node_list_push_front(parent->fn_children,
131 0, type,
132 index));
133}
134
135void
136fib_node_child_remove (fib_node_type_t parent_type,
137 fib_node_index_t parent_index,
138 fib_node_index_t sibling_index)
139{
140 fib_node_t *parent;
141
142 parent = fn_vfts[parent_type].fnv_get(parent_index);
143
144 fib_node_list_remove(parent->fn_children, sibling_index);
145
146 if (0 == fib_node_list_get_size(parent->fn_children))
147 {
148 fib_node_list_destroy(&parent->fn_children);
149 }
150
151 fib_node_unlock(parent);
152}
153
Neale Rannsad422ed2016-11-02 14:20:04 +0000154u32
155fib_node_get_n_children (fib_node_type_t parent_type,
156 fib_node_index_t parent_index)
157{
158 fib_node_t *parent;
159
160 parent = fn_vfts[parent_type].fnv_get(parent_index);
161
162 return (fib_node_list_get_size(parent->fn_children));
163}
164
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100165
166fib_node_back_walk_rc_t
167fib_node_back_walk_one (fib_node_ptr_t *ptr,
168 fib_node_back_walk_ctx_t *ctx)
169{
170 fib_node_t *node;
171
172 node = fn_vfts[ptr->fnp_type].fnv_get(ptr->fnp_index);
173
174 return (fn_vfts[ptr->fnp_type].fnv_back_walk(node, ctx));
175}
176
Neale Rannsfdf6b6f2020-11-26 09:34:39 +0000177static walk_rc_t
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100178fib_node_ptr_format_one_child (fib_node_ptr_t *ptr,
179 void *arg)
180{
181 u8 **s = (u8**) arg;
182
183 *s = fib_node_format(ptr, *s);
184
Neale Rannsfdf6b6f2020-11-26 09:34:39 +0000185 return (WALK_CONTINUE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100186}
187
188u8*
189fib_node_children_format (fib_node_list_t list,
190 u8 *s)
191{
192 fib_node_list_walk(list, fib_node_ptr_format_one_child, (void*)&s);
193
194 return (s);
195}
196
197void
198fib_node_init (fib_node_t *node,
199 fib_node_type_t type)
200{
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100201 /**
Neale Ranns630b9742017-11-25 10:04:32 -0800202 * The node's type. used to retrieve the VFT.
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100203 */
204 node->fn_type = type;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100205 node->fn_locks = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100206 node->fn_children = FIB_NODE_INDEX_INVALID;
207}
208
209void
210fib_node_deinit (fib_node_t *node)
211{
212 fib_node_list_destroy(&node->fn_children);
213}
214
215void
216fib_node_lock (fib_node_t *node)
217{
218 node->fn_locks++;
219}
220
221void
222fib_node_unlock (fib_node_t *node)
223{
224 node->fn_locks--;
225
226 if (0 == node->fn_locks)
227 {
Neale Ranns630b9742017-11-25 10:04:32 -0800228 fn_vfts[node->fn_type].fnv_last_lock(node);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100229 }
230}
Neale Ranns6c3ebcc2016-10-02 21:20:15 +0100231
232void
233fib_show_memory_usage (const char *name,
234 u32 in_use_elts,
235 u32 allocd_elts,
236 size_t size_elt)
237{
238 vlib_cli_output (vlib_get_main(), "%=30s %=5d %=8d/%=9d %d/%d ",
239 name, size_elt,
240 in_use_elts, allocd_elts,
241 in_use_elts*size_elt, allocd_elts*size_elt);
242}
243
244static clib_error_t *
245fib_memory_show (vlib_main_t * vm,
246 unformat_input_t * input,
247 vlib_cli_command_t * cmd)
248{
249 fib_node_vft_t *vft;
250
251 vlib_cli_output (vm, "FIB memory");
Neale Rannsc87aafa2017-11-29 00:59:31 -0800252 vlib_cli_output (vm, " Tables:");
Neale Ranns05cac302019-05-28 11:09:40 +0000253 vlib_cli_output (vm, "%=30s %=6s %=12s", "SAFI", "Number", "Bytes");
Neale Rannsc87aafa2017-11-29 00:59:31 -0800254 vlib_cli_output (vm, "%U", format_fib_table_memory);
255 vlib_cli_output (vm, "%U", format_mfib_table_memory);
256 vlib_cli_output (vm, " Nodes:");
Neale Ranns6c3ebcc2016-10-02 21:20:15 +0100257 vlib_cli_output (vm, "%=30s %=5s %=8s/%=9s totals",
258 "Name","Size", "in-use", "allocated");
259
260 vec_foreach(vft, fn_vfts)
261 {
262 if (NULL != vft->fnv_mem_show)
263 vft->fnv_mem_show();
264 }
265
266 fib_node_list_memory_show();
267
268 return (NULL);
269}
270
271/* *INDENT-OFF* */
272/*?
273 * The '<em>sh fib memory </em>' command displays the memory usage for each
274 * FIB object type.
275 *
276 * @cliexpar
277 * @cliexstart{show fib memory}
Neale Rannsc87aafa2017-11-29 00:59:31 -0800278 *FIB memory
279 * Tables:
280 * SAFI Number Bytes
281 * IPv4 unicast 2 673066
282 * IPv6 unicast 2 1054608
283 * MPLS 1 4194312
284 * IPv4 multicast 2 2322
285 * IPv6 multicast 2 ???
286 * Nodes:
287 * Name Size in-use /allocated totals
288 * Entry 96 20 / 20 1920/1920
289 * Entry Source 32 0 / 0 0/0
290 * Entry Path-Extensions 60 0 / 0 0/0
291 * multicast-Entry 192 12 / 12 2304/2304
292 * Path-list 40 28 / 28 1120/1120
293 * uRPF-list 16 20 / 20 320/320
294 * Path 72 28 / 28 2016/2016
295 * Node-list elements 20 28 / 28 560/560
296 * Node-list heads 8 30 / 30 240/240
Neale Ranns6c3ebcc2016-10-02 21:20:15 +0100297 * @cliexend
298?*/
299VLIB_CLI_COMMAND (show_fib_memory, static) = {
300 .path = "show fib memory",
301 .function = fib_memory_show,
302 .short_help = "show fib memory",
303};
304/* *INDENT-ON* */