• DPDK — CLI 指令行模块


    目录

    DPDK CLI

    当我们开发一个 DPDK App 时,可以利用 DPDK 提供的 CLI 工具为程序添加命令行实现。添加一个命令由四部分组成:

    1. 命令行初始化
    2. 命令行解析
    3. 命令行参数的数据结构
    4. 命令行的功能实现函数

    在 /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 <zer0@droids-corp.org>
     * 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
    ");
    
    	cl = cmdline_stdin_new(main_ctx, "example> ");
    	if (cl == NULL)
    		rte_panic("Cannot create cmdline instance
    ");
    	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
    ", res->name);
    			return;
    		}
    		break;
    	}
     
    	o = malloc(sizeof(*o));
    	if (!o) {
    		cmdline_printf(cl, "mem error
    ");
    		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
    ",
    		       o->name, ip_str);
    }
    

    参考文档

    https://blog.csdn.net/zhang1051546117/article/details/78051240

    相关阅读:

  • 相关阅读:
    数据库性能优化一:数据库自身优化(大数据量)
    Delphi中initialization和finalization
    Delphi中的消息处理
    布施持戒忍辱精进禅定般若——净空法师【转】
    如何清除sql server日志
    工作反省
    软件设计入门2 数据库设计
    软件设计入门1 架构设计
    invokeRequired属性和 invoke()方法
    delphi 生成验证码
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309169.html
Copyright © 2020-2023  润新知