typedef struct vlib_main_t
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); //指定结构体按照64字节对齐,提高缓存命中
/*指令级别的时间. */
clib_time_t clib_time;
/*主线程时间偏移*/
f64 time_offset;
f64 time_last_barrier_release;
/*最后一个节点调度的时间戳. */
u64 cpu_time_last_node_dispatch;
/* 开启主线程时的时间戳. */
u64 cpu_time_main_loop_start;
/* 主循环递增次数. */
u32 main_loop_count;
/*主循环中vectors和nodes计数. */
u32 main_loop_vectors_processed;
u32 main_loop_nodes_processed;
/* 内部节点vectors,calls*/
u64 internal_node_vectors;
u64 internal_node_calls;
u64 internal_node_vectors_last_clear;
u64 internal_node_calls_last_clear;
/* 即时向量速率 */
u32 internal_node_last_vectors_per_main_loop;
/* 主循环 hw/sw 性能计数器*/
void (**vlib_node_runtime_perf_counter_cbs) (struct vlib_main_t *,
u64 *, u64 *,
vlib_node_runtime_t *,
vlib_frame_t *, int);
void (**vlib_node_runtime_perf_counter_cb_tmp) (struct vlib_main_t *,
u64 *, u64 *,
vlib_node_runtime_t *,
vlib_frame_t *, int);
/* Every so often we switch to the next counter. */
#define VLIB_LOG2_MAIN_LOOPS_PER_STATS_UPDATE 7
/*跳转退出主循环. */
u32 main_loop_exit_set;
/* Set e.g. in the SIGTERM signal handler, checked in a safe place... */
volatile u32 main_loop_exit_now;
clib_longjmp_t main_loop_exit;
#define VLIB_MAIN_LOOP_EXIT_NONE 0
#define VLIB_MAIN_LOOP_EXIT_PANIC 1
/* Exit via CLI. */
#define VLIB_MAIN_LOOP_EXIT_CLI 2
/*退出主循环时候的出错标记. */
clib_error_t *main_loop_error;
/*名称,例如:syslog. */
char *name;
/* 堆的开始. */
void *heap_base;
/* 截断版本,帧的索引*/
void *heap_aligned_base;
/* 堆的大小 */
uword heap_size;
/* 缓存区主体结构. */
vlib_buffer_main_t *buffer_main;
/* 物理内存主体结构. */
vlib_physmem_main_t physmem_main;
/* 节点编排主体结构. */
vlib_node_main_t node_main;
/* 命令行接口. */
vlib_cli_main_t cli_main;
/* 包的追踪缓冲区. */
vlib_trace_main_t trace_main;
/* Pcap 调度追踪 */
pcap_main_t dispatch_pcap_main;
uword dispatch_pcap_enable;
u32 *dispatch_buffer_trace_nodes;
u8 *pcap_buffer;
/* pcap 发送/接收跟踪 */
vnet_pcap_t pcap;
/* 错误处理. */
vlib_error_main_t error_main;
/* Punt packets to underlying operating system for when fast switching
code does not know what to do. */
void (*os_punt_frame) (struct vlib_main_t * vm,
struct vlib_node_runtime_t * node,
vlib_frame_t * frame);
/* Stream index to use for distribution when MC is enabled. */
u32 mc_stream_index;
vlib_one_time_waiting_process_t *procs_waiting_for_mc_stream_join;
/* 事件记录器. */
elog_main_t elog_main;
/* 事件记录器跟踪标志 */
int elog_trace_api_messages;
int elog_trace_cli_commands;
int elog_trace_graph_dispatch;
int elog_trace_graph_circuit;
u32 elog_trace_graph_circuit_node_index;
/* 节点调用和返回的时间类型. */
elog_event_type_t *node_call_elog_event_types;
elog_event_type_t *node_return_elog_event_types;
elog_event_type_t *error_elog_event_types;
/*种子随机生成器. */
uword random_seed;
/* 用于各种用途的随机数缓冲区. */
clib_random_buffer_t random_buffer;
/*用来记录调用了哪些init函数的散列表. */
uword *init_functions_called;
/* thread, cpu and numa_node 索引 */
u32 thread_index;
u32 cpu_id;
u32 numa_node;
/*要调用的init函数列表,由构造函数设置*/
_vlib_init_function_list_elt_t *init_function_registrations;
_vlib_init_function_list_elt_t *worker_init_function_registrations;
_vlib_init_function_list_elt_t *main_loop_enter_function_registrations;
_vlib_init_function_list_elt_t *main_loop_exit_function_registrations;
_vlib_init_function_list_elt_t *api_init_function_registrations;
vlib_config_function_runtime_t *config_function_registrations;
/*控制平面API队列信号挂起,长度指示*/
volatile u32 queue_signal_pending;
volatile u32 api_queue_nonempty;
void (*queue_signal_callback) (struct vlib_main_t *);
u8 **argv;
/* Top of (worker) dispatch loop callback */
void (**volatile worker_thread_main_loop_callbacks) (struct vlib_main_t *);
void (**volatile worker_thread_main_loop_callback_tmp)
(struct vlib_main_t *);
clib_spinlock_t worker_thread_main_loop_callback_lock;
/* debugging */
volatile int parked_at_barrier;
/* 事后日志转存 */
int elog_post_mortem_dump;
/*
* Need to call vlib_worker_thread_node_runtime_update before
* releasing worker thread barrier. Only valid in vlib_global_main.
*/
int need_vlib_worker_thread_node_runtime_update;
/*
* Barrier epoch - Set to current time, each time barrier_sync or
* barrier_release is called with zero recursion.
*/
f64 barrier_epoch;
/* Earliest barrier can be closed again */
f64 barrier_no_close_before;
/* 检测帧队列 */
volatile uword check_frame_queues;
/* RPC 请求, 仅仅是主线程*/
uword *pending_rpc_requests;
uword *processing_rpc_requests;
clib_spinlock_t pending_rpc_lock;
} vlib_main_t;
//注册节点,调用的是宏定义
VLIB_REGISTER_NODE (abf_ip6_node) =
{
.function = abf_input_ip6,
.name = "abf-input-ip6",
.vector_size = sizeof (u32),
.format_trace = format_abf_input_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = 0,
.n_next_nodes = ABF_N_NEXT,
.next_nodes =
{
[ABF_NEXT_DROP] = "error-drop",
}
};
//…,__VA_ARGS__为可变参数,##连接字符串
//__attribute__((__constructor__))修饰函数main函数之前执行
// __attribute__((__destructor__)) 修饰函数在main函数结束之后执行
#define VLIB_REGISTER_NODE(x,...) \
__VA_ARGS__ vlib_node_registration_t x; \
static void __vlib_add_node_registration_##x (void) \
__attribute__((__constructor__)) ; \
static void __vlib_add_node_registration_##x (void) \
{ \
vlib_main_t * vm = vlib_get_main(); \
x.next_registration = vm->node_main.node_registrations; \
vm->node_main.node_registrations = &x; \
} \
static void __vlib_rm_node_registration_##x (void) \
__attribute__((__destructor__)) ; \
static void __vlib_rm_node_registration_##x (void) \
{ \
vlib_main_t * vm = vlib_get_main(); \
VLIB_REMOVE_FROM_LINKED_LIST (vm->node_main.node_registrations, \
&x, next_registration); \
} \
__VA_ARGS__ vlib_node_registration_t x
//定义
//构造init函数列表
#define VLIB_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,init)
#define VLIB_WORKER_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,worker_init)
#define VLIB_MAIN_LOOP_ENTER_FUNCTION(x) \
VLIB_DECLARE_INIT_FUNCTION(x,main_loop_enter)
#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x) \
VLIB_DECLARE_INIT_FUNCTION(x,main_loop_exit)
#define VLIB_API_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,api_init)
#define VLIB_CONFIG_FUNCTION(x,n,...)
启动调用vlib_call_all_init_functions函数加载执行。
typedef struct
{
/* 公共节点. */
vlib_node_t **nodes;
/* 按照节点名散列的节点索引. */
uword *node_by_name;
u32 flags;
#define VLIB_NODE_MAIN_RUNTIME_STARTED (1 << 0)
/* 按类型为缓存位置分隔的节点.
Does not apply to nodes of type VLIB_NODE_TYPE_INTERNAL. */
vlib_node_runtime_t *nodes_by_type[VLIB_N_NODE_TYPE];
/* 带有挂起中断的输入节点的节点运行时索引. */
u32 *pending_interrupt_node_runtime_indices;
clib_spinlock_t pending_interrupt_lock;
/* 输入节点切换从/打断/轮询方式当平均向量长度高于/低于轮询/中断阈值. */
u32 polling_threshold_vector_length;
u32 interrupt_threshold_vector_length;
/* 下一帧向量. */
vlib_next_frame_t *next_frames;
/* 等待调用的内部节点帧的向量. */
vlib_pending_frame_t *pending_frames;
/* 用于调度基于时间的节点调度的定时轮. */
void *timing_wheel;
vlib_signal_timed_event_data_t *signal_timed_event_data_pool;
/* 通过timing_wheel_advance添加的不透明数据向量. */
u32 *data_from_advancing_timing_wheel;
/* CPU time of next process to be ready on timing wheel. */
f64 time_next_process_ready;
/* Vector of process nodes.
One for each node of type VLIB_NODE_TYPE_PROCESS. */
vlib_process_t **processes;
/* Current running process or ~0 if no process running. */
u32 current_process_index;
/* Pool of pending process frames. */
vlib_pending_frame_t *suspended_process_frames;
/* Vector of event data vectors pending recycle. */
void **recycled_event_data_vectors;
/* 每个状态的当前节点数. */
u32 input_node_counts_by_state[VLIB_N_NODE_STATE];
/* Hash of (scalar_size,vector_size) to frame_sizes index. */
uword *frame_size_hash;
/* Per-size frame allocation information. */
vlib_frame_size_t *frame_sizes;
/* 清除最后一个节点运行时的时间统计信息. */
f64 time_last_runtime_stats_clear;
/* 节点注册结构 */
vlib_node_registration_t *node_registrations;
/* Node index from error code */
u32 *node_by_error;
} vlib_node_main_t;
typedef struct _vlib_node_registration
{
/* 此节点的向量处理函数. */
vlib_node_function_t *function;
/*通过优先级节点函数候选注册 */
vlib_node_fn_registration_t *node_fn_registrations;
/* 节点名称. */
char *name;
/* 兄弟名称. */
char *sibling_of;
/* 节点索引. */
u32 index;
/* 节点类型. */
vlib_node_type_t type;
/* 错误字符串. */
char **error_strings;
/*这个节点的缓冲区格式. */
format_function_t *format_buffer;
unformat_function_t *unformat_buffer;
/*这个节点的消息跟踪格式. */
format_function_t *format_trace;
unformat_function_t *unformat_trace;
/*用于验证传入帧. */
u8 *(*validate_frame) (struct vlib_main_t * vm,
struct vlib_node_runtime_t *,
struct vlib_frame_t * f);
/*每个节点的运行时数据. */
void *runtime_data;
/*进程堆栈大小. */
u16 process_log2_n_stack_bytes;
/*每个节点运行时数据的字节数. */
u8 runtime_data_bytes;
/*输入节点的状态*/
u8 state;
/* 节点标志. */
u16 flags;
/* protocol at b->data[b->current_data] upon entry to the dispatch fn */
u8 protocol_hint;
/*标量和向量的大小(以字节为单位). */
u16 scalar_size, vector_size;
/*此节点使用的错误代码数量. */
u16 n_errors;
/*随后的下一个节点名的数目. */
u16 n_next_nodes;
/* 链表结构,下一个节点*/
struct _vlib_node_registration *next_registration;
/*此节点输入到的下一个节点的名称. */
char *next_nodes[];
} vlib_node_registration_t;
typedef uword (vlib_node_function_t) (struct vlib_main_t * vm,
struct vlib_node_runtime_t * node,
struct vlib_frame_t * frame);
vlib_main_or_worker_loop函数中循环处理node调度