1cb9cadadSEd Warnicke/*
2cb9cadadSEd Warnicke * Copyright (c) 2015 Cisco and/or its affiliates.
3cb9cadadSEd Warnicke * Licensed under the Apache License, Version 2.0 (the "License");
4cb9cadadSEd Warnicke * you may not use this file except in compliance with the License.
5cb9cadadSEd Warnicke * You may obtain a copy of the License at:
6cb9cadadSEd Warnicke *
7cb9cadadSEd Warnicke *     http://www.apache.org/licenses/LICENSE-2.0
8cb9cadadSEd Warnicke *
9cb9cadadSEd Warnicke * Unless required by applicable law or agreed to in writing, software
10cb9cadadSEd Warnicke * distributed under the License is distributed on an "AS IS" BASIS,
11cb9cadadSEd Warnicke * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cb9cadadSEd Warnicke * See the License for the specific language governing permissions and
13cb9cadadSEd Warnicke * limitations under the License.
14cb9cadadSEd Warnicke */
15cb9cadadSEd Warnicke/*
16cb9cadadSEd Warnicke * node.h: VLIB processing nodes
17cb9cadadSEd Warnicke *
18cb9cadadSEd Warnicke * Copyright (c) 2008 Eliot Dresselhaus
19cb9cadadSEd Warnicke *
20cb9cadadSEd Warnicke * Permission is hereby granted, free of charge, to any person obtaining
21cb9cadadSEd Warnicke * a copy of this software and associated documentation files (the
22cb9cadadSEd Warnicke * "Software"), to deal in the Software without restriction, including
23cb9cadadSEd Warnicke * without limitation the rights to use, copy, modify, merge, publish,
24cb9cadadSEd Warnicke * distribute, sublicense, and/or sell copies of the Software, and to
25cb9cadadSEd Warnicke * permit persons to whom the Software is furnished to do so, subject to
26cb9cadadSEd Warnicke * the following conditions:
27cb9cadadSEd Warnicke *
28cb9cadadSEd Warnicke * The above copyright notice and this permission notice shall be
29cb9cadadSEd Warnicke * included in all copies or substantial portions of the Software.
30cb9cadadSEd Warnicke *
38cb9cadadSEd Warnicke */
39cb9cadadSEd Warnicke
40cb9cadadSEd Warnicke#ifndef included_vlib_node_h
41cb9cadadSEd Warnicke#define included_vlib_node_h
42cb9cadadSEd Warnicke
431c80e831SDamjan Marion#include <vppinfra/cpu.h>
44cb9cadadSEd Warnicke#include <vppinfra/longjmp.h>
452c2b6407SDamjan Marion#include <vppinfra/lock.h>
46cb9cadadSEd Warnicke#include <vlib/trace.h>		/* for vlib_trace_filter_t */
47cb9cadadSEd Warnicke
48cb9cadadSEd Warnicke/* Forward declaration. */
49cb9cadadSEd Warnickestruct vlib_node_runtime_t;
50cb9cadadSEd Warnickestruct vlib_frame_t;
51cb9cadadSEd Warnicke
52cb9cadadSEd Warnicke/* Internal nodes (including output nodes) move data from node to
53cb9cadadSEd Warnicke   node (or out of the graph for output nodes). */
54cb9cadadSEd Warnicketypedef uword (vlib_node_function_t) (struct vlib_main_t * vm,
55cb9cadadSEd Warnicke				      struct vlib_node_runtime_t * node,
56cb9cadadSEd Warnicke				      struct vlib_frame_t * frame);
57cb9cadadSEd Warnicke
587fff3d20SDave Barachtypedef enum
597fff3d20SDave Barach{
607fff3d20SDave Barach  VLIB_NODE_PROTO_HINT_NONE = 0,
627fff3d20SDave Barach  VLIB_NODE_PROTO_HINT_IP4,
637fff3d20SDave Barach  VLIB_NODE_PROTO_HINT_IP6,
647fff3d20SDave Barach  VLIB_NODE_PROTO_HINT_TCP,
657fff3d20SDave Barach  VLIB_NODE_PROTO_HINT_UDP,
667fff3d20SDave Barach  VLIB_NODE_N_PROTO_HINTS,
677fff3d20SDave Barach} vlib_node_proto_hint_t;
687fff3d20SDave Barach
699b8ffd99SDave Barachtypedef enum
709b8ffd99SDave Barach{
71cb9cadadSEd Warnicke  /* An internal node on the call graph (could be output). */
72cb9cadadSEd Warnicke  VLIB_NODE_TYPE_INTERNAL,
73cb9cadadSEd Warnicke
74cb9cadadSEd Warnicke  /* Nodes which input data into the processing graph.
75cb9cadadSEd Warnicke     Input nodes are called for each iteration of main loop. */
76cb9cadadSEd Warnicke  VLIB_NODE_TYPE_INPUT,
77cb9cadadSEd Warnicke
78cb9cadadSEd Warnicke  /* Nodes to be called before all input nodes.
79cb9cadadSEd Warnicke     Used, for example, to clean out driver TX rings before
80cb9cadadSEd Warnicke     processing input. */
81cb9cadadSEd Warnicke  VLIB_NODE_TYPE_PRE_INPUT,
82cb9cadadSEd Warnicke
83cb9cadadSEd Warnicke  /* "Process" nodes which can be suspended and later resumed. */
84cb9cadadSEd Warnicke  VLIB_NODE_TYPE_PROCESS,
85cb9cadadSEd Warnicke
86cb9cadadSEd Warnicke  VLIB_N_NODE_TYPE,
87cb9cadadSEd Warnicke} vlib_node_type_t;
88cb9cadadSEd Warnicke
89812b32ddSDamjan Mariontypedef struct _vlib_node_fn_registration
90812b32ddSDamjan Marion{
91812b32ddSDamjan Marion  vlib_node_function_t *function;
92812b32ddSDamjan Marion  int priority;
93812b32ddSDamjan Marion  struct _vlib_node_fn_registration *next_registration;
9469abe444SDamjan Marion  char *name;
95812b32ddSDamjan Marion} vlib_node_fn_registration_t;
96812b32ddSDamjan Marion
979b8ffd99SDave Barachtypedef struct _vlib_node_registration
989b8ffd99SDave Barach{
99cb9cadadSEd Warnicke  /* Vector processing function for this node. */
1009b8ffd99SDave Barach  vlib_node_function_t *function;
101cb9cadadSEd Warnicke
102812b32ddSDamjan Marion  /* Node function candidate registration with priority */
103812b32ddSDamjan Marion  vlib_node_fn_registration_t *node_fn_registrations;
104812b32ddSDamjan Marion
105cb9cadadSEd Warnicke  /* Node name. */
1069b8ffd99SDave Barach  char *name;
107cb9cadadSEd Warnicke
108cb9cadadSEd Warnicke  /* Name of sibling (if applicable). */
1099b8ffd99SDave Barach  char *sibling_of;
110cb9cadadSEd Warnicke
111cb9cadadSEd Warnicke  /* Node index filled in by registration. */
112cb9cadadSEd Warnicke  u32 index;
113cb9cadadSEd Warnicke
114cb9cadadSEd Warnicke  /* Type of this node. */
115cb9cadadSEd Warnicke  vlib_node_type_t type;
116cb9cadadSEd Warnicke
117cb9cadadSEd Warnicke  /* Error strings indexed by error code for this node. */
1189b8ffd99SDave Barach  char **error_strings;
119cb9cadadSEd Warnicke
120cb9cadadSEd Warnicke  /* Buffer format/unformat for this node. */
1219b8ffd99SDave Barach  format_function_t *format_buffer;
1229b8ffd99SDave Barach  unformat_function_t *unformat_buffer;
123cb9cadadSEd Warnicke
124cb9cadadSEd Warnicke  /* Trace format/unformat for this node. */
1259b8ffd99SDave Barach  format_function_t *format_trace;
1269b8ffd99SDave Barach  unformat_function_t *unformat_trace;
127cb9cadadSEd Warnicke
128cb9cadadSEd Warnicke  /* Function to validate incoming frames. */
1299b8ffd99SDave Barach  u8 *(*validate_frame) (struct vlib_main_t * vm,
1309b8ffd99SDave Barach			 struct vlib_node_runtime_t *,
1319b8ffd99SDave Barach			 struct vlib_frame_t * f);
132cb9cadadSEd Warnicke
133cb9cadadSEd Warnicke  /* Per-node runtime data. */
1349b8ffd99SDave Barach  void *runtime_data;
135cb9cadadSEd Warnicke
136cb9cadadSEd Warnicke  /* Process stack size. */
137cb9cadadSEd Warnicke  u16 process_log2_n_stack_bytes;
138cb9cadadSEd Warnicke
139cb9cadadSEd Warnicke  /* Number of bytes of per-node run time data. */
140cb9cadadSEd Warnicke  u8 runtime_data_bytes;
141cb9cadadSEd Warnicke
142cb9cadadSEd Warnicke  /* State for input nodes. */
143cb9cadadSEd Warnicke  u8 state;
144cb9cadadSEd Warnicke
145cb9cadadSEd Warnicke  /* Node flags. */
146cb9cadadSEd Warnicke  u16 flags;
147cb9cadadSEd Warnicke
1487fff3d20SDave Barach  /* protocol at b->data[b->current_data] upon entry to the dispatch fn */
1497fff3d20SDave Barach  u8 protocol_hint;
1507fff3d20SDave Barach
151cb9cadadSEd Warnicke  /* Size of scalar and vector arguments in bytes. */
152cb9cadadSEd Warnicke  u16 scalar_size, vector_size;
153cb9cadadSEd Warnicke
154cb9cadadSEd Warnicke  /* Number of error codes used by this node. */
155cb9cadadSEd Warnicke  u16 n_errors;
156cb9cadadSEd Warnicke
157cb9cadadSEd Warnicke  /* Number of next node names that follow. */
158cb9cadadSEd Warnicke  u16 n_next_nodes;
159cb9cadadSEd Warnicke
160cb9cadadSEd Warnicke  /* Constructor link-list, don't ask... */
1619b8ffd99SDave Barach  struct _vlib_node_registration *next_registration;
162cb9cadadSEd Warnicke
163cb9cadadSEd Warnicke  /* Names of next nodes which this node feeds into. */
1649b8ffd99SDave Barach  char *next_nodes[];
165cb9cadadSEd Warnicke
166cb9cadadSEd Warnicke} vlib_node_registration_t;
167cb9cadadSEd Warnicke
1686e36351fSDamjan Marion#ifndef CLIB_MARCH_VARIANT
169cb9cadadSEd Warnicke#define VLIB_REGISTER_NODE(x,...)                                       \
170cb9cadadSEd Warnicke    __VA_ARGS__ vlib_node_registration_t x;                             \
171cb9cadadSEd Warnickestatic void __vlib_add_node_registration_##x (void)                     \
172cb9cadadSEd Warnicke    __attribute__((__constructor__)) ;                                  \
173cb9cadadSEd Warnickestatic void __vlib_add_node_registration_##x (void)                     \
174cb9cadadSEd Warnicke{                                                                       \
175cb9cadadSEd Warnicke    vlib_main_t * vm = vlib_get_main();                                 \
176cb9cadadSEd Warnicke    x.next_registration = vm->node_main.node_registrations;             \
177cb9cadadSEd Warnicke    vm->node_main.node_registrations = &x;                              \
178cb9cadadSEd Warnicke}                                                                       \
17972d2c4f3SDamjan Marionstatic void __vlib_rm_node_registration_##x (void)                      \
18072d2c4f3SDamjan Marion    __attribute__((__destructor__)) ;                                   \
18172d2c4f3SDamjan Marionstatic void __vlib_rm_node_registration_##x (void)                      \
18272d2c4f3SDamjan Marion{                                                                       \
18372d2c4f3SDamjan Marion    vlib_main_t * vm = vlib_get_main();                                 \
18472d2c4f3SDamjan Marion    VLIB_REMOVE_FROM_LINKED_LIST (vm->node_main.node_registrations,     \
18572d2c4f3SDamjan Marion                                  &x, next_registration);               \
18672d2c4f3SDamjan Marion}                                                                       \
1879b8ffd99SDave Barach__VA_ARGS__ vlib_node_registration_t x
1886e36351fSDamjan Marion#else
1896e36351fSDamjan Marion#define VLIB_REGISTER_NODE(x,...)                                       \
190d770cfc9SDamjan MarionSTATIC_ASSERT (sizeof(# __VA_ARGS__) != 7,"node " #x " must not be declared as static"); \
1916e36351fSDamjan Marionstatic __clib_unused vlib_node_registration_t __clib_unused_##x
1926e36351fSDamjan Marion#endif
193cb9cadadSEd Warnicke
19469abe444SDamjan Marion#ifndef CLIB_MARCH_VARIANT
19569abe444SDamjan Marion#define CLIB_MARCH_VARIANT_STR "default"
19669abe444SDamjan Marion#else
19769abe444SDamjan Marion#define _CLIB_MARCH_VARIANT_STR(s) __CLIB_MARCH_VARIANT_STR(s)
19869abe444SDamjan Marion#define __CLIB_MARCH_VARIANT_STR(s) #s
20069abe444SDamjan Marion#endif
20169abe444SDamjan Marion
202812b32ddSDamjan Marion#define VLIB_NODE_FN(node)						\
203812b32ddSDamjan Marionuword CLIB_MARCH_SFX (node##_fn)();					\
204812b32ddSDamjan Marionstatic vlib_node_fn_registration_t					\
205812b32ddSDamjan Marion  CLIB_MARCH_SFX(node##_fn_registration) =				\
206812b32ddSDamjan Marion  { .function = &CLIB_MARCH_SFX (node##_fn), };				\
207812b32ddSDamjan Marion									\
208812b32ddSDamjan Marionstatic void __clib_constructor						\
209812b32ddSDamjan MarionCLIB_MARCH_SFX (node##_multiarch_register) (void)			\
210812b32ddSDamjan Marion{									\
211812b32ddSDamjan Marion  extern vlib_node_registration_t node;					\
212812b32ddSDamjan Marion  vlib_node_fn_registration_t *r;					\
213812b32ddSDamjan Marion  r = & CLIB_MARCH_SFX (node##_fn_registration);			\
214812b32ddSDamjan Marion  r->priority = CLIB_MARCH_FN_PRIORITY();				\
21569abe444SDamjan Marion  r->name = CLIB_MARCH_VARIANT_STR;					\
216812b32ddSDamjan Marion  r->next_registration = node.node_fn_registrations;			\
217812b32ddSDamjan Marion  node.node_fn_registrations = r;					\
218812b32ddSDamjan Marion}									\
219812b32ddSDamjan Marionuword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (node##_fn)
220812b32ddSDamjan Marion
2214830e4f7SRay Kinsellaunformat_function_t unformat_vlib_node_variant;
2224830e4f7SRay Kinsella
223cb9cadadSEd Warnickealways_inline vlib_node_registration_t *
224cb9cadadSEd Warnickevlib_node_next_registered (vlib_node_registration_t * c)
225cb9cadadSEd Warnicke{
2269b8ffd99SDave Barach  c =
2279b8ffd99SDave Barach    clib_elf_section_data_next (c,
2289b8ffd99SDave Barach				c->n_next_nodes * sizeof (c->next_nodes[0]));
229cb9cadadSEd Warnicke  return c;
230cb9cadadSEd Warnicke}
231cb9cadadSEd Warnicke
2329b8ffd99SDave Barachtypedef struct
2339b8ffd99SDave Barach{
234cb9cadadSEd Warnicke  /* Total calls, clock ticks and vector elements processed for this node. */
235cb9cadadSEd Warnicke  u64 calls, vectors, clocks, suspends;
236cb9cadadSEd Warnicke  u64 max_clock;
237cb9cadadSEd Warnicke  u64 max_clock_n;
238ec595ef0SDave Barach  u64 perf_counter0_ticks;
239ec595ef0SDave Barach  u64 perf_counter1_ticks;
2404d1a866aSDave Barach  u64 perf_counter_vectors;
241cb9cadadSEd Warnicke} vlib_node_stats_t;
242cb9cadadSEd Warnicke
243cb9cadadSEd Warnicke#define foreach_vlib_node_state					\
244cb9cadadSEd Warnicke  /* Input node is called each iteration of main loop.		\
245cb9cadadSEd Warnicke     This is the default (zero). */				\
246cb9cadadSEd Warnicke  _ (POLLING)							\
247cb9cadadSEd Warnicke  /* Input node is called when device signals an interrupt. */	\
248cb9cadadSEd Warnicke  _ (INTERRUPT)							\
249cb9cadadSEd Warnicke  /* Input node is never called. */				\
250cb9cadadSEd Warnicke  _ (DISABLED)
251cb9cadadSEd Warnicke
2529b8ffd99SDave Barachtypedef enum
2539b8ffd99SDave Barach{
254cb9cadadSEd Warnicke#define _(f) VLIB_NODE_STATE_##f,
255cb9cadadSEd Warnicke  foreach_vlib_node_state
256cb9cadadSEd Warnicke#undef _
2579b8ffd99SDave Barach    VLIB_N_NODE_STATE,
258cb9cadadSEd Warnicke} vlib_node_state_t;
259cb9cadadSEd Warnicke
2609b8ffd99SDave Barachtypedef struct vlib_node_t
2619b8ffd99SDave Barach{
262cb9cadadSEd Warnicke  /* Vector processing function for this node. */
2639b8ffd99SDave Barach  vlib_node_function_t *function;
264cb9cadadSEd Warnicke
265cb9cadadSEd Warnicke  /* Node name. */
2669b8ffd99SDave Barach  u8 *name;
267cb9cadadSEd Warnicke
268cb9cadadSEd Warnicke  /* Node name index in elog string table. */
269cb9cadadSEd Warnicke  u32 name_elog_string;
270cb9cadadSEd Warnicke
271cb9cadadSEd Warnicke  /* Total statistics for this node. */
272cb9cadadSEd Warnicke  vlib_node_stats_t stats_total;
273cb9cadadSEd Warnicke
274cb9cadadSEd Warnicke  /* Saved values as of last clear (or zero if never cleared).
275cb9cadadSEd Warnicke     Current values are always stats_total - stats_last_clear. */
276cb9cadadSEd Warnicke  vlib_node_stats_t stats_last_clear;
277cb9cadadSEd Warnicke
278cb9cadadSEd Warnicke  /* Type of this node. */
279cb9cadadSEd Warnicke  vlib_node_type_t type;
280cb9cadadSEd Warnicke
281cb9cadadSEd Warnicke  /* Node index. */
282cb9cadadSEd Warnicke  u32 index;
283cb9cadadSEd Warnicke
284cb9cadadSEd Warnicke  /* Index of corresponding node runtime. */
285cb9cadadSEd Warnicke  u32 runtime_index;
286cb9cadadSEd Warnicke
287cb9cadadSEd Warnicke  /* Runtime data for this node. */
2889b8ffd99SDave Barach  void *runtime_data;
289cb9cadadSEd Warnicke
290cb9cadadSEd Warnicke  /* Node flags. */
291cb9cadadSEd Warnicke  u16 flags;
292cb9cadadSEd Warnicke
293cb9cadadSEd Warnicke  /* Processing function keeps frame.  Tells node dispatching code not
294cb9cadadSEd Warnicke     to free frame after dispatch is done.  */
295cb9cadadSEd Warnicke#define VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH (1 << 0)
296cb9cadadSEd Warnicke
297cb9cadadSEd Warnicke  /* Node counts as output/drop/punt node for stats purposes. */
298cb9cadadSEd Warnicke#define VLIB_NODE_FLAG_IS_OUTPUT (1 << 1)
299cb9cadadSEd Warnicke#define VLIB_NODE_FLAG_IS_DROP (1 << 2)
300cb9cadadSEd Warnicke#define VLIB_NODE_FLAG_IS_PUNT (1 << 3)
301cb9cadadSEd Warnicke#define VLIB_NODE_FLAG_IS_HANDOFF (1 << 4)
302cb9cadadSEd Warnicke
303cb9cadadSEd Warnicke  /* Set if current node runtime has traced vectors. */
304cb9cadadSEd Warnicke#define VLIB_NODE_FLAG_TRACE (1 << 5)
305cb9cadadSEd Warnicke
3087ca5aaacSDamjan Marion#define VLIB_NODE_FLAG_TRACE_SUPPORTED (1 << 8)
309cb9cadadSEd Warnicke
310cb9cadadSEd Warnicke  /* State for input nodes. */
311cb9cadadSEd Warnicke  u8 state;
312cb9cadadSEd Warnicke
313cb9cadadSEd Warnicke  /* Number of bytes of run time data. */
314cb9cadadSEd Warnicke  u8 runtime_data_bytes;
315cb9cadadSEd Warnicke
3167fff3d20SDave Barach  /* protocol at b->data[b->current_data] upon entry to the dispatch fn */
3177fff3d20SDave Barach  u8 protocol_hint;
3187fff3d20SDave Barach
319cb9cadadSEd Warnicke  /* Number of error codes used by this node. */
320cb9cadadSEd Warnicke  u16 n_errors;
321cb9cadadSEd Warnicke
322cb9cadadSEd Warnicke  /* Size of scalar and vector arguments in bytes. */
323cb9cadadSEd Warnicke  u16 scalar_size, vector_size;
324cb9cadadSEd Warnicke
325cb9cadadSEd Warnicke  /* Handle/index in error heap for this node. */
326cb9cadadSEd Warnicke  u32 error_heap_handle;
327cb9cadadSEd Warnicke  u32 error_heap_index;
328cb9cadadSEd Warnicke
329cb9cadadSEd Warnicke  /* Error strings indexed by error code for this node. */
3309b8ffd99SDave Barach  char **error_strings;
331cb9cadadSEd Warnicke
332cb9cadadSEd Warnicke  /* Vector of next node names.
333cb9cadadSEd Warnicke     Only used before next_nodes array is initialized. */
3349b8ffd99SDave Barach  char **next_node_names;
335cb9cadadSEd Warnicke
336cb9cadadSEd Warnicke  /* Next node indices for this node. */
3379b8ffd99SDave Barach  u32 *next_nodes;
338cb9cadadSEd Warnicke
339cb9cadadSEd Warnicke  /* Name of node that we are sibling of. */
3409b8ffd99SDave Barach  char *sibling_of;
341cb9cadadSEd Warnicke
342cb9cadadSEd Warnicke  /* Bitmap of all of this node's siblings. */
3439b8ffd99SDave Barach  uword *sibling_bitmap;
344cb9cadadSEd Warnicke
345cb9cadadSEd Warnicke  /* Total number of vectors sent to each next node. */
3469b8ffd99SDave Barach  u64 *n_vectors_by_next_node;
347cb9cadadSEd Warnicke
348cb9cadadSEd Warnicke  /* Hash table mapping next node index into slot in
349cb9cadadSEd Warnicke     next_nodes vector.  Quickly determines whether this node
350cb9cadadSEd Warnicke     is connected to given next node and, if so, with which slot. */
3519b8ffd99SDave Barach  uword *next_slot_by_node;
352cb9cadadSEd Warnicke
353cb9cadadSEd Warnicke  /* Bitmap of node indices which feed this node. */
3549b8ffd99SDave Barach  uword *prev_node_bitmap;
355cb9cadadSEd Warnicke
356cb9cadadSEd Warnicke  /* Node/next-index which own enqueue rights with to this node. */
357cb9cadadSEd Warnicke  u32 owner_node_index, owner_next_index;
358cb9cadadSEd Warnicke
359cb9cadadSEd Warnicke  /* Buffer format/unformat for this node. */
3609b8ffd99SDave Barach  format_function_t *format_buffer;
3619b8ffd99SDave Barach  unformat_function_t *unformat_buffer;
362cb9cadadSEd Warnicke
363cb9cadadSEd Warnicke  /* Trace buffer format/unformat for this node. */
3649b8ffd99SDave Barach  format_function_t *format_trace;
365cb9cadadSEd Warnicke
366cb9cadadSEd Warnicke  /* Function to validate incoming frames. */
3679b8ffd99SDave Barach  u8 *(*validate_frame) (struct vlib_main_t * vm,
3689b8ffd99SDave Barach			 struct vlib_node_runtime_t *,
3699b8ffd99SDave Barach			 struct vlib_frame_t * f);
3706931f59eSDave Barach  /* for pretty-printing, not typically valid */
3719b8ffd99SDave Barach  u8 *state_string;
37269abe444SDamjan Marion
37369abe444SDamjan Marion  /* Node function candidate registration with priority */
37469abe444SDamjan Marion  vlib_node_fn_registration_t *node_fn_registrations;
375cb9cadadSEd Warnicke} vlib_node_t;
376cb9cadadSEd Warnicke
377cb9cadadSEd Warnicke#define VLIB_INVALID_NODE_INDEX ((u32) ~0)
378cb9cadadSEd Warnicke
379cb9cadadSEd Warnicke/* Max number of vector elements to process at once per node. */
380cb9cadadSEd Warnicke#define VLIB_FRAME_SIZE 256
382cb9cadadSEd Warnicke
383cb9cadadSEd Warnicke/* Calling frame (think stack frame) for a node. */
3849b8ffd99SDave Barachtypedef struct vlib_frame_t
3859b8ffd99SDave Barach{
386cb9cadadSEd Warnicke  /* Frame flags. */
387633b6fd6SDamjan Marion  u16 frame_flags;
388633b6fd6SDamjan Marion
389633b6fd6SDamjan Marion  /* User flags. Used for sending hints to the next node. */
390cb9cadadSEd Warnicke  u16 flags;
391cb9cadadSEd Warnicke
392cb9cadadSEd Warnicke  /* Number of scalar bytes in arguments. */
393cb9cadadSEd Warnicke  u8 scalar_size;
394cb9cadadSEd Warnicke
395cb9cadadSEd Warnicke  /* Number of bytes per vector argument. */
396cb9cadadSEd Warnicke  u8 vector_size;
397cb9cadadSEd Warnicke
398cb9cadadSEd Warnicke  /* Number of vector elements currently in frame. */
399cb9cadadSEd Warnicke  u16 n_vectors;
400cb9cadadSEd Warnicke
401cb9cadadSEd Warnicke  /* Scalar and vector arguments to next node. */
402cb9cadadSEd Warnicke  u8 arguments[0];
403cb9cadadSEd Warnicke} vlib_frame_t;
404cb9cadadSEd Warnicke
4059b8ffd99SDave Barachtypedef struct
4069b8ffd99SDave Barach{
40758b2eb1aSAndreas Schultz  /* Frame pointer. */
40858b2eb1aSAndreas Schultz  vlib_frame_t *frame;
409cb9cadadSEd Warnicke
410cb9cadadSEd Warnicke  /* Node runtime for this next. */
411cb9cadadSEd Warnicke  u32 node_runtime_index;
412cb9cadadSEd Warnicke
413cb9cadadSEd Warnicke  /* Next frame flags. */
414cb9cadadSEd Warnicke  u32 flags;
415cb9cadadSEd Warnicke
416cb9cadadSEd Warnicke  /* Reflects node frame-used flag for this next. */
417cb9cadadSEd Warnicke#define VLIB_FRAME_NO_FREE_AFTER_DISPATCH \
419cb9cadadSEd Warnicke
420296988d3SDamjan Marion  /* Don't append this frame */
421296988d3SDamjan Marion#define VLIB_FRAME_NO_APPEND (1 << 14)
422296988d3SDamjan Marion
423cb9cadadSEd Warnicke  /* This next frame owns enqueue to node
424cb9cadadSEd Warnicke     corresponding to node_runtime_index. */
425cb9cadadSEd Warnicke#define VLIB_FRAME_OWNER (1 << 15)
426cb9cadadSEd Warnicke
427cb9cadadSEd Warnicke  /* Set when frame has been allocated for this next. */
429cb9cadadSEd Warnicke
430cb9cadadSEd Warnicke  /* Set when frame has been added to pending vector. */
432cb9cadadSEd Warnicke
433cb9cadadSEd Warnicke  /* Set when frame is to be freed after dispatch. */
435cb9cadadSEd Warnicke
436cb9cadadSEd Warnicke  /* Set when frame has traced packets. */
437cb9cadadSEd Warnicke#define VLIB_FRAME_TRACE VLIB_NODE_FLAG_TRACE
438cb9cadadSEd Warnicke
439cb9cadadSEd Warnicke  /* Number of vectors enqueue to this next since last overflow. */
440cb9cadadSEd Warnicke  u32 vectors_since_last_overflow;
441cb9cadadSEd Warnicke} vlib_next_frame_t;
442cb9cadadSEd Warnicke
443cb9cadadSEd Warnickealways_inline void
444cb9cadadSEd Warnickevlib_next_frame_init (vlib_next_frame_t * nf)
445cb9cadadSEd Warnicke{
446b7b92993SDave Barach  clib_memset (nf, 0, sizeof (nf[0]));
447cb9cadadSEd Warnicke  nf->node_runtime_index = ~0;
448cb9cadadSEd Warnicke}
449cb9cadadSEd Warnicke
450cb9cadadSEd Warnicke/* A frame pending dispatch by main loop. */
4519b8ffd99SDave Barachtypedef struct
4529b8ffd99SDave Barach{
453cb9cadadSEd Warnicke  /* Node and runtime for this frame. */
454cb9cadadSEd Warnicke  u32 node_runtime_index;
455cb9cadadSEd Warnicke
456cb9cadadSEd Warnicke  /* Frame index (in the heap). */
45758b2eb1aSAndreas Schultz  vlib_frame_t *frame;
458cb9cadadSEd Warnicke
459cb9cadadSEd Warnicke  /* Start of next frames for this node. */
460cb9cadadSEd Warnicke  u32 next_frame_index;
461cb9cadadSEd Warnicke
462cb9cadadSEd Warnicke  /* Special value for next_frame_index when there is no next frame. */
463cb9cadadSEd Warnicke#define VLIB_PENDING_FRAME_NO_NEXT_FRAME ((u32) ~0)
464cb9cadadSEd Warnicke} vlib_pending_frame_t;
465cb9cadadSEd Warnicke
4669b8ffd99SDave Barachtypedef struct vlib_node_runtime_t
4679b8ffd99SDave Barach{
468e9f929b5SDamjan Marion  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);	/**< cacheline mark */
469cb9cadadSEd Warnicke
470e9f929b5SDamjan Marion  vlib_node_function_t *function;	/**< Node function to call. */
471cb9cadadSEd Warnicke
472e9f929b5SDamjan Marion  vlib_error_t *errors;			/**< Vector of errors for this node. */
473cb9cadadSEd Warnicke
47436c1308bSDamjan Marion#if __SIZEOF_POINTER__ == 4
47536c1308bSDamjan Marion  u8 pad[8];
47636c1308bSDamjan Marion#endif
47736c1308bSDamjan Marion
478e9f929b5SDamjan Marion  u32 clocks_since_last_overflow;	/**< Number of clock cycles. */
479cb9cadadSEd Warnicke
480e9f929b5SDamjan Marion  u32 max_clock;			/**< Maximum clock cycle for an
481e9f929b5SDamjan Marion					  invocation. */
482cb9cadadSEd Warnicke
483e9f929b5SDamjan Marion  u32 max_clock_n;			/**< Number of vectors in the recorded
484e9f929b5SDamjan Marion					  max_clock. */
485cb9cadadSEd Warnicke
486e9f929b5SDamjan Marion  u32 calls_since_last_overflow;	/**< Number of calls. */
487cb9cadadSEd Warnicke
488e9f929b5SDamjan Marion  u32 vectors_since_last_overflow;	/**< Number of vector elements
489e9f929b5SDamjan Marion					  processed by this node. */
490cb9cadadSEd Warnicke
491ec595ef0SDave Barach  u32 perf_counter0_ticks_since_last_overflow; /**< Perf counter 0 ticks */
492ec595ef0SDave Barach  u32 perf_counter1_ticks_since_last_overflow; /**< Perf counter 1 ticks */
4934d1a866aSDave Barach  u32 perf_counter_vectors_since_last_overflow;	/**< Perf counter vectors */
4944d1a866aSDave Barach
495e9f929b5SDamjan Marion  u32 next_frame_index;			/**< Start of next frames for this
496e9f929b5SDamjan Marion					  node. */
497e9f929b5SDamjan Marion
498e9f929b5SDamjan Marion  u32 node_index;			/**< Node index. */
499cb9cadadSEd Warnicke
500e9f929b5SDamjan Marion  u32 input_main_loops_per_call;	/**< For input nodes: decremented
501e9f929b5SDamjan Marion					  on each main loop interation until
502e9f929b5SDamjan Marion					  it reaches zero and function is
503e9f929b5SDamjan Marion					  called.  Allows some input nodes to
504e9f929b5SDamjan Marion					  be called more than others. */
505cb9cadadSEd Warnicke
506e9f929b5SDamjan Marion  u32 main_loop_count_last_dispatch;	/**< Saved main loop counter of last
507e9f929b5SDamjan Marion					  dispatch of this node. */
508cb9cadadSEd Warnicke
509cb9cadadSEd Warnicke  u32 main_loop_vector_stats[2];
510cb9cadadSEd Warnicke
511e9f929b5SDamjan Marion  u16 flags;				/**< Copy of main node flags. */
512cb9cadadSEd Warnicke
513e9f929b5SDamjan Marion  u16 state;				/**< Input node state. */
514cb9cadadSEd Warnicke
515cb9cadadSEd Warnicke  u16 n_next_nodes;
516cb9cadadSEd Warnicke
517e9f929b5SDamjan Marion  u16 cached_next_index;		/**< Next frame index that vector
518e9f929b5SDamjan Marion					  arguments were last enqueued to
519e9f929b5SDamjan Marion					  last time this node ran. Set to
520e9f929b5SDamjan Marion					  zero before first run of this
521e9f929b5SDamjan Marion					  node. */
522e9f929b5SDamjan Marion
523586afd76SDamjan Marion  u16 thread_index;			/**< thread this node runs on */
524e9f929b5SDamjan Marion
525e9f929b5SDamjan Marion  u8 runtime_data[0];			/**< Function dependent
526e9f929b5SDamjan Marion					  node-runtime data. This data is
527e9f929b5SDamjan Marion					  thread local, and it is not
528e9f929b5SDamjan Marion					  cloned from main thread. It needs
529e9f929b5SDamjan Marion					  to be initialized for each thread
530e9f929b5SDamjan Marion					  before it is used unless
531e9f929b5SDamjan Marion					  runtime_data template exists in
532e9f929b5SDamjan Marion					  vlib_node_t. */
5339b8ffd99SDave Barach}
5349b8ffd99SDave Barachvlib_node_runtime_t;
535cb9cadadSEd Warnicke
536e9f929b5SDamjan Marion#define VLIB_NODE_RUNTIME_DATA_SIZE	(sizeof (vlib_node_runtime_t) - STRUCT_OFFSET_OF (vlib_node_runtime_t, runtime_data))
537e9f929b5SDamjan Marion
5389b8ffd99SDave Barachtypedef struct
5399b8ffd99SDave Barach{
540cb9cadadSEd Warnicke  /* Number of allocated frames for this scalar/vector size. */
541cb9cadadSEd Warnicke  u32 n_alloc_frames;
542cb9cadadSEd Warnicke
54358b2eb1aSAndreas Schultz  /* Vector of free frames for this scalar/vector size. */
54458b2eb1aSAndreas Schultz  vlib_frame_t **free_frames;
545cb9cadadSEd Warnicke} vlib_frame_size_t;
546cb9cadadSEd Warnicke
5479b8ffd99SDave Barachtypedef struct
5489b8ffd99SDave Barach{
549cb9cadadSEd Warnicke  /* Users opaque value for event type. */
550cb9cadadSEd Warnicke  uword opaque;
551cb9cadadSEd Warnicke} vlib_process_event_type_t;
552cb9cadadSEd Warnicke
5539b8ffd99SDave Barachtypedef struct
5549b8ffd99SDave Barach{
555ef587582SDamjan Marion  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
556cb9cadadSEd Warnicke  /* Node runtime for this process. */
557cb9cadadSEd Warnicke  vlib_node_runtime_t node_runtime;
558cb9cadadSEd Warnicke
559cb9cadadSEd Warnicke  /* Where to longjmp when process is done. */
560cb9cadadSEd Warnicke  clib_longjmp_t return_longjmp;
561cb9cadadSEd Warnicke
562cb9cadadSEd Warnicke#define VLIB_PROCESS_RETURN_LONGJMP_RETURN ((uword) ~0 - 0)
563cb9cadadSEd Warnicke#define VLIB_PROCESS_RETURN_LONGJMP_SUSPEND ((uword) ~0 - 1)
564cb9cadadSEd Warnicke
565cb9cadadSEd Warnicke  /* Where to longjmp to resume node after suspend. */
566cb9cadadSEd Warnicke  clib_longjmp_t resume_longjmp;
567cb9cadadSEd Warnicke#define VLIB_PROCESS_RESUME_LONGJMP_SUSPEND 0
568cb9cadadSEd Warnicke#define VLIB_PROCESS_RESUME_LONGJMP_RESUME  1
569cb9cadadSEd Warnicke
570cb9cadadSEd Warnicke  u16 flags;
571cb9cadadSEd Warnicke#define VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK (1 << 0)
572cb9cadadSEd Warnicke#define VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT (1 << 1)
573cb9cadadSEd Warnicke  /* Set to indicate that this process has been added to resume vector. */
574cb9cadadSEd Warnicke#define VLIB_PROCESS_RESUME_PENDING (1 << 2)
575cb9cadadSEd Warnicke
576cb9cadadSEd Warnicke  /* Process function is currently running. */
577cb9cadadSEd Warnicke#define VLIB_PROCESS_IS_RUNNING (1 << 3)
578cb9cadadSEd Warnicke
579cb9cadadSEd Warnicke  /* Size of process stack. */
580cb9cadadSEd Warnicke  u16 log2_n_stack_bytes;
581cb9cadadSEd Warnicke
582cb9cadadSEd Warnicke  u32 suspended_process_frame_index;
583cb9cadadSEd Warnicke
584cb9cadadSEd Warnicke  /* Number of times this process was suspended. */
585cb9cadadSEd Warnicke  u32 n_suspends;
586cb9cadadSEd Warnicke
587cb9cadadSEd Warnicke  /* Vectors of pending event data indexed by event type index. */
5889b8ffd99SDave Barach  void **pending_event_data_by_type_index;
589cb9cadadSEd Warnicke
590cb9cadadSEd Warnicke  /* Bitmap of event type-indices with non-empty vectors. */
5919b8ffd99SDave Barach  uword *non_empty_event_type_bitmap;
592cb9cadadSEd Warnicke
593cb9cadadSEd Warnicke  /* Bitmap of event type-indices which are one time events. */
5949b8ffd99SDave Barach  uword *one_time_event_type_bitmap;
595cb9cadadSEd Warnicke
596cb9cadadSEd Warnicke  /* Type is opaque pointer -- typically a pointer to an event handler
597cb9cadadSEd Warnicke     function.  Hash table to map opaque to a type index. */
5989b8ffd99SDave Barach  uword *event_type_index_by_type_opaque;
599cb9cadadSEd Warnicke
600cb9cadadSEd Warnicke  /* Pool of currently valid event types. */
6019b8ffd99SDave Barach  vlib_process_event_type_t *event_type_pool;
602cb9cadadSEd Warnicke
6035c20a013SDave Barach  /*
6045c20a013SDave Barach   * When suspending saves clock time (10us ticks) when process
6055c20a013SDave Barach   * is to be resumed.
6065c20a013SDave Barach   */
6075c20a013SDave Barach  u64 resume_clock_interval;
6085c20a013SDave Barach
6095c20a013SDave Barach  /* Handle from timer code, to cancel an unexpired timer */
6105c20a013SDave Barach  u32 stop_timer_handle;
611cb9cadadSEd Warnicke
612716d9593SAndrew Yourtchenko  /* Default output function and its argument for any CLI outputs
613716d9593SAndrew Yourtchenko     within the process. */
614716d9593SAndrew Yourtchenko  vlib_cli_output_function_t *output_function;
615716d9593SAndrew Yourtchenko  uword output_function_arg;
616716d9593SAndrew Yourtchenko
617ef587582SDamjan Marion  /* Process stack */
618cb9cadadSEd Warnicke#define VLIB_PROCESS_STACK_MAGIC (0xdead7ead)
619ef587582SDamjan Marion  u32 *stack;
620ef587582SDamjan Marion} vlib_process_t;
621716d9593SAndrew Yourtchenko
6229b8ffd99SDave Barachtypedef struct
6239b8ffd99SDave Barach{
6249b8ffd99SDave Barach  u32 node_index;
625cb9cadadSEd Warnicke
6269b8ffd99SDave Barach  u32 one_time_event;
627cb9cadadSEd Warnicke} vlib_one_time_waiting_process_t;
628cb9cadadSEd Warnicke
6299b8ffd99SDave Barachtypedef struct
6309b8ffd99SDave Barach{
631cb9cadadSEd Warnicke  u16 n_data_elts;
632cb9cadadSEd Warnicke
633cb9cadadSEd Warnicke  u16 n_data_elt_bytes;
634cb9cadadSEd Warnicke
635cb9cadadSEd Warnicke  /* n_data_elts * n_data_elt_bytes */
636cb9cadadSEd Warnicke  u32 n_data_bytes;
637cb9cadadSEd Warnicke
638cb9cadadSEd Warnicke  /* Process node & event type to be used to signal event. */
639cb9cadadSEd Warnicke  u32 process_node_index;
640cb9cadadSEd Warnicke
641cb9cadadSEd Warnicke  u32 event_type_index;
642cb9cadadSEd Warnicke
6439b8ffd99SDave Barach  union
6449b8ffd99SDave Barach  {
645cb9cadadSEd Warnicke    u8 inline_event_data[64 - 3 * sizeof (u32) - 2 * sizeof (u16)];
646cb9cadadSEd Warnicke
647cb9cadadSEd Warnicke    /* Vector of event data used only when data does not fit inline. */
6489b8ffd99SDave Barach    u8 *event_data_as_vector;
649cb9cadadSEd Warnicke  };
6509b8ffd99SDave Barach}
6519b8ffd99SDave Barachvlib_signal_timed_event_data_t;
652cb9cadadSEd Warnicke
653cb9cadadSEd Warnickealways_inline uword
654cb9cadadSEd Warnickevlib_timing_wheel_data_is_timed_event (u32 d)
6559b8ffd99SDave Barach{
6569b8ffd99SDave Barach  return d & 1;
6579b8ffd99SDave Barach}
658cb9cadadSEd Warnicke
659cb9cadadSEd Warnickealways_inline u32
660cb9cadadSEd Warnickevlib_timing_wheel_data_set_suspended_process (u32 i)
6619b8ffd99SDave Barach{
6629b8ffd99SDave Barach  return 0 + 2 * i;
6639b8ffd99SDave Barach}
664cb9cadadSEd Warnicke
665cb9cadadSEd Warnickealways_inline u32
666cb9cadadSEd Warnickevlib_timing_wheel_data_set_timed_event (u32 i)
6679b8ffd99SDave Barach{
6689b8ffd99SDave Barach  return 1 + 2 * i;
6699b8ffd99SDave Barach}
670cb9cadadSEd Warnicke
671cb9cadadSEd Warnickealways_inline uword
672cb9cadadSEd Warnickevlib_timing_wheel_data_get_index (u32 d)
6739b8ffd99SDave Barach{
6749b8ffd99SDave Barach  return d / 2;
6759b8ffd99SDave Barach}
676cb9cadadSEd Warnicke
6779b8ffd99SDave Barachtypedef struct
6789b8ffd99SDave Barach{
679cb9cadadSEd Warnicke  /* Public nodes. */
6809b8ffd99SDave Barach  vlib_node_t **nodes;
681cb9cadadSEd Warnicke
682cb9cadadSEd Warnicke  /* Node index hashed by node name. */
6839b8ffd99SDave Barach  uword *node_by_name;
684cb9cadadSEd Warnicke
685cb9cadadSEd Warnicke  u32 flags;
686cb9cadadSEd Warnicke#define VLIB_NODE_MAIN_RUNTIME_STARTED (1 << 0)
687cb9cadadSEd Warnicke
688cb9cadadSEd Warnicke  /* Nodes segregated by type for cache locality.
689cb9cadadSEd Warnicke     Does not apply to nodes of type VLIB_NODE_TYPE_INTERNAL. */
6909b8ffd99SDave Barach  vlib_node_runtime_t *nodes_by_type[VLIB_N_NODE_TYPE];
691cb9cadadSEd Warnicke
692cb9cadadSEd Warnicke  /* Node runtime indices for input nodes with pending interrupts. */
6939b8ffd99SDave Barach  u32 *pending_interrupt_node_runtime_indices;
6942c2b6407SDamjan Marion  clib_spinlock_t pending_interrupt_lock;
695cb9cadadSEd Warnicke
696cb9cadadSEd Warnicke  /* Input nodes are switched from/to interrupt to/from polling mode
697cb9cadadSEd Warnicke     when average vector length goes above/below polling/interrupt
698cb9cadadSEd Warnicke     thresholds. */
699cb9cadadSEd Warnicke  u32 polling_threshold_vector_length;
700cb9cadadSEd Warnicke  u32 interrupt_threshold_vector_length;
701cb9cadadSEd Warnicke
702cb9cadadSEd Warnicke  /* Vector of next frames. */
7039b8ffd99SDave Barach  vlib_next_frame_t *next_frames;
704cb9cadadSEd Warnicke
705cb9cadadSEd Warnicke  /* Vector of internal node's frames waiting to be called. */
7069b8ffd99SDave Barach  vlib_pending_frame_t *pending_frames;
707cb9cadadSEd Warnicke
708cb9cadadSEd Warnicke  /* Timing wheel for scheduling time-based node dispatch. */
7095c20a013SDave Barach  void *timing_wheel;
710cb9cadadSEd Warnicke
7119b8ffd99SDave Barach  vlib_signal_timed_event_data_t *signal_timed_event_data_pool;
712cb9cadadSEd Warnicke
713cb9cadadSEd Warnicke  /* Opaque data vector added via timing_wheel_advance. */
7149b8ffd99SDave Barach  u32 *data_from_advancing_timing_wheel;
715cb9cadadSEd Warnicke
716cb9cadadSEd Warnicke  /* CPU time of next process to be ready on timing wheel. */
7175c20a013SDave Barach  f64 time_next_process_ready;
718cb9cadadSEd Warnicke
719cb9cadadSEd Warnicke  /* Vector of process nodes.
720cb9cadadSEd Warnicke     One for each node of type VLIB_NODE_TYPE_PROCESS. */
7219b8ffd99SDave Barach  vlib_process_t **processes;
722cb9cadadSEd Warnicke
723cb9cadadSEd Warnicke  /* Current running process or ~0 if no process running. */
724cb9cadadSEd Warnicke  u32 current_process_index;
725cb9cadadSEd Warnicke
726cb9cadadSEd Warnicke  /* Pool of pending process frames. */
7279b8ffd99SDave Barach  vlib_pending_frame_t *suspended_process_frames;
728cb9cadadSEd Warnicke
729cb9cadadSEd Warnicke  /* Vector of event data vectors pending recycle. */
7309b8ffd99SDave Barach  void **recycled_event_data_vectors;
731cb9cadadSEd Warnicke
732cb9cadadSEd Warnicke  /* Current counts of nodes in each state. */
733cb9cadadSEd Warnicke  u32 input_node_counts_by_state[VLIB_N_NODE_STATE];
734cb9cadadSEd Warnicke
735cb9cadadSEd Warnicke  /* Hash of (scalar_size,vector_size) to frame_sizes index. */
7369b8ffd99SDave Barach  uword *frame_size_hash;
737cb9cadadSEd Warnicke
738cb9cadadSEd Warnicke  /* Per-size frame allocation information. */
7399b8ffd99SDave Barach  vlib_frame_size_t *frame_sizes;
740cb9cadadSEd Warnicke
741cb9cadadSEd Warnicke  /* Time of last node runtime stats clear. */
742cb9cadadSEd Warnicke  f64 time_last_runtime_stats_clear;
743cb9cadadSEd Warnicke
744cb9cadadSEd Warnicke  /* Node registrations added by constructors */
7459b8ffd99SDave Barach  vlib_node_registration_t *node_registrations;
746687c9021SDave Barach
747687c9021SDave Barach  /* Node index from error code */
748687c9021SDave Barach  u32 *node_by_error;
749cb9cadadSEd Warnicke} vlib_node_main_t;
750cb9cadadSEd Warnicke
751687c9021SDave Barachtypedef u16 vlib_error_t;
752687c9021SDave Barach
753687c9021SDave Barachalways_inline u32
754687c9021SDave Barachvlib_error_get_node (vlib_node_main_t * nm, vlib_error_t e)
755687c9021SDave Barach{
756687c9021SDave Barach  return nm->node_by_error[e];
757687c9021SDave Barach}
758687c9021SDave Barach
759687c9021SDave Barachalways_inline u32
760687c9021SDave Barachvlib_error_get_code (vlib_node_main_t * nm, vlib_error_t e)
761687c9021SDave Barach{
762687c9021SDave Barach  u32 node_index = nm->node_by_error[e];
763687c9021SDave Barach  vlib_node_t *n = nm->nodes[node_index];
764687c9021SDave Barach  u32 error_code = e - n->error_heap_index;
765687c9021SDave Barach  return error_code;
766687c9021SDave Barach}
7670f8ecf0eSDamjan Marion
7688875248fSdongjuan#define FRAME_QUEUE_MAX_NELTS 64
7699b8ffd99SDave Barachtypedef struct
7709b8ffd99SDave Barach{
7719b8ffd99SDave Barach  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
7720f8ecf0eSDamjan Marion  u64 head;
7730f8ecf0eSDamjan Marion  u64 head_hint;
7740f8ecf0eSDamjan Marion  u64 tail;
7750f8ecf0eSDamjan Marion  u32 n_in_use;
7760f8ecf0eSDamjan Marion  u32 nelts;
7770f8ecf0eSDamjan Marion  u32 written;
7780f8ecf0eSDamjan Marion  u32 threshold;
7790f8ecf0eSDamjan Marion  i32 n_vectors[FRAME_QUEUE_MAX_NELTS];
7800f8ecf0eSDamjan Marion} frame_queue_trace_t;
7810f8ecf0eSDamjan Marion
7829b8ffd99SDave Barachtypedef struct
7839b8ffd99SDave Barach{
7840f8ecf0eSDamjan Marion  u64 count[FRAME_QUEUE_MAX_NELTS];
7850f8ecf0eSDamjan Marion} frame_queue_nelt_counter_t;
7860f8ecf0eSDamjan Marion
787cb9cadadSEd Warnicke#endif /* included_vlib_node_h */
7889b8ffd99SDave Barach
7899b8ffd99SDave Barach/*
7909b8ffd99SDave Barach * fd.io coding-style-patch-verification: ON
7919b8ffd99SDave Barach *
7929b8ffd99SDave Barach * Local Variables:
7939b8ffd99SDave Barach * eval: (c-set-style "gnu")
7949b8ffd99SDave Barach * End:
7959b8ffd99SDave Barach */