FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
fib_node.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/fib/fib_node.h>
17 #include <vnet/fib/fib_node_list.h>
18 
19 /*
20  * The per-type vector of virtual function tables
21  */
23 
24 /**
25  * The last registered new type
26  */
28 
29 /*
30  * the node type names
31  */
32 static const char *fn_type_names[] = FIB_NODE_TYPES;
33 
34 const char*
36 {
37  if (type < FIB_NODE_TYPE_LAST)
38  return (fn_type_names[type]);
39  else
40  {
41  if (NULL != fn_vfts[type].fnv_format)
42  {
43  return ("fixme");
44  }
45  else
46  {
47  return ("unknown");
48  }
49  }
50 }
51 
52 /**
53  * fib_node_register_type
54  *
55  * Register the function table for a given type
56  */
57 void
59  const fib_node_vft_t *vft)
60 {
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;
75 }
76 
79 {
80  fib_node_type_t new_type;
81 
82  new_type = ++last_new_type;
83 
84  fib_node_register_type(new_type, vft);
85 
86  return (new_type);
87 }
88 
89 static u8*
91 {
92  return (format(s, "{%s:%d}", fn_type_names[fnp->fnp_type], fnp->fnp_index));
93 }
94 
95 u32
97  fib_node_index_t parent_index,
98  fib_node_type_t type,
99  fib_node_index_t index)
100 {
101  fib_node_t *parent;
102 
103  parent = fn_vfts[parent_type].fnv_get(parent_index);
104 
105  /*
106  * return the index of the sibling in the child list
107  */
108  fib_node_lock(parent);
109 
110  if (FIB_NODE_INDEX_INVALID == parent->fn_children)
111  {
112  parent->fn_children = fib_node_list_create();
113  }
114 
115  return (fib_node_list_push_front(parent->fn_children,
116  0, type,
117  index));
118 }
119 
120 void
122  fib_node_index_t parent_index,
123  fib_node_index_t sibling_index)
124 {
125  fib_node_t *parent;
126 
127  parent = fn_vfts[parent_type].fnv_get(parent_index);
128 
129  fib_node_list_remove(parent->fn_children, sibling_index);
130 
131  if (0 == fib_node_list_get_size(parent->fn_children))
132  {
134  }
135 
136  fib_node_unlock(parent);
137 }
138 
139 u32
141  fib_node_index_t parent_index)
142 {
143  fib_node_t *parent;
144 
145  parent = fn_vfts[parent_type].fnv_get(parent_index);
146 
147  return (fib_node_list_get_size(parent->fn_children));
148 }
149 
150 
154 {
155  fib_node_t *node;
156 
157  node = fn_vfts[ptr->fnp_type].fnv_get(ptr->fnp_index);
158 
159  return (fn_vfts[ptr->fnp_type].fnv_back_walk(node, ctx));
160 }
161 
162 static int
164  void *arg)
165 {
166  u8 **s = (u8**) arg;
167 
168  *s = fib_node_format(ptr, *s);
169 
170  return (1);
171 }
172 
173 u8*
175  u8 *s)
176 {
178 
179  return (s);
180 }
181 
182 void
184  fib_node_type_t type)
185 {
186 #if CLIB_DEBUG > 0
187  /**
188  * The node's type. make sure we are dynamic/down casting correctly
189  */
190  node->fn_type = type;
191 #endif
192  node->fn_locks = 0;
193  node->fn_vft = &fn_vfts[type];
195 }
196 
197 void
199 {
201 }
202 
203 void
205 {
206  node->fn_locks++;
207 }
208 
209 void
211 {
212  node->fn_locks--;
213 
214  if (0 == node->fn_locks)
215  {
216  node->fn_vft->fnv_last_lock(node);
217  }
218 }
219 
220 void
221 fib_show_memory_usage (const char *name,
222  u32 in_use_elts,
223  u32 allocd_elts,
224  size_t size_elt)
225 {
226  vlib_cli_output (vlib_get_main(), "%=30s %=5d %=8d/%=9d %d/%d ",
227  name, size_elt,
228  in_use_elts, allocd_elts,
229  in_use_elts*size_elt, allocd_elts*size_elt);
230 }
231 
232 static clib_error_t *
234  unformat_input_t * input,
235  vlib_cli_command_t * cmd)
236 {
237  fib_node_vft_t *vft;
238 
239  vlib_cli_output (vm, "FIB memory");
240  vlib_cli_output (vm, "%=30s %=5s %=8s/%=9s totals",
241  "Name","Size", "in-use", "allocated");
242 
243  vec_foreach(vft, fn_vfts)
244  {
245  if (NULL != vft->fnv_mem_show)
246  vft->fnv_mem_show();
247  }
248 
250 
251  return (NULL);
252 }
253 
254 /* *INDENT-OFF* */
255 /*?
256  * The '<em>sh fib memory </em>' command displays the memory usage for each
257  * FIB object type.
258  *
259  * @cliexpar
260  * @cliexstart{show fib memory}
261  * FIB memory
262  * Name Size in-use /allocated totals
263  * Entry 120 11 / 11 1320/1320
264  * Entry Source 32 11 / 11 352/352
265  * Entry Path-Extensions 44 0 / 0 0/0
266  * Path-list 40 11 / 11 440/440
267  * Path 88 11 / 11 968/968
268  * Node-list elements 20 11 / 11 220/220
269  * Node-list heads 8 13 / 13 104/104
270  * @cliexend
271 ?*/
272 VLIB_CLI_COMMAND (show_fib_memory, static) = {
273  .path = "show fib memory",
274  .function = fib_memory_show,
275  .short_help = "show fib memory",
276 };
277 /* *INDENT-ON* */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
static fib_node_type_t last_new_type
The last registered new type.
Definition: fib_node.c:27
const fib_node_vft_t * fn_vft
The node&#39;s VFT.
Definition: fib_node.h:289
enum fib_node_type_t_ fib_node_type_t
The types of nodes in a FIB graph.
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:183
#define NULL
Definition: clib.h:55
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
void fib_node_list_memory_show(void)
void fib_node_deinit(fib_node_t *node)
Definition: fib_node.c:198
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
static fib_node_vft_t * fn_vfts
Definition: fib_node.c:22
void fib_node_list_walk(fib_node_list_t list, fib_node_list_walk_cb_t fn, void *args)
Walk the list of node.
fib_node_type_t fib_node_register_new_type(const fib_node_vft_t *vft)
Create a new FIB node type and Register the function table for it.
Definition: fib_node.c:78
u32 fib_node_child_add(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_type_t type, fib_node_index_t index)
Definition: fib_node.c:96
void fib_node_register_type(fib_node_type_t type, const fib_node_vft_t *vft)
fib_node_register_type
Definition: fib_node.c:58
fib_node_index_t fnp_index
node&#39;s index
Definition: fib_node.h:179
void fib_node_list_remove(fib_node_list_t list, u32 sibling)
fib_node_back_walk_rc_t fib_node_back_walk_one(fib_node_ptr_t *ptr, fib_node_back_walk_ctx_t *ctx)
Definition: fib_node.c:152
fib_node_last_lock_gone_t fnv_last_lock
Definition: fib_node.h:266
void fib_show_memory_usage(const char *name, u32 in_use_elts, u32 allocd_elts, size_t size_elt)
Show the memory usage for a type.
Definition: fib_node.c:221
A representation of one pointer to another node.
Definition: fib_node.h:171
#define FIB_NODE_TYPES
Definition: fib_node.h:54
fib_node_type_t fnp_type
node type
Definition: fib_node.h:175
void fib_node_lock(fib_node_t *node)
Definition: fib_node.c:204
struct _unformat_input_t unformat_input_t
u32 fib_node_list_push_front(fib_node_list_t list, int owner_id, fib_node_type_t type, fib_node_index_t index)
Insert an element at the from of the list.
fib_node_type_t fn_type
The node&#39;s type.
Definition: fib_node.h:282
static const char * fn_type_names[]
Definition: fib_node.c:32
An node in the FIB graph.
Definition: fib_node.h:277
void fib_node_unlock(fib_node_t *node)
Definition: fib_node.c:210
fib_node_list_t fn_children
Vector of nodes that depend upon/use/share this node.
Definition: fib_node.h:294
vlib_main_t * vm
Definition: buffer.c:276
fib_node_get_t fnv_get
Definition: fib_node.h:265
fib_node_back_walk_t fnv_back_walk
Definition: fib_node.h:267
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
u32 fib_node_get_n_children(fib_node_type_t parent_type, fib_node_index_t parent_index)
Definition: fib_node.c:140
Context passed between object during a back walk.
Definition: fib_node.h:190
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u32 fib_node_list_get_size(fib_node_list_t list)
static clib_error_t * fib_memory_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: fib_node.c:233
#define ASSERT(truth)
fib_node_list_t fib_node_list_create(void)
Create a new node list.
unsigned int u32
Definition: types.h:88
static int fib_node_ptr_format_one_child(fib_node_ptr_t *ptr, void *arg)
Definition: fib_node.c:163
void fib_node_list_destroy(fib_node_list_t *list)
void fib_node_child_remove(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_index_t sibling_index)
Definition: fib_node.c:121
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:29
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
u32 fn_locks
Number of dependents on this node.
Definition: fib_node.h:300
A FIB graph nodes virtual function table.
Definition: fib_node.h:264
static u8 * fib_node_format(fib_node_ptr_t *fnp, u8 *s)
Definition: fib_node.c:90
u32 fib_node_list_t
A list of FIB nodes.
Definition: fib_node.h:185
#define vec_foreach(var, vec)
Vector iterator.
u8 * fib_node_children_format(fib_node_list_t list, u8 *s)
Definition: fib_node.c:174
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:577
const char * fib_node_type_get_name(fib_node_type_t type)
Definition: fib_node.c:35
fib_node_memory_show_t fnv_mem_show
Definition: fib_node.h:269