VPP CLI 原理分析
1.命令注册
1.1 VLIB_CLI_COMMAND 宏
static clib_error_t *
upf_show_ha_command_fn (vlib_main_t *vm, unformat_input_t *main_input,
vlib_cli_command_t *cmd)
{
upf_main_t *um = &upf_main;
vlib_cli_output (vm, "UPF HA Status: %s\n",
um->ha_status == HA_STATUS_ACTIVE ? "ACTIVE" : "BACKUP");
return NULL;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (upf_show_ha_command, static) = {
.path = "show upf ha status",
.short_help = "show upf ha status",
.function = upf_show_ha_command_fn,
};
/* *INDENT-ON* */
VLIB_CLI_COMMAND 将命令 upf_show_ha_command
注册到 vm->cli_main->cli_command_registrations
链表
命令名定义: .path = “show upf ha status”,
命令格式定义:.short_help = “show upf ha status”,
命令对应的钩子函数,实现命令的功能:.function = upf_show_ha_command_fn。
1.2 VLIB_INIT_FUNCTION宏
VLIB_INIT_FUNCTION (upf_init);
VLIB_INIT_FUNCTION (upf_init) 中的 upf_init 遍历 vm->cli_main->cli_command_registrations
链表,对 upf 的每个命令调 vlib_cli_register 函数。
1.3 vlib_cli_register函数
四要素:命令、标准化命令(normalized_path),命令索引链表(command_index_by_path)、命令向量链表(commands)。
注册大致过程:查看 vm->cli_main->command_index_by_path
的 hash 链表,是否存在标准化命令 normalized_path。如果对应的命令索引存在,则把注册命令时向量结点的参数覆盖原有的向量结点的值。如果命令向量不存在,则创建。把命令添加到命令向量链表里,首先检查下标ci是否越界,如果没有越界则获取向量值。
2. VPP CLI 机制之客户端 vppctl 和服务端 vpp
2.1 vpp与vppctl交互的关键文件
/run/vpp/cli.sock
VPPCTL
vppctl 端创建与 /run/vpp/cli.sock 路径服务端进行通信的本地套接字 client 端,从标准输入读取命令,发送给服务端,并从服务端读取返回值。
VPP
vpp 端创建监听 /run/vpp/cli.sock 路径的服务端,创建权限为 755。服务端通过 epoll 实现多并发过程。
与客户端交互,当客户端发送数据来时,file_main 接收到 epoll_in 事件调客户端注册的 read_function(unix_cli_read_ready)
,从描述符读数据存放到 cf->input_vector
,并发送 UNIX_CLI_PROCESS_EVENT_READ_READY 事件交 unix_cli_process 结点处理,unix_cli_process_input 进行命令解析和处理;
unix_cli_process_input -> unix_cli_line_edit -> unix_cli_line_process_one 逐字读取字符并回显 -> 然后判断 unix_cli_match_action 是否是 telnet -> 然后调 unix_cli_process_telnet 或 unix_cli_process_one 进行输入的字符串读取 -> 读取完成调 vlib_cli_input 进行关键字匹配 -> 匹配到后通过命令执行函数 -> vlib_cli_output 函数将需要发送或回复 cli 客户端的信息通过 output_function: unix_vlib_cli_output;将数据 send 发到 cli 客户端。
2.2 VLIB_EARLY_CONFIG_FUNCTION 宏
VLIB_EARLY_CONFIG_FUNCTION (unix_config, "unix")
读取 startup.conf 中 unix 相关配置,对应 cli 默认配置了 cli socket 的路径(cli-listen /run/vpp/cli.sock)。
2.3 VLIB_CONFIG_FUNCTION 宏
VLIB_CONFIG_FUNCTION (unix_cli_config, "unix-cli")
cli 默认配置是非交互模式。cli 配置成交互式,则将标准输入作为客户端进行监听(startup.conf 配置文件中默认未配置)。