在前面的章节中,我们讲述了如何编译和安装思科开源的fdio/vpp
有关于如何编译vpp,本章节不做过多的讲述,下面我们主要分析一下VPP这款软件架构的启动流程;
下载源码
git clone https://git.fd.io/vpp
VPP 初始化描述
在vpp代码中其初始化通过 VLIB_INIT_FUNCTION 宏来定义构造函数(代码路径vpp/src/vlib/init.h)
#define VLIB_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,init)
这个宏定义如下所示:
在这个宏定义中注册函数到vlib_global_main_t ->
init_function_registrations,这个链表在main()函数之前创建。
我们可以通过指令查询初始化,指令设计如下所示:
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_init_function, static) = {
.path = "show init-function",
.short_help = "show init-function [init | enter | exit][verbose [nn]]",
.function = show_init_function_command_fn,
};
/* *INDENT-ON* */
在main函数中vlib_main(),调用vlib_node_main_init,将前面注册的初始化函数调用。
vlib_main()-> vlib_call_all_init_functions()
然后在最后执行main loop
全局其他宏定义:
序号 | 由宏定义和构造函数创建的全局链表的方式的其他函数 | ||||||||
---|---|---|---|---|---|---|---|---|---|
1、 | VLIB_API_INIT_FUNCTION | ||||||||
2、 | VLIB_CLI_COMMAND | ||||||||
3、 | VLIB_CONFIG_FUNCTION | ||||||||
4、 | VLIB_EARLY_CONFIG_FUNCTION | ||||||||
5、 | VLIB_MAIN_LOOP_ENTER_FUNCTION | ||||||||
6、 | VLIB_MAIN_LOOP_EXIT_FUNCTION | ||||||||
7、 | VLIB_REGISTER_NODE |
vlib main 函数相关流程:相关函数的具体功能请大家结合源码对照详细的处理逻辑。
1、vlib_main函数位于vlib/main.c中
2、VLIB_REGISTER_NODE定义图节点,注册到vlib_main_t->node_registrations,vlib_register_all_static_nodes()遍历这个链表,创建图节点(不是连接,是创建)。
3、VLIB_INIT_FUNCTION声明的函数,由vlib_call_all_init_functions()调用初始化。
4、如果结点被创建,vlib/node.c的vlib_node_main_init()会对图结点进行初始化。
5、VLIB_MAIN_LOOP_ENTER_FUNCTION注册一个链表,vlib_call_all_main_loop_enter_functions()函数遍历该链表。
6、调用vlib_main_loop()。
Vlib_main_loop 函数逻辑介绍:
函数位于:vpp/src/vlib/main.c
函数处理逻辑描述:
1、VLIB_NODE_TYPE_PRE_INPUT:类似DBG_CLI的节点。
2、VLIB_NODE_TYPE_INPUT:这些是主要节点,主要从网卡或者硬件加速器获取数据包。
3、进程等待信号,这个很重要,因为所有的客户端都要通过共享内存和VPP通信。客户端向共享内存发送一些API消息,并且向VPP发送信号(SIGUSR1)。
输入结点组织数据包,并且将他们发送到合适的中间结点。由dispatch_pending_node()进一步处理这些数据包。
写在最后:
本文主要讲述了思科开源的,可用于开箱生产的DPDK协议栈软件VPP的初始化流程,时间仓促,难免有疏漏之处,欢迎广大朋友们斧正。