目錄
DPDK CLI
當我們開發一個 DPDK App 時,可以利用 DPDK 提供的 CLI 工具爲程序添加命令行實現。添加一個命令由四部分組成:
- 命令行初始化
- 命令行解析
- 命令行參數的數據結構
- 命令行的功能實現函數
在 /opt/dpdk-18.08/examples/cmdline 中提供了一個完整的 Demo 可以供參考,也可以基於此 EXAMPLE 進行擴展。下述代碼均出於該示例。
初始化命令行
初始化命令行,其中命令行功能爲 cmd_obj_add_parsed,命令行的格式爲 tokens:
cmdline_parse_inst_t cmd_obj_add = {
.f = cmd_obj_add_parsed, /* function to call */
.data = NULL, /* 2nd arg of func */
.help_str = "Add an object (name, val)",
.tokens = { /* token 列表, NULL 結束 */
(void *)&cmd_obj_action_add,
(void *)&cmd_obj_name,
(void *)&cmd_obj_ip,
NULL,
},
};
然後,將初始化的命令行添加到一個保存命令行的數組中,該數組保存了所有命令行的實例(包含:定義、解析以及功能),以 NULL 結束:
/* CONTEXT (list of instruction */
cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_obj_add,
NULL,
};
最後,在 mian 函數中創建命令行對象,通過控制檯和用戶交互,具體實現如下:
// dpdk-18.08/examples/cmdline/main.c
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2014 Intel Corporation.
* Copyright (c) 2009, Olivier MATZ <[email protected]>
* All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <termios.h>
#include <sys/queue.h>
#include <cmdline_rdline.h>
#include <cmdline_parse.h>
#include <cmdline_socket.h>
#include <cmdline.h>
#include <rte_memory.h>
#include <rte_eal.h>
#include <rte_debug.h>
#include "commands.h"
int main(int argc, char **argv)
{
int ret;
struct cmdline *cl;
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_panic("Cannot init EAL\n");
cl = cmdline_stdin_new(main_ctx, "example> ");
if (cl == NULL)
rte_panic("Cannot create cmdline instance\n");
cmdline_interact(cl);
cmdline_stdin_exit(cl);
return 0;
}
命令行解析
cmdline_parse_token_string_t cmd_obj_action_add =
TOKEN_STRING_INITIALIZER(struct cmd_obj_add_result, action, "add");
cmdline_parse_token_string_t cmd_obj_name =
TOKEN_STRING_INITIALIZER(struct cmd_obj_add_result, name, NULL);
cmdline_parse_token_ipaddr_t cmd_obj_ip =
TOKEN_IPADDR_INITIALIZER(struct cmd_obj_add_result, ip);
命令行的參數
該結構體用於存儲命令行的參數列表:
struct cmd_obj_add_result {
cmdline_fixed_string_t action;
cmdline_fixed_string_t name;
cmdline_ipaddr_t ip;
};
命令行的功能
執行某個命令具體完成的功能:
static void cmd_obj_add_parsed(void *parsed_result,struct cmdline *cl, __attribute__((unused)) void *data)
{
struct cmd_obj_add_result *res = parsed_result; // 初始化命令行參數結構體;
struct object *o;
char ip_str[INET6_ADDRSTRLEN];
SLIST_FOREACH(o, &global_obj_list, next) {
if (!strcmp(res->name, o->name)) {
cmdline_printf(cl, "Object %s already exist\n", res->name);
return;
}
break;
}
o = malloc(sizeof(*o));
if (!o) {
cmdline_printf(cl, "mem error\n");
return;
}
snprintf(o->name, sizeof(o->name), "%s", res->name);
o->ip = res->ip;
SLIST_INSERT_HEAD(&global_obj_list, o, next);
if (o->ip.family == AF_INET)
snprintf(ip_str, sizeof(ip_str), NIPQUAD_FMT,
NIPQUAD(o->ip.addr.ipv4));
else
snprintf(ip_str, sizeof(ip_str), NIP6_FMT,
NIP6(o->ip.addr.ipv6));
cmdline_printf(cl, "Object %s added, ip=%s\n",
o->name, ip_str);
}
參考文檔
https://blog.csdn.net/zhang1051546117/article/details/78051240