FD.io VPP  v16.12-rc0-308-g931be3a
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,
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 
143 {
144  fib_node_t *node;
145 
146  node = fn_vfts[ptr->fnp_type].fnv_get(ptr->fnp_index);
147 
148  return (fn_vfts[ptr->fnp_type].fnv_back_walk(node, ctx));
149 }
150 
151 static int
153  void *arg)
154 {
155  u8 **s = (u8**) arg;
156 
157  *s = fib_node_format(ptr, *s);
158 
159  return (1);
160 }
161 
162 u8*
164  u8 *s)
165 {
167 
168  return (s);
169 }
170 
171 void
174 {
175 #if CLIB_DEBUG > 0
176  /**
177  * The node's type. make sure we are dynamic/down casting correctly
178  */
179  node->fn_type = type;
180 #endif
181  node->fn_locks = 0;
182  node->fn_vft = &fn_vfts[type];
184 }
185 
186 void
188 {
190 }
191 
192 void
194 {
195  node->fn_locks++;
196 }
197 
198 void
200 {
201  node->fn_locks--;
202 
203  if (0 == node->fn_locks)
204  {
205  node->fn_vft->fnv_last_lock(node);
206  }
207 }
208 
209 void
210 fib_show_memory_usage (const char *name,
211  u32 in_use_elts,
212  u32 allocd_elts,
213  size_t size_elt)
214 {
215  vlib_cli_output (vlib_get_main(), "%=30s %=5d %=8d/%=9d %d/%d ",
216  name, size_elt,
217  in_use_elts, allocd_elts,
218  in_use_elts*size_elt, allocd_elts*size_elt);
219 }
220 
221 static clib_error_t *
223  unformat_input_t * input,
224  vlib_cli_command_t * cmd)
225 {
226  fib_node_vft_t *vft;
227 
228  vlib_cli_output (vm, "FIB memory");
229  vlib_cli_output (vm, "%=30s %=5s %=8s/%=9s totals",
230  "Name","Size", "in-use", "allocated");
231 
232  vec_foreach(vft, fn_vfts)
233  {
234  if (NULL != vft->fnv_mem_show)
235  vft->fnv_mem_show();
236  }
237 
239 
240  return (NULL);
241 }
242 
243 /* *INDENT-OFF* */
244 /*?
245  * The '<em>sh fib memory </em>' command displays the memory usage for each
246  * FIB object type.
247  *
248  * @cliexpar
249  * @cliexstart{show fib memory}
250  * FIB memory
251  * Name Size in-use /allocated totals
252  * Entry 120 11 / 11 1320/1320
253  * Entry Source 32 11 / 11 352/352
254  * Entry Path-Extensions 44 0 / 0 0/0
255  * Path-list 40 11 / 11 440/440
256  * Path 88 11 / 11 968/968
257  * Node-list elements 20 11 / 11 220/220
258  * Node-list heads 8 13 / 13 104/104
259  * @cliexend
260 ?*/
261 VLIB_CLI_COMMAND (show_fib_memory, static) = {
262  .path = "show fib memory",
263  .function = fib_memory_show,
264  .short_help = "show fib memory",
265 };
266 /* *INDENT-ON* */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
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:254
enum fib_node_type_t_ fib_node_type_t
The types of nodes in a FIB graph.
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:172
#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:187
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:149
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:141
fib_node_last_lock_gone_t fnv_last_lock
Definition: fib_node.h:231
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:210
A representation of one pointer to another node.
Definition: fib_node.h:141
#define FIB_NODE_TYPES
Definition: fib_node.h:50
fib_node_type_t fnp_type
node type
Definition: fib_node.h:145
void fib_node_lock(fib_node_t *node)
Definition: fib_node.c:193
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:247
static const char * fn_type_names[]
Definition: fib_node.c:32
An node in the FIB graph.
Definition: fib_node.h:242
void fib_node_unlock(fib_node_t *node)
Definition: fib_node.c:199
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
fib_node_list_t fn_children
Vector of nodes that depend upon/use/share this node.
Definition: fib_node.h:259
fib_node_get_t fnv_get
Definition: fib_node.h:230
fib_node_back_walk_t fnv_back_walk
Definition: fib_node.h:232
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
Context passed between object during a back walk.
Definition: fib_node.h:160
#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:222
#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:152
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
#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:265
A FIB graph nodes virtual function table.
Definition: fib_node.h:229
static u8 * fib_node_format(fib_node_ptr_t *fnp, u8 *s)
Definition: fib_node.c:90
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
u32 fib_node_list_t
A list of FIB nodes.
Definition: fib_node.h:155
#define vec_foreach(var, vec)
Vector iterator.
struct _unformat_input_t unformat_input_t
u8 * fib_node_children_format(fib_node_list_t list, u8 *s)
Definition: fib_node.c:163
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:234