struct vlib_node_runtime_t * node,
struct vlib_frame_t * frame);
+typedef enum
+{
+ VLIB_NODE_PROTO_HINT_NONE = 0,
+ VLIB_NODE_PROTO_HINT_ETHERNET,
+ VLIB_NODE_PROTO_HINT_IP4,
+ VLIB_NODE_PROTO_HINT_IP6,
+ VLIB_NODE_PROTO_HINT_TCP,
+ VLIB_NODE_PROTO_HINT_UDP,
+ VLIB_NODE_N_PROTO_HINTS,
+} vlib_node_proto_hint_t;
+
typedef enum
{
/* An internal node on the call graph (could be output). */
VLIB_N_NODE_TYPE,
} vlib_node_type_t;
+typedef struct _vlib_node_fn_registration
+{
+ vlib_node_function_t *function;
+ int priority;
+ struct _vlib_node_fn_registration *next_registration;
+ char *name;
+} vlib_node_fn_registration_t;
+
typedef struct _vlib_node_registration
{
/* Vector processing function for this node. */
vlib_node_function_t *function;
+ /* Node function candidate registration with priority */
+ vlib_node_fn_registration_t *node_fn_registrations;
+
/* Node name. */
char *name;
/* Node flags. */
u16 flags;
+ /* protocol at b->data[b->current_data] upon entry to the dispatch fn */
+ u8 protocol_hint;
+
/* Size of scalar and vector arguments in bytes. */
u16 scalar_size, vector_size;
} vlib_node_registration_t;
+#ifndef CLIB_MARCH_VARIANT
#define VLIB_REGISTER_NODE(x,...) \
__VA_ARGS__ vlib_node_registration_t x; \
static void __vlib_add_node_registration_##x (void) \
&x, next_registration); \
} \
__VA_ARGS__ vlib_node_registration_t x
+#else
+#define VLIB_REGISTER_NODE(x,...) \
+static __clib_unused vlib_node_registration_t __clib_unused_##x
+#endif
+
+#ifndef CLIB_MARCH_VARIANT
+#define CLIB_MARCH_VARIANT_STR "default"
+#else
+#define _CLIB_MARCH_VARIANT_STR(s) __CLIB_MARCH_VARIANT_STR(s)
+#define __CLIB_MARCH_VARIANT_STR(s) #s
+#define CLIB_MARCH_VARIANT_STR _CLIB_MARCH_VARIANT_STR(CLIB_MARCH_VARIANT)
+#endif
+
+#define VLIB_NODE_FN(node) \
+uword CLIB_MARCH_SFX (node##_fn)(); \
+static vlib_node_fn_registration_t \
+ CLIB_MARCH_SFX(node##_fn_registration) = \
+ { .function = &CLIB_MARCH_SFX (node##_fn), }; \
+ \
+static void __clib_constructor \
+CLIB_MARCH_SFX (node##_multiarch_register) (void) \
+{ \
+ extern vlib_node_registration_t node; \
+ vlib_node_fn_registration_t *r; \
+ r = & CLIB_MARCH_SFX (node##_fn_registration); \
+ r->priority = CLIB_MARCH_FN_PRIORITY(); \
+ r->name = CLIB_MARCH_VARIANT_STR; \
+ r->next_registration = node.node_fn_registrations; \
+ node.node_fn_registrations = r; \
+} \
+uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (node##_fn)
#if CLIB_DEBUG > 0
#define VLIB_NODE_FUNCTION_CLONE_TEMPLATE(arch, fn)
u64 calls, vectors, clocks, suspends;
u64 max_clock;
u64 max_clock_n;
+ u64 perf_counter_ticks;
+ u64 perf_counter_vectors;
} vlib_node_stats_t;
#define foreach_vlib_node_state \
/* Number of bytes of run time data. */
u8 runtime_data_bytes;
+ /* protocol at b->data[b->current_data] upon entry to the dispatch fn */
+ u8 protocol_hint;
+
/* Number of error codes used by this node. */
u16 n_errors;
struct vlib_frame_t * f);
/* for pretty-printing, not typically valid */
u8 *state_string;
+
+ /* Node function candidate registration with priority */
+ vlib_node_fn_registration_t *node_fn_registrations;
} vlib_node_t;
#define VLIB_INVALID_NODE_INDEX ((u32) ~0)
typedef struct vlib_frame_t
{
/* Frame flags. */
+ u16 frame_flags;
+
+ /* User flags. Used for sending hints to the next node. */
u16 flags;
/* Number of scalar bytes in arguments. */
always_inline void
vlib_next_frame_init (vlib_next_frame_t * nf)
{
- memset (nf, 0, sizeof (nf[0]));
+ clib_memset (nf, 0, sizeof (nf[0]));
nf->frame_index = ~0;
nf->node_runtime_index = ~0;
}
u32 vectors_since_last_overflow; /**< Number of vector elements
processed by this node. */
+ u32 perf_counter_ticks_since_last_overflow; /**< Perf counter ticks */
+ u32 perf_counter_vectors_since_last_overflow; /**< Perf counter vectors */
+
u32 next_frame_index; /**< Start of next frames for this
node. */