FD.io VPP  v16.06
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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  * node.c: VLIB processing nodes
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vlib/vlib.h>
41 #include <vlib/threads.h>
42 
43 /* Query node given name. */
45 {
46  vlib_node_main_t * nm = &vm->node_main;
47  uword * p;
48  u8 * key = name;
49  if (! clib_mem_is_heap_object (key))
50  key = format (0, "%s", key);
51  p = hash_get (nm->node_by_name, key);
52  if (key != name)
53  vec_free (key);
54  return p ? vec_elt (nm->nodes, p[0]) : 0;
55 }
56 
57 static void node_set_elog_name (vlib_main_t * vm, uword node_index)
58 {
59  vlib_node_t * n = vlib_get_node (vm, node_index);
61 
62  t = vec_elt_at_index (vm->node_call_elog_event_types, node_index);
63  vec_free (t->format);
64  t->format = (char *) format (0, "%v-call: %%d%c", n->name, 0);
65 
66  t = vec_elt_at_index (vm->node_return_elog_event_types, node_index);
67  vec_free (t->format);
68  t->format = (char *) format (0, "%v-return: %%d%c", n->name, 0);
69 
70  n->name_elog_string = elog_string (&vm->elog_main, "%v%c", n->name,0);
71 }
72 
73 void vlib_node_rename (vlib_main_t * vm, u32 node_index, char * fmt, ...)
74 {
75  va_list va;
76  vlib_node_main_t * nm = &vm->node_main;
77  vlib_node_t * n = vlib_get_node (vm, node_index);
78 
79  va_start (va, fmt);
80  hash_unset (nm->node_by_name, n->name);
81  vec_free (n->name);
82  n->name = va_format (0, fmt, &va);
83  va_end (va);
84  hash_set (nm->node_by_name, n->name, n->index);
85 
86  node_set_elog_name (vm, node_index);
87 }
88 
89 static void
91  u32 node_index,
92  u32 next_index)
93 {
94  vlib_node_main_t * nm = &vm->node_main;
95  vlib_node_runtime_t * r, * s;
96  vlib_node_t * node, * next_node;
97  vlib_next_frame_t * nf;
99  i32 i, j, n_insert;
100 
101  ASSERT(os_get_cpu_number() == 0);
102 
104 
105  node = vec_elt (nm->nodes, node_index);
106  r = vlib_node_get_runtime (vm, node_index);
107 
108  n_insert = vec_len (node->next_nodes) - r->n_next_nodes;
109  if (n_insert > 0)
110  {
111  i = r->next_frame_index + r->n_next_nodes;
112  vec_insert (nm->next_frames, n_insert, i);
113 
114  /* Initialize newly inserted next frames. */
115  for (j = 0; j < n_insert; j++)
116  vlib_next_frame_init (nm->next_frames + i + j);
117 
118  /* Relocate other next frames at higher indices. */
119  for (j = 0; j < vec_len (nm->nodes); j++)
120  {
121  s = vlib_node_get_runtime (vm, j);
122  if (j != node_index
123  && s->next_frame_index >= i)
124  s->next_frame_index += n_insert;
125  }
126 
127  /* Pending frames may need to be relocated also. */
128  vec_foreach (pf, nm->pending_frames)
129  {
131  && pf->next_frame_index >= i)
132  pf->next_frame_index += n_insert;
133  }
135  if (pf->next_frame_index != ~0 && pf->next_frame_index >= i)
136  pf->next_frame_index += n_insert;
137  }));
138 
139  r->n_next_nodes = vec_len (node->next_nodes);
140  }
141 
142  /* Set frame's node runtime index. */
143  next_node = vlib_get_node (vm, node->next_nodes[next_index]);
144  nf = nm->next_frames + r->next_frame_index + next_index;
145  nf->node_runtime_index = next_node->runtime_index;
146 
148 
150 }
151 
152 /* Add next node to given node in given slot. */
153 uword
155  uword node_index,
156  uword next_node_index,
157  uword slot)
158 {
159  vlib_node_main_t * nm = &vm->node_main;
160  vlib_node_t * node, * next;
161  uword * p;
162 
163  node = vec_elt (nm->nodes, node_index);
164  next = vec_elt (nm->nodes, next_node_index);
165 
166  /* Fill in static next nodes if runtime has yet to be initialized. */
167  if (slot == ~0 && ! (nm->flags & VLIB_NODE_MAIN_RUNTIME_STARTED))
168  {
169  uword i;
170  for (i = 0; i < vec_len (node->next_node_names); i++)
171  {
172  char * a = node->next_node_names[i];
173  if (a)
174  vlib_node_add_named_next_with_slot (vm, node->index, a, i);
175  }
176  }
177 
178  if ((p = hash_get (node->next_slot_by_node, next_node_index)))
179  {
180  /* Next already exists: slot must match. */
181  if (slot != ~0)
182  ASSERT (slot == p[0]);
183  return p[0];
184  }
185 
186  if (slot == ~0)
187  slot = vec_len (node->next_nodes);
188 
189  vec_validate_init_empty (node->next_nodes, slot, ~0);
190  vec_validate (node->n_vectors_by_next_node, slot);
191 
192  node->next_nodes[slot] = next_node_index;
193  hash_set (node->next_slot_by_node, next_node_index, slot);
194 
195  vlib_node_runtime_update (vm, node_index, slot);
196 
197  next->prev_node_bitmap = clib_bitmap_ori (next->prev_node_bitmap,
198  node_index);
199 
200  /* Siblings all get same node structure. */
201  {
202  uword sib_node_index, sib_slot;
203  vlib_node_t * sib_node;
204  clib_bitmap_foreach (sib_node_index, node->sibling_bitmap, ({
205  sib_node = vec_elt (nm->nodes, sib_node_index);
206  if (sib_node != node)
207  {
208  sib_slot = vlib_node_add_next_with_slot (vm, sib_node_index, next_node_index, slot);
209  ASSERT (sib_slot == slot);
210  }
211  }));
212  }
213 
214  return slot;
215 }
216 
217 /* Add named next node to given node in given slot. */
218 uword
220  uword node,
221  char * name,
222  uword slot)
223 {
224  vlib_node_main_t * nm;
225  vlib_node_t * n, * n_next;
226 
227  nm = &vm->node_main;
228  n = vlib_get_node (vm, node);
229 
230  n_next = vlib_get_node_by_name (vm, (u8 *) name);
231  if (! n_next)
232  {
234  return ~0;
235 
236  if (slot == ~0)
237  slot = clib_max (vec_len (n->next_node_names),
238  vec_len (n->next_nodes));
239  vec_validate (n->next_node_names, slot);
240  n->next_node_names[slot] = name;
241  return slot;
242  }
243 
244  return vlib_node_add_next_with_slot (vm, node, n_next->index, slot);
245 }
246 
247 static void node_elog_init (vlib_main_t * vm, uword ni)
248 {
250 
251  memset (&t, 0, sizeof (t));
252 
253  /* 2 event types for this node: one when node function is called.
254  One when it returns. */
256  vm->node_call_elog_event_types[ni] = t;
257 
259  vm->node_return_elog_event_types[ni] = t;
260 
261  node_set_elog_name (vm, ni);
262 }
263 
264 #ifdef CLIB_UNIX
265 #define STACK_ALIGN (clib_mem_get_page_size())
266 #else
267 #define STACK_ALIGN CLIB_CACHE_LINE_BYTES
268 #endif
269 
270 static void register_node (vlib_main_t * vm,
272 {
273  vlib_node_main_t * nm = &vm->node_main;
274  vlib_node_t * n;
275  u32 page_size = clib_mem_get_page_size();
276  int i;
277 
278  if (CLIB_DEBUG > 0)
279  {
280  /* Default (0) type should match INTERNAL. */
281  vlib_node_t zero = {0};
283  }
284 
285  ASSERT (r->function != 0);
286 
287  n = clib_mem_alloc_no_fail (sizeof (n[0]));
288  memset (n, 0, sizeof (n[0]));
289  n->index = vec_len (nm->nodes);
290 
291  vec_add1 (nm->nodes, n);
292 
293  /* Name is always a vector so it can be formatted with %v. */
294  if (clib_mem_is_heap_object (vec_header (r->name, 0)))
295  n->name = vec_dup ((u8 *) r->name);
296  else
297  n->name = format (0, "%s", r->name);
298 
299  if (! nm->node_by_name)
300  nm->node_by_name = hash_create_vec (/* size */ 32,
301  sizeof (n->name[0]),
302  sizeof (uword));
303 
304  /* Node names must be unique. */
305  {
306  vlib_node_t * o = vlib_get_node_by_name (vm, n->name);
307  if (o)
308  clib_error ("more than one node named `%v'", n->name);
309  }
310 
311  hash_set (nm->node_by_name, n->name, n->index);
312 
313  r->index = n->index; /* save index in registration */
314  n->function = r->function;
315 
316  /* Node index of next sibling will be filled in by vlib_node_main_init. */
317  n->sibling_of = r->sibling_of;
318 
319  if (r->type == VLIB_NODE_TYPE_INTERNAL)
320  ASSERT (r->vector_size > 0);
321 
322 #define _(f) n->f = r->f
323 
324  _ (type);
325  _ (flags);
326  _ (state);
327  _ (scalar_size);
328  _ (vector_size);
329  _ (format_buffer);
330  _ (unformat_buffer);
331  _ (format_trace);
332  _ (validate_frame);
333 
334  /* Register error counters. */
335  vlib_register_errors (vm, n->index, r->n_errors, r->error_strings);
336  node_elog_init (vm, n->index);
337 
338  _ (runtime_data_bytes);
339  if (r->runtime_data_bytes > 0)
340  {
341  vec_resize (n->runtime_data, r->runtime_data_bytes);
342  if (r->runtime_data)
343  clib_memcpy (n->runtime_data, r->runtime_data, r->runtime_data_bytes);
344  }
345 
346  vec_resize (n->next_node_names, r->n_next_nodes);
347  for (i = 0; i < r->n_next_nodes; i++)
348  n->next_node_names[i] = r->next_nodes[i];
349 
350  vec_validate_init_empty (n->next_nodes, r->n_next_nodes - 1, ~0);
351  vec_validate (n->n_vectors_by_next_node, r->n_next_nodes - 1);
352 
353  n->owner_node_index = n->owner_next_index = ~0;
354 
355  /* Initialize node runtime. */
356  {
357  vlib_node_runtime_t * rt;
358  u32 i;
359 
360  if (n->type == VLIB_NODE_TYPE_PROCESS)
361  {
362  vlib_process_t * p;
363  uword log2_n_stack_bytes;
364 
365  log2_n_stack_bytes = clib_max (r->process_log2_n_stack_bytes, 15);
366 
367 #ifdef CLIB_UNIX
368  /*
369  * Bump the stack size if running over a kernel with a large page size,
370  * and the stack isn't any too big to begin with. Otherwise, we'll
371  * trip over the stack guard page for sure.
372  */
373  if ((page_size > (4<<10)) && log2_n_stack_bytes < 19)
374  {
375  if ((1<<log2_n_stack_bytes) <= page_size)
376  log2_n_stack_bytes = min_log2 (page_size) + 1;
377  else
378  log2_n_stack_bytes++;
379  }
380 #endif
381 
383  (sizeof (p[0]) + (1 << log2_n_stack_bytes),
385  if (p == 0)
386  clib_panic ("failed to allocate process stack (%d bytes)", 1<<log2_n_stack_bytes);
387 
388  memset (p, 0, sizeof (p[0]));
389  p->log2_n_stack_bytes = log2_n_stack_bytes;
390 
391  /* Process node's runtime index is really index into process
392  pointer vector. */
393  n->runtime_index = vec_len (nm->processes);
394 
395  vec_add1 (nm->processes, p);
396 
397  /* Paint first stack word with magic number so we can at least
398  detect process stack overruns. */
399  p->stack[0] = VLIB_PROCESS_STACK_MAGIC;
400 
401  /* Node runtime is stored inside of process. */
402  rt = &p->node_runtime;
403 
404 #ifdef CLIB_UNIX
405  /*
406  * Disallow writes to the bottom page of the stack, to
407  * catch stack overflows.
408  */
409  if (mprotect (p->stack, page_size, PROT_READ) < 0)
410  clib_unix_warning ("process stack");
411 #endif
412 
413  }
414  else
415  {
416  vec_add2_aligned (nm->nodes_by_type[n->type], rt, 1,
417  /* align */ CLIB_CACHE_LINE_BYTES);
418  n->runtime_index = rt - nm->nodes_by_type[n->type];
419  }
420 
421  if (n->type == VLIB_NODE_TYPE_INPUT)
422  nm->input_node_counts_by_state[n->state] += 1;
423 
424  rt->function = n->function;
425  rt->flags = n->flags;
426  rt->state = n->state;
427  rt->node_index = n->index;
428 
429  rt->n_next_nodes = r->n_next_nodes;
431 
433  for (i = 0; i < rt->n_next_nodes; i++)
435 
436  vec_resize (rt->errors, r->n_errors);
437  for (i = 0; i < vec_len (rt->errors); i++)
438  rt->errors[i] = vlib_error_set (n->index, i);
439 
440  ASSERT (vec_len (n->runtime_data) <= sizeof (rt->runtime_data));
441  if (vec_len (n->runtime_data) > 0)
442  clib_memcpy (rt->runtime_data, n->runtime_data, vec_len (n->runtime_data));
443 
444  vec_free (n->runtime_data);
445  }
446 }
447 
448 /* Register new packet processing node. */
450 {
451  register_node (vm, r);
452  return r->index;
453 }
454 
456 {
458 
460  while (r) {
461  register_node (vm, r);
462  r = r->next_registration;
463  }
464 }
465 
466 clib_error_t *
468 {
469  vlib_node_main_t * nm = &vm->node_main;
470  clib_error_t * error = 0;
471  vlib_node_t * n;
472  uword ni;
473 
475 
476  /* Resolve next names into next indices. */
477  for (ni = 0; ni < vec_len (nm->nodes); ni++)
478  {
479  uword i;
480 
481  n = vec_elt (nm->nodes, ni);
482 
483  for (i = 0; i < vec_len (n->next_node_names); i++)
484  {
485  char * a = n->next_node_names[i];
486 
487  if (! a)
488  continue;
489 
490  if (~0 == vlib_node_add_named_next_with_slot (vm, n->index, a, i))
491  {
492  error = clib_error_create
493  ("node `%v' refers to unknown node `%s'", n->name, a);
494  goto done;
495  }
496  }
497 
499  }
500 
501  /* Set previous node pointers. */
502  for (ni = 0; ni < vec_len (nm->nodes); ni++)
503  {
504  vlib_node_t * n_next;
505  uword i;
506 
507  n = vec_elt (nm->nodes, ni);
508 
509  for (i = 0; i < vec_len (n->next_nodes); i++)
510  {
511  if (n->next_nodes[i] >= vec_len (nm->nodes))
512  continue;
513 
514  n_next = vec_elt (nm->nodes, n->next_nodes[i]);
515  n_next->prev_node_bitmap =
516  clib_bitmap_ori (n_next->prev_node_bitmap, n->index);
517  }
518  }
519 
520  {
521  vlib_next_frame_t * nf;
523  vlib_node_t * next;
524  uword i;
525 
527  {
528  if (r->n_next_nodes == 0)
529  continue;
530 
531  n = vlib_get_node (vm, r->node_index);
533 
534  for (i = 0; i < vec_len (n->next_nodes); i++)
535  {
536  next = vlib_get_node (vm, n->next_nodes[i]);
537 
538  /* Validate node runtime indices are correctly initialized. */
539  ASSERT (nf[i].node_runtime_index == next->runtime_index);
540 
541  nf[i].flags = 0;
544  }
545  }
546  }
547 
548  /* Generate node sibling relationships. */
549  {
550  vlib_node_t * n, * sib;
551  uword si;
552 
553  for (ni = 0; ni < vec_len (nm->nodes); ni++)
554  {
555  n = vec_elt (nm->nodes, ni);
556 
557  if (! n->sibling_of)
558  continue;
559 
560  sib = vlib_get_node_by_name (vm, (u8 *) n->sibling_of);
561  if (! sib)
562  clib_error ("sibling `%s' not found for node `%v'", n->sibling_of, n->name);
563 
564  clib_bitmap_foreach (si, sib->sibling_bitmap, ({
565  vlib_node_t * m = vec_elt (nm->nodes, si);
566 
567  /* Connect all of sibling's siblings to us. */
568  m->sibling_bitmap = clib_bitmap_ori (m->sibling_bitmap, n->index);
569 
570  /* Connect us to all of sibling's siblings. */
571  n->sibling_bitmap = clib_bitmap_ori (n->sibling_bitmap, si);
572  }));
573 
574  /* Connect sibling to us. */
575  sib->sibling_bitmap = clib_bitmap_ori (sib->sibling_bitmap, n->index);
576 
577  /* Connect us to sibling. */
578  n->sibling_bitmap = clib_bitmap_ori (n->sibling_bitmap, sib->index);
579  }
580  }
581 
582  done:
583  return error;
584 }
uword * sibling_bitmap
Definition: node.h:260
u32 * next_nodes
Definition: node.h:254
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
u32 next_frame_index
Definition: node.h:396
#define hash_set(h, key, value)
Definition: hash.h:237
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
vlib_process_t ** processes
Definition: node.h:610
#define hash_unset(h, key)
Definition: hash.h:243
vlib_node_runtime_t node_runtime
Definition: node.h:450
a
Definition: bitmap.h:393
always_inline void * clib_mem_alloc_aligned_at_offset(uword size, uword align, uword align_offset)
Definition: mem.h:70
always_inline vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Definition: node_funcs.h:46
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
uword vlib_node_add_next_with_slot(vlib_main_t *vm, uword node_index, uword next_node_index, uword slot)
Definition: node.c:154
void vlib_register_errors(vlib_main_t *vm, u32 node_index, u32 n_errors, char *error_strings[])
Definition: error.c:145
u32 index
Definition: node.h:203
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:531
#define clib_error(format, args...)
Definition: error.h:62
u16 flags
Definition: node.h:212
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:480
static void node_set_elog_name(vlib_main_t *vm, uword node_index)
Definition: node.c:57
#define VLIB_NODE_MAIN_RUNTIME_STARTED
Definition: node.h:576
clib_error_t * vlib_node_main_init(vlib_main_t *vm)
Definition: node.c:467
struct _vlib_node_registration vlib_node_registration_t
#define VLIB_FRAME_NO_FREE_AFTER_DISPATCH
Definition: node.h:327
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:62
char * format
Definition: elog.h:79
void * runtime_data
Definition: node.h:209
vlib_error_t * errors
Definition: node.h:378
u8 state
Definition: node.h:231
vlib_node_function_t * function
Definition: node.h:184
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
Definition: node.c:449
#define pool_foreach(VAR, POOL, BODY)
Definition: pool.h:328
vlib_node_function_t * function
Definition: node.h:375
u16 log2_n_stack_bytes
Definition: node.h:473
vlib_node_t ** nodes
Definition: node.h:570
int i32
Definition: types.h:81
char ** next_node_names
Definition: node.h:251
char * sibling_of
Definition: node.h:257
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:199
vlib_node_runtime_t * nodes_by_type[VLIB_N_NODE_TYPE]
Definition: node.h:580
always_inline void vlib_next_frame_init(vlib_next_frame_t *nf)
Definition: node.h:351
void vlib_node_rename(vlib_main_t *vm, u32 node_index, char *fmt,...)
Definition: node.c:73
char * name
Definition: main.h:97
#define hash_get(h, key)
Definition: hash.h:231
#define clib_bitmap_foreach(i, ai, body)
Definition: bitmap.h:308
u32 next_frame_index
Definition: node.h:367
#define vec_insert(V, N, M)
Insert N vector elements starting at element M, initialize new elements to zero (no header...
Definition: vec.h:644
#define STACK_ALIGN
Definition: node.c:265
void vlib_register_all_static_nodes(vlib_main_t *vm)
Definition: node.c:455
uword os_get_cpu_number(void)
Definition: unix-misc.c:206
vlib_node_registration_t * node_registrations
Definition: node.h:634
elog_event_type_t * node_return_elog_event_types
Definition: main.h:145
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:332
u64 * n_vectors_by_next_node
Definition: node.h:263
#define clib_error_create(args...)
Definition: error.h:109
u8 * name
Definition: node.h:187
u32 owner_node_index
Definition: node.h:274
void vlib_worker_thread_node_runtime_update(void)
Definition: threads.c:796
#define clib_mem_alloc_no_fail(size)
Definition: mem.h:128
u32 runtime_index
Definition: node.h:206
u8 * va_format(u8 *s, char *fmt, va_list *va)
Definition: format.c:374
vlib_pending_frame_t * pending_frames
Definition: node.h:595
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
#define clib_memcpy(a, b, c)
Definition: string.h:63
#define clib_unix_warning(format, args...)
Definition: error.h:68
uword * node_by_name
Definition: node.h:573
elog_main_t elog_main
Definition: main.h:141
#define ASSERT(truth)
void vlib_worker_thread_barrier_sync(vlib_main_t *vm)
Definition: threads.c:1100
unsigned int u32
Definition: types.h:88
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
#define VLIB_PROCESS_STACK_MAGIC
Definition: node.h:515
vhost_vring_state_t state
Definition: vhost-user.h:77
always_inline vlib_error_t vlib_error_set(u32 node_index, u32 code)
Definition: error.h:55
static void vlib_node_runtime_update(vlib_main_t *vm, u32 node_index, u32 next_index)
Definition: node.c:90
uword * next_slot_by_node
Definition: node.h:268
static void register_node(vlib_main_t *vm, vlib_node_registration_t *r)
Definition: node.c:270
uword * prev_node_bitmap
Definition: node.h:271
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1131
#define clib_max(x, y)
Definition: clib.h:288
u64 uword
Definition: types.h:112
#define vec_elt(v, i)
Get vector value at index i.
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:44
#define hash_create_vec(elts, key_bytes, value_bytes)
Definition: hash.h:601
always_inline uword clib_mem_is_heap_object(void *p)
Definition: mem.h:133
u32 elog_string(elog_main_t *em, char *fmt,...)
Definition: elog.c:496
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 input_node_counts_by_state[VLIB_N_NODE_STATE]
Definition: node.h:622
unsigned char u8
Definition: types.h:56
#define VLIB_PENDING_FRAME_NO_NEXT_FRAME
Definition: node.h:370
vlib_pending_frame_t * suspended_process_frames
Definition: node.h:616
vlib_node_main_t node_main
Definition: main.h:115
u32 owner_next_index
Definition: node.h:274
vlib_next_frame_t * next_frames
Definition: node.h:592
always_inline void * vec_header(void *v, uword header_bytes)
Find a user vector header.
Definition: vec_bootstrap.h:88
elog_event_type_t * node_call_elog_event_types
Definition: main.h:144
vlib_node_type_t type
Definition: node.h:200
u32 name_elog_string
Definition: node.h:190
static void node_elog_init(vlib_main_t *vm, uword ni)
Definition: node.c:247
always_inline vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:61
#define clib_panic(format, args...)
Definition: error.h:72
#define vec_foreach(var, vec)
Vector iterator.
always_inline uword min_log2(uword x)
Definition: clib.h:181
u32 node_runtime_index
Definition: node.h:321
uword vlib_node_add_named_next_with_slot(vlib_main_t *vm, uword node, char *name, uword slot)
Definition: node.c:219
u32 flags
Definition: vhost-user.h:73
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:443
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
uword clib_mem_get_page_size(void)
Definition: mem_mheap.c:111
#define VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH
Definition: node.h:216
uword runtime_data[(128-1 *sizeof(vlib_node_function_t *)-1 *sizeof(vlib_error_t *)-11 *sizeof(u32)-5 *sizeof(u16))/sizeof(uword)]
Definition: node.h:432