blob: bb6d8f818a8425565ff67650fb4c86c92731c795 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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.h: 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#ifndef included_vlib_node_h
41#define included_vlib_node_h
42
Damjan Marion1c80e832016-05-11 23:07:18 +020043#include <vppinfra/cpu.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070044#include <vppinfra/longjmp.h>
Damjan Marion2c2b6402017-03-28 14:16:15 +020045#include <vppinfra/lock.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070046#include <vlib/trace.h> /* for vlib_trace_filter_t */
47
48/* Forward declaration. */
49struct vlib_node_runtime_t;
50struct vlib_frame_t;
51
52/* Internal nodes (including output nodes) move data from node to
53 node (or out of the graph for output nodes). */
54typedef uword (vlib_node_function_t) (struct vlib_main_t * vm,
55 struct vlib_node_runtime_t * node,
56 struct vlib_frame_t * frame);
57
Dave Barach9b8ffd92016-07-08 08:13:45 -040058typedef enum
59{
Dave Barach7fff3d22018-11-27 16:52:59 -050060 VLIB_NODE_PROTO_HINT_NONE = 0,
61 VLIB_NODE_PROTO_HINT_ETHERNET,
62 VLIB_NODE_PROTO_HINT_IP4,
63 VLIB_NODE_PROTO_HINT_IP6,
64 VLIB_NODE_PROTO_HINT_TCP,
65 VLIB_NODE_PROTO_HINT_UDP,
66 VLIB_NODE_N_PROTO_HINTS,
67} vlib_node_proto_hint_t;
68
69typedef enum
70{
Ed Warnickecb9cada2015-12-08 15:45:58 -070071 /* An internal node on the call graph (could be output). */
72 VLIB_NODE_TYPE_INTERNAL,
73
74 /* Nodes which input data into the processing graph.
75 Input nodes are called for each iteration of main loop. */
76 VLIB_NODE_TYPE_INPUT,
77
78 /* Nodes to be called before all input nodes.
79 Used, for example, to clean out driver TX rings before
80 processing input. */
81 VLIB_NODE_TYPE_PRE_INPUT,
82
83 /* "Process" nodes which can be suspended and later resumed. */
84 VLIB_NODE_TYPE_PROCESS,
85
86 VLIB_N_NODE_TYPE,
87} vlib_node_type_t;
88
Damjan Marion812b32d2018-05-28 21:26:47 +020089typedef struct _vlib_node_fn_registration
90{
91 vlib_node_function_t *function;
Damjan Mariona31698b2021-03-10 14:35:28 +010092 clib_march_variant_type_t march_variant;
Damjan Marion812b32d2018-05-28 21:26:47 +020093 struct _vlib_node_fn_registration *next_registration;
94} vlib_node_fn_registration_t;
95
Dave Barach9b8ffd92016-07-08 08:13:45 -040096typedef struct _vlib_node_registration
97{
Ed Warnickecb9cada2015-12-08 15:45:58 -070098 /* Vector processing function for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -040099 vlib_node_function_t *function;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700100
Damjan Marion812b32d2018-05-28 21:26:47 +0200101 /* Node function candidate registration with priority */
102 vlib_node_fn_registration_t *node_fn_registrations;
103
Ed Warnickecb9cada2015-12-08 15:45:58 -0700104 /* Node name. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400105 char *name;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700106
107 /* Name of sibling (if applicable). */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400108 char *sibling_of;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700109
110 /* Node index filled in by registration. */
111 u32 index;
112
113 /* Type of this node. */
114 vlib_node_type_t type;
115
116 /* Error strings indexed by error code for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400117 char **error_strings;
Ole Troan2c4acdd2021-05-06 14:09:50 +0200118 vlib_error_desc_t *error_counters;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119
120 /* Buffer format/unformat for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400121 format_function_t *format_buffer;
122 unformat_function_t *unformat_buffer;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700123
124 /* Trace format/unformat for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400125 format_function_t *format_trace;
126 unformat_function_t *unformat_trace;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700127
128 /* Function to validate incoming frames. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400129 u8 *(*validate_frame) (struct vlib_main_t * vm,
130 struct vlib_node_runtime_t *,
131 struct vlib_frame_t * f);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700132
133 /* Per-node runtime data. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400134 void *runtime_data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135
136 /* Process stack size. */
137 u16 process_log2_n_stack_bytes;
138
139 /* Number of bytes of per-node run time data. */
140 u8 runtime_data_bytes;
141
142 /* State for input nodes. */
143 u8 state;
144
145 /* Node flags. */
146 u16 flags;
147
Dave Barach7fff3d22018-11-27 16:52:59 -0500148 /* protocol at b->data[b->current_data] upon entry to the dispatch fn */
149 u8 protocol_hint;
150
Ed Warnickecb9cada2015-12-08 15:45:58 -0700151 /* Size of scalar and vector arguments in bytes. */
Damjan Marion198ddad2022-01-18 16:24:23 +0100152 u8 vector_size, aux_size;
153 u16 scalar_size;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700154
155 /* Number of error codes used by this node. */
156 u16 n_errors;
157
158 /* Number of next node names that follow. */
159 u16 n_next_nodes;
160
161 /* Constructor link-list, don't ask... */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400162 struct _vlib_node_registration *next_registration;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700163
164 /* Names of next nodes which this node feeds into. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400165 char *next_nodes[];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700166
167} vlib_node_registration_t;
168
Damjan Marion6e363512018-08-10 22:39:11 +0200169#ifndef CLIB_MARCH_VARIANT
Damjan Marionfd8deb42021-03-06 12:26:28 +0100170#define VLIB_REGISTER_NODE(x, ...) \
171 __VA_ARGS__ vlib_node_registration_t x; \
172 static void __vlib_add_node_registration_##x (void) \
173 __attribute__ ((__constructor__)); \
174 static void __vlib_add_node_registration_##x (void) \
175 { \
176 vlib_global_main_t *vgm = vlib_get_global_main (); \
177 x.next_registration = vgm->node_registrations; \
178 vgm->node_registrations = &x; \
179 } \
180 static void __vlib_rm_node_registration_##x (void) \
181 __attribute__ ((__destructor__)); \
182 static void __vlib_rm_node_registration_##x (void) \
183 { \
184 vlib_global_main_t *vgm = vlib_get_global_main (); \
185 VLIB_REMOVE_FROM_LINKED_LIST (vgm->node_registrations, &x, \
186 next_registration); \
187 } \
188 __VA_ARGS__ vlib_node_registration_t x
Damjan Marion6e363512018-08-10 22:39:11 +0200189#else
190#define VLIB_REGISTER_NODE(x,...) \
Damjan Mariond770cfc2019-09-02 19:00:33 +0200191STATIC_ASSERT (sizeof(# __VA_ARGS__) != 7,"node " #x " must not be declared as static"); \
Damjan Marion6e363512018-08-10 22:39:11 +0200192static __clib_unused vlib_node_registration_t __clib_unused_##x
193#endif
Ed Warnickecb9cada2015-12-08 15:45:58 -0700194
Damjan Marion69abe442018-08-27 22:43:23 +0200195#ifndef CLIB_MARCH_VARIANT
196#define CLIB_MARCH_VARIANT_STR "default"
197#else
198#define _CLIB_MARCH_VARIANT_STR(s) __CLIB_MARCH_VARIANT_STR(s)
199#define __CLIB_MARCH_VARIANT_STR(s) #s
200#define CLIB_MARCH_VARIANT_STR _CLIB_MARCH_VARIANT_STR(CLIB_MARCH_VARIANT)
201#endif
202
Damjan Mariona31698b2021-03-10 14:35:28 +0100203#define VLIB_NODE_FN(node) \
Damjan Mariondd298e82022-10-12 16:02:18 +0200204 uword CLIB_MARCH_SFX (node##_fn) (vlib_main_t *, vlib_node_runtime_t *, \
205 vlib_frame_t *); \
Damjan Mariona31698b2021-03-10 14:35:28 +0100206 static vlib_node_fn_registration_t CLIB_MARCH_SFX ( \
207 node##_fn_registration) = { \
208 .function = &CLIB_MARCH_SFX (node##_fn), \
209 }; \
210 \
211 static void __clib_constructor CLIB_MARCH_SFX (node##_multiarch_register) ( \
212 void) \
213 { \
214 extern vlib_node_registration_t node; \
215 vlib_node_fn_registration_t *r; \
216 r = &CLIB_MARCH_SFX (node##_fn_registration); \
217 r->march_variant = CLIB_MARCH_SFX (CLIB_MARCH_VARIANT_TYPE); \
218 r->next_registration = node.node_fn_registrations; \
219 node.node_fn_registrations = r; \
220 } \
Damjan Marion1bb67ab2021-04-30 11:11:08 +0200221 uword CLIB_MARCH_SFX (node##_fn)
Damjan Marion812b32d2018-05-28 21:26:47 +0200222
Ray Kinsella4830e4f2020-03-10 14:35:32 +0000223unformat_function_t unformat_vlib_node_variant;
224
Dave Barach9b8ffd92016-07-08 08:13:45 -0400225typedef struct
226{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700227 /* Total calls, clock ticks and vector elements processed for this node. */
228 u64 calls, vectors, clocks, suspends;
229 u64 max_clock;
230 u64 max_clock_n;
231} vlib_node_stats_t;
232
233#define foreach_vlib_node_state \
234 /* Input node is called each iteration of main loop. \
235 This is the default (zero). */ \
236 _ (POLLING) \
237 /* Input node is called when device signals an interrupt. */ \
238 _ (INTERRUPT) \
239 /* Input node is never called. */ \
240 _ (DISABLED)
241
Dave Barach9b8ffd92016-07-08 08:13:45 -0400242typedef enum
243{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700244#define _(f) VLIB_NODE_STATE_##f,
245 foreach_vlib_node_state
246#undef _
Dave Barach9b8ffd92016-07-08 08:13:45 -0400247 VLIB_N_NODE_STATE,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700248} vlib_node_state_t;
249
Dave Barach9b8ffd92016-07-08 08:13:45 -0400250typedef struct vlib_node_t
251{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252 /* Vector processing function for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400253 vlib_node_function_t *function;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700254
255 /* Node name. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400256 u8 *name;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700257
258 /* Node name index in elog string table. */
259 u32 name_elog_string;
260
261 /* Total statistics for this node. */
262 vlib_node_stats_t stats_total;
263
264 /* Saved values as of last clear (or zero if never cleared).
265 Current values are always stats_total - stats_last_clear. */
266 vlib_node_stats_t stats_last_clear;
267
268 /* Type of this node. */
269 vlib_node_type_t type;
270
271 /* Node index. */
272 u32 index;
273
274 /* Index of corresponding node runtime. */
275 u32 runtime_index;
276
277 /* Runtime data for this node. */
Damjan Marion299571a2022-03-19 00:07:52 +0100278 u8 *runtime_data;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700279
280 /* Node flags. */
281 u16 flags;
282
283 /* Processing function keeps frame. Tells node dispatching code not
284 to free frame after dispatch is done. */
285#define VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH (1 << 0)
286
287 /* Node counts as output/drop/punt node for stats purposes. */
288#define VLIB_NODE_FLAG_IS_OUTPUT (1 << 1)
289#define VLIB_NODE_FLAG_IS_DROP (1 << 2)
290#define VLIB_NODE_FLAG_IS_PUNT (1 << 3)
291#define VLIB_NODE_FLAG_IS_HANDOFF (1 << 4)
292
293 /* Set if current node runtime has traced vectors. */
294#define VLIB_NODE_FLAG_TRACE (1 << 5)
295
296#define VLIB_NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE (1 << 6)
297#define VLIB_NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE (1 << 7)
Damjan Marion7ca5aaa2019-09-24 18:10:49 +0200298#define VLIB_NODE_FLAG_TRACE_SUPPORTED (1 << 8)
Florin Coras982e44f2021-03-19 13:12:41 -0700299#define VLIB_NODE_FLAG_ADAPTIVE_MODE (1 << 9)
Mohammed Hawari3b5a0132024-08-29 14:01:06 +0200300#define VLIB_NODE_FLAG_ALLOW_LAZY_NEXT_NODES (1 << 10)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700301
302 /* State for input nodes. */
303 u8 state;
304
305 /* Number of bytes of run time data. */
306 u8 runtime_data_bytes;
307
Dave Barach7fff3d22018-11-27 16:52:59 -0500308 /* protocol at b->data[b->current_data] upon entry to the dispatch fn */
309 u8 protocol_hint;
310
Ed Warnickecb9cada2015-12-08 15:45:58 -0700311 /* Number of error codes used by this node. */
312 u16 n_errors;
313
314 /* Size of scalar and vector arguments in bytes. */
Damjan Marionb32bd702021-12-23 17:05:02 +0100315 u16 frame_size, scalar_offset, vector_offset, magic_offset, aux_offset;
316 u16 frame_size_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700317
318 /* Handle/index in error heap for this node. */
319 u32 error_heap_handle;
320 u32 error_heap_index;
321
Ole Troan148c7b72020-10-07 18:05:37 +0200322 /* Counter structures indexed by counter code for this node. */
Ole Troan2c4acdd2021-05-06 14:09:50 +0200323 vlib_error_desc_t *error_counters;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700324
325 /* Vector of next node names.
326 Only used before next_nodes array is initialized. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400327 char **next_node_names;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700328
329 /* Next node indices for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400330 u32 *next_nodes;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700331
332 /* Name of node that we are sibling of. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400333 char *sibling_of;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700334
335 /* Bitmap of all of this node's siblings. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400336 uword *sibling_bitmap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700337
338 /* Total number of vectors sent to each next node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400339 u64 *n_vectors_by_next_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700340
341 /* Hash table mapping next node index into slot in
342 next_nodes vector. Quickly determines whether this node
343 is connected to given next node and, if so, with which slot. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400344 uword *next_slot_by_node;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700345
346 /* Bitmap of node indices which feed this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400347 uword *prev_node_bitmap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700348
349 /* Node/next-index which own enqueue rights with to this node. */
350 u32 owner_node_index, owner_next_index;
351
352 /* Buffer format/unformat for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400353 format_function_t *format_buffer;
354 unformat_function_t *unformat_buffer;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700355
356 /* Trace buffer format/unformat for this node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400357 format_function_t *format_trace;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700358
359 /* Function to validate incoming frames. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400360 u8 *(*validate_frame) (struct vlib_main_t * vm,
361 struct vlib_node_runtime_t *,
362 struct vlib_frame_t * f);
Dave Barach6931f592016-05-13 12:55:01 -0400363 /* for pretty-printing, not typically valid */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400364 u8 *state_string;
Damjan Marion69abe442018-08-27 22:43:23 +0200365
366 /* Node function candidate registration with priority */
367 vlib_node_fn_registration_t *node_fn_registrations;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700368} vlib_node_t;
369
370#define VLIB_INVALID_NODE_INDEX ((u32) ~0)
371
372/* Max number of vector elements to process at once per node. */
373#define VLIB_FRAME_SIZE 256
Damjan Marionb32bd702021-12-23 17:05:02 +0100374/* Number of extra elements allocated at the end of vecttor. */
375#define VLIB_FRAME_SIZE_EXTRA 4
376/* Frame data alignment */
377#define VLIB_FRAME_DATA_ALIGN 16
Ed Warnickecb9cada2015-12-08 15:45:58 -0700378
379/* Calling frame (think stack frame) for a node. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400380typedef struct vlib_frame_t
381{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700382 /* Frame flags. */
Damjan Marion633b6fd2018-09-14 14:38:53 +0200383 u16 frame_flags;
384
385 /* User flags. Used for sending hints to the next node. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700386 u16 flags;
387
Damjan Marionb32bd702021-12-23 17:05:02 +0100388 /* Scalar, vector and aux offsets in this frame. */
389 u16 scalar_offset, vector_offset, aux_offset;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700390
391 /* Number of vector elements currently in frame. */
392 u16 n_vectors;
393
Dmitry Valter9f5b3692022-09-05 15:30:18 +0000394 /* Index of frame size corresponding to allocated node. */
395 u16 frame_size_index;
396
Ed Warnickecb9cada2015-12-08 15:45:58 -0700397 /* Scalar and vector arguments to next node. */
398 u8 arguments[0];
399} vlib_frame_t;
400
Dave Barach9b8ffd92016-07-08 08:13:45 -0400401typedef struct
402{
Andreas Schultz58b2eb12019-07-15 15:40:56 +0200403 /* Frame pointer. */
404 vlib_frame_t *frame;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700405
406 /* Node runtime for this next. */
407 u32 node_runtime_index;
408
409 /* Next frame flags. */
410 u32 flags;
411
412 /* Reflects node frame-used flag for this next. */
413#define VLIB_FRAME_NO_FREE_AFTER_DISPATCH \
414 VLIB_NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH
415
Damjan Marion296988d2019-02-21 20:24:54 +0100416 /* Don't append this frame */
417#define VLIB_FRAME_NO_APPEND (1 << 14)
418
Ed Warnickecb9cada2015-12-08 15:45:58 -0700419 /* This next frame owns enqueue to node
420 corresponding to node_runtime_index. */
421#define VLIB_FRAME_OWNER (1 << 15)
422
423 /* Set when frame has been allocated for this next. */
424#define VLIB_FRAME_IS_ALLOCATED VLIB_NODE_FLAG_IS_OUTPUT
425
426 /* Set when frame has been added to pending vector. */
427#define VLIB_FRAME_PENDING VLIB_NODE_FLAG_IS_DROP
428
429 /* Set when frame is to be freed after dispatch. */
430#define VLIB_FRAME_FREE_AFTER_DISPATCH VLIB_NODE_FLAG_IS_PUNT
431
432 /* Set when frame has traced packets. */
433#define VLIB_FRAME_TRACE VLIB_NODE_FLAG_TRACE
434
435 /* Number of vectors enqueue to this next since last overflow. */
436 u32 vectors_since_last_overflow;
437} vlib_next_frame_t;
438
439always_inline void
440vlib_next_frame_init (vlib_next_frame_t * nf)
441{
Dave Barachb7b92992018-10-17 10:38:51 -0400442 clib_memset (nf, 0, sizeof (nf[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700443 nf->node_runtime_index = ~0;
444}
445
446/* A frame pending dispatch by main loop. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400447typedef struct
448{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700449 /* Frame index (in the heap). */
Andreas Schultz58b2eb12019-07-15 15:40:56 +0200450 vlib_frame_t *frame;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700451
Damjan Marionf70cf232021-04-15 19:54:44 +0200452 /* Node and runtime for this frame. */
453 u32 node_runtime_index;
454
Ed Warnickecb9cada2015-12-08 15:45:58 -0700455 /* Start of next frames for this node. */
456 u32 next_frame_index;
457
458 /* Special value for next_frame_index when there is no next frame. */
459#define VLIB_PENDING_FRAME_NO_NEXT_FRAME ((u32) ~0)
460} vlib_pending_frame_t;
461
Dave Barach9b8ffd92016-07-08 08:13:45 -0400462typedef struct vlib_node_runtime_t
463{
Damjan Marione9f929b2017-03-16 11:32:09 +0100464 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); /**< cacheline mark */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700465
Damjan Marione9f929b2017-03-16 11:32:09 +0100466 vlib_node_function_t *function; /**< Node function to call. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700467
Damjan Marione9f929b2017-03-16 11:32:09 +0100468 vlib_error_t *errors; /**< Vector of errors for this node. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700469
Damjan Marione9f929b2017-03-16 11:32:09 +0100470 u32 clocks_since_last_overflow; /**< Number of clock cycles. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700471
Damjan Marione9f929b2017-03-16 11:32:09 +0100472 u32 max_clock; /**< Maximum clock cycle for an
473 invocation. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700474
Damjan Marione9f929b2017-03-16 11:32:09 +0100475 u32 max_clock_n; /**< Number of vectors in the recorded
476 max_clock. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700477
Damjan Marione9f929b2017-03-16 11:32:09 +0100478 u32 calls_since_last_overflow; /**< Number of calls. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700479
Damjan Marione9f929b2017-03-16 11:32:09 +0100480 u32 vectors_since_last_overflow; /**< Number of vector elements
481 processed by this node. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700482
Damjan Marione9f929b2017-03-16 11:32:09 +0100483 u32 next_frame_index; /**< Start of next frames for this
484 node. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700485
Damjan Marione9f929b2017-03-16 11:32:09 +0100486 u32 node_index; /**< Node index. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700487
Damjan Marione9f929b2017-03-16 11:32:09 +0100488 u32 input_main_loops_per_call; /**< For input nodes: decremented
489 on each main loop interation until
490 it reaches zero and function is
491 called. Allows some input nodes to
492 be called more than others. */
493
494 u32 main_loop_count_last_dispatch; /**< Saved main loop counter of last
495 dispatch of this node. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700496
497 u32 main_loop_vector_stats[2];
498
Damjan Marione9f929b2017-03-16 11:32:09 +0100499 u16 flags; /**< Copy of main node flags. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700500
Damjan Marione9f929b2017-03-16 11:32:09 +0100501 u16 state; /**< Input node state. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700502
503 u16 n_next_nodes;
504
Damjan Marione9f929b2017-03-16 11:32:09 +0100505 u16 cached_next_index; /**< Next frame index that vector
506 arguments were last enqueued to
507 last time this node ran. Set to
508 zero before first run of this
509 node. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700510
Dmitry Valter5760fdf2022-03-29 15:13:26 +0000511 CLIB_ALIGN_MARK (runtime_data_pad, 8);
512
Damjan Marione9f929b2017-03-16 11:32:09 +0100513 u8 runtime_data[0]; /**< Function dependent
514 node-runtime data. This data is
515 thread local, and it is not
516 cloned from main thread. It needs
517 to be initialized for each thread
518 before it is used unless
519 runtime_data template exists in
520 vlib_node_t. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400521}
522vlib_node_runtime_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700523
Damjan Marione9f929b2017-03-16 11:32:09 +0100524#define VLIB_NODE_RUNTIME_DATA_SIZE (sizeof (vlib_node_runtime_t) - STRUCT_OFFSET_OF (vlib_node_runtime_t, runtime_data))
525
Dave Barach9b8ffd92016-07-08 08:13:45 -0400526typedef struct
527{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700528 /* Number of allocated frames for this scalar/vector size. */
529 u32 n_alloc_frames;
530
Damjan Marionb32bd702021-12-23 17:05:02 +0100531 /* Frame size */
532 u16 frame_size;
533
Andreas Schultz58b2eb12019-07-15 15:40:56 +0200534 /* Vector of free frames for this scalar/vector size. */
535 vlib_frame_t **free_frames;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700536} vlib_frame_size_t;
537
Damjan Marionb32bd702021-12-23 17:05:02 +0100538STATIC_ASSERT_SIZEOF (vlib_frame_size_t, 16);
539
Dave Barach9b8ffd92016-07-08 08:13:45 -0400540typedef struct
541{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700542 /* Users opaque value for event type. */
543 uword opaque;
544} vlib_process_event_type_t;
545
Damjan Mariondfa77dc2024-09-10 17:07:49 +0200546#define foreach_vlib_process_state \
547 _ (NOT_STARTED, "not started") \
548 _ (RUNNING, "running") \
549 _ (SUSPENDED, "suspended") \
550 _ (WAIT_FOR_EVENT, "event wait") \
551 _ (WAIT_FOR_CLOCK, "clock wait") \
552 _ (WAIT_FOR_EVENT_OR_CLOCK, "any wait") \
553 _ (WAIT_FOR_ONE_TIME_EVENT, "one time event wait") \
554 _ (YIELD, "yield")
555
556typedef enum
557{
558#define _(n, s) VLIB_PROCESS_STATE_##n,
559 foreach_vlib_process_state VLIB_PROCESS_N_STATES
560#undef _
561} __clib_packed vlib_process_state_t;
562
563STATIC_ASSERT (VLIB_PROCESS_STATE_NOT_STARTED == 0, "");
564
565typedef enum
566{
567 VLIB_PROCESS_RESTORE_REASON_UNKNOWN = 0,
568 VLIB_PROCESS_RESTORE_REASON_EVENT,
569 VLIB_PROCESS_RESTORE_REASON_CLOCK,
570 VLIB_PROCESS_RESTORE_REASON_TIMED_EVENT,
571 VLIB_PROCESS_RESTORE_REASON_YIELD,
572 VLIB_PROCRSS_N_RESTORE_REASON
573} __clib_packed vlib_process_restore_reason_t;
574
575typedef struct
576{
577 vlib_process_restore_reason_t reason;
578 union
579 {
580 u32 runtime_index;
581 u32 timed_event_data_pool_index;
582 };
583} __clib_packed vlib_process_restore_t;
584
Dave Barach9b8ffd92016-07-08 08:13:45 -0400585typedef struct
586{
Damjan Marionef587582020-05-20 22:01:44 +0200587 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700588 /* Node runtime for this process. */
589 vlib_node_runtime_t node_runtime;
590
591 /* Where to longjmp when process is done. */
592 clib_longjmp_t return_longjmp;
593
594#define VLIB_PROCESS_RETURN_LONGJMP_RETURN ((uword) ~0 - 0)
595#define VLIB_PROCESS_RETURN_LONGJMP_SUSPEND ((uword) ~0 - 1)
596
597 /* Where to longjmp to resume node after suspend. */
598 clib_longjmp_t resume_longjmp;
599#define VLIB_PROCESS_RESUME_LONGJMP_SUSPEND 0
600#define VLIB_PROCESS_RESUME_LONGJMP_RESUME 1
601
Damjan Mariondfa77dc2024-09-10 17:07:49 +0200602 /* Process state. */
603 vlib_process_state_t state;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700604
Damjan Mariondfa77dc2024-09-10 17:07:49 +0200605 /* Process is added to resume list due to pending event */
606 u8 event_resume_pending : 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700607
608 /* Size of process stack. */
609 u16 log2_n_stack_bytes;
610
611 u32 suspended_process_frame_index;
612
613 /* Number of times this process was suspended. */
614 u32 n_suspends;
615
616 /* Vectors of pending event data indexed by event type index. */
Damjan Mariond24b86e2022-03-23 16:59:23 +0100617 u8 **pending_event_data_by_type_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700618
619 /* Bitmap of event type-indices with non-empty vectors. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400620 uword *non_empty_event_type_bitmap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700621
622 /* Bitmap of event type-indices which are one time events. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400623 uword *one_time_event_type_bitmap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700624
625 /* Type is opaque pointer -- typically a pointer to an event handler
626 function. Hash table to map opaque to a type index. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400627 uword *event_type_index_by_type_opaque;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700628
629 /* Pool of currently valid event types. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400630 vlib_process_event_type_t *event_type_pool;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700631
Dave Barach5c20a012017-06-13 08:48:31 -0400632 /*
633 * When suspending saves clock time (10us ticks) when process
634 * is to be resumed.
635 */
636 u64 resume_clock_interval;
637
638 /* Handle from timer code, to cancel an unexpired timer */
639 u32 stop_timer_handle;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700640
Andrew Yourtchenko716d9592016-05-10 10:51:34 +0000641 /* Default output function and its argument for any CLI outputs
642 within the process. */
643 vlib_cli_output_function_t *output_function;
644 uword output_function_arg;
645
Damjan Marionef587582020-05-20 22:01:44 +0200646 /* Process stack */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700647#define VLIB_PROCESS_STACK_MAGIC (0xdead7ead)
Damjan Marionef587582020-05-20 22:01:44 +0200648 u32 *stack;
649} vlib_process_t;
Andrew Yourtchenko716d9592016-05-10 10:51:34 +0000650
Dave Barach9b8ffd92016-07-08 08:13:45 -0400651typedef struct
652{
653 u32 node_index;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700654
Dave Barach9b8ffd92016-07-08 08:13:45 -0400655 u32 one_time_event;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700656} vlib_one_time_waiting_process_t;
657
Dave Barach9b8ffd92016-07-08 08:13:45 -0400658typedef struct
659{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700660 u16 n_data_elts;
661
662 u16 n_data_elt_bytes;
663
664 /* n_data_elts * n_data_elt_bytes */
665 u32 n_data_bytes;
666
667 /* Process node & event type to be used to signal event. */
668 u32 process_node_index;
669
670 u32 event_type_index;
671
Dave Barach9b8ffd92016-07-08 08:13:45 -0400672 union
673 {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700674 u8 inline_event_data[64 - 3 * sizeof (u32) - 2 * sizeof (u16)];
675
676 /* Vector of event data used only when data does not fit inline. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400677 u8 *event_data_as_vector;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700678 };
Dave Barach9b8ffd92016-07-08 08:13:45 -0400679}
680vlib_signal_timed_event_data_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700681
682always_inline uword
683vlib_timing_wheel_data_is_timed_event (u32 d)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400684{
685 return d & 1;
686}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700687
688always_inline u32
689vlib_timing_wheel_data_set_suspended_process (u32 i)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400690{
691 return 0 + 2 * i;
692}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700693
694always_inline u32
695vlib_timing_wheel_data_set_timed_event (u32 i)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400696{
697 return 1 + 2 * i;
698}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700699
700always_inline uword
701vlib_timing_wheel_data_get_index (u32 d)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400702{
703 return d / 2;
704}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700705
Dave Barach9b8ffd92016-07-08 08:13:45 -0400706typedef struct
707{
Damjan Mariona31698b2021-03-10 14:35:28 +0100708 clib_march_variant_type_t index;
709 int priority;
710 char *suffix;
711 char *desc;
712} vlib_node_fn_variant_t;
713
714typedef struct
715{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700716 /* Public nodes. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400717 vlib_node_t **nodes;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700718
719 /* Node index hashed by node name. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400720 uword *node_by_name;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700721
722 u32 flags;
723#define VLIB_NODE_MAIN_RUNTIME_STARTED (1 << 0)
724
725 /* Nodes segregated by type for cache locality.
726 Does not apply to nodes of type VLIB_NODE_TYPE_INTERNAL. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400727 vlib_node_runtime_t *nodes_by_type[VLIB_N_NODE_TYPE];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700728
729 /* Node runtime indices for input nodes with pending interrupts. */
Damjan Marioncc8249c2023-07-23 14:24:22 +0200730 void *input_node_interrupts;
731 void *pre_input_node_interrupts;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700732
733 /* Input nodes are switched from/to interrupt to/from polling mode
734 when average vector length goes above/below polling/interrupt
735 thresholds. */
736 u32 polling_threshold_vector_length;
737 u32 interrupt_threshold_vector_length;
738
739 /* Vector of next frames. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400740 vlib_next_frame_t *next_frames;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700741
742 /* Vector of internal node's frames waiting to be called. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400743 vlib_pending_frame_t *pending_frames;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700744
745 /* Timing wheel for scheduling time-based node dispatch. */
Dave Barach5c20a012017-06-13 08:48:31 -0400746 void *timing_wheel;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700747
Dave Barach9b8ffd92016-07-08 08:13:45 -0400748 vlib_signal_timed_event_data_t *signal_timed_event_data_pool;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700749
Damjan Mariondfa77dc2024-09-10 17:07:49 +0200750 /* Vector of process nodes waiting for restore */
751 vlib_process_restore_t *process_restore_current;
752
753 /* Vector of process nodes waiting for restore in next greaph scheduler run
754 */
755 vlib_process_restore_t *process_restore_next;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700756
757 /* CPU time of next process to be ready on timing wheel. */
Dave Barach5c20a012017-06-13 08:48:31 -0400758 f64 time_next_process_ready;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700759
760 /* Vector of process nodes.
761 One for each node of type VLIB_NODE_TYPE_PROCESS. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400762 vlib_process_t **processes;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700763
764 /* Current running process or ~0 if no process running. */
765 u32 current_process_index;
766
767 /* Pool of pending process frames. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400768 vlib_pending_frame_t *suspended_process_frames;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700769
770 /* Vector of event data vectors pending recycle. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400771 void **recycled_event_data_vectors;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700772
773 /* Current counts of nodes in each state. */
774 u32 input_node_counts_by_state[VLIB_N_NODE_STATE];
775
Ed Warnickecb9cada2015-12-08 15:45:58 -0700776 /* Per-size frame allocation information. */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400777 vlib_frame_size_t *frame_sizes;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700778
779 /* Time of last node runtime stats clear. */
780 f64 time_last_runtime_stats_clear;
781
Dave Barach687c9022019-07-23 10:22:31 -0400782 /* Node index from error code */
783 u32 *node_by_error;
Damjan Mariona31698b2021-03-10 14:35:28 +0100784
785 /* Node Function Variants */
786 vlib_node_fn_variant_t *variants;
787
788 /* Node Function Default Variant Index */
789 u32 node_fn_default_march_variant;
790
791 /* Node Function march Variant by Suffix Hash */
792 uword *node_fn_march_variant_by_suffix;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700793} vlib_node_main_t;
794
Dave Barach687c9022019-07-23 10:22:31 -0400795typedef u16 vlib_error_t;
796
797always_inline u32
798vlib_error_get_node (vlib_node_main_t * nm, vlib_error_t e)
799{
800 return nm->node_by_error[e];
801}
802
803always_inline u32
804vlib_error_get_code (vlib_node_main_t * nm, vlib_error_t e)
805{
806 u32 node_index = nm->node_by_error[e];
807 vlib_node_t *n = nm->nodes[node_index];
808 u32 error_code = e - n->error_heap_index;
809 return error_code;
810}
Damjan Marion0f8ecf02016-06-27 08:30:30 +0200811
dongjuan88752482019-06-04 10:59:02 +0800812#define FRAME_QUEUE_MAX_NELTS 64
Dave Barach9b8ffd92016-07-08 08:13:45 -0400813typedef struct
814{
815 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion0f8ecf02016-06-27 08:30:30 +0200816 u64 head;
Damjan Marion0f8ecf02016-06-27 08:30:30 +0200817 u64 tail;
818 u32 n_in_use;
819 u32 nelts;
820 u32 written;
821 u32 threshold;
822 i32 n_vectors[FRAME_QUEUE_MAX_NELTS];
823} frame_queue_trace_t;
824
Dave Barach9b8ffd92016-07-08 08:13:45 -0400825typedef struct
826{
Damjan Marion0f8ecf02016-06-27 08:30:30 +0200827 u64 count[FRAME_QUEUE_MAX_NELTS];
828} frame_queue_nelt_counter_t;
829
Ed Warnickecb9cada2015-12-08 15:45:58 -0700830#endif /* included_vlib_node_h */
Dave Barach9b8ffd92016-07-08 08:13:45 -0400831
832/*
833 * fd.io coding-style-patch-verification: ON
834 *
835 * Local Variables:
836 * eval: (c-set-style "gnu")
837 * End:
838 */