简介
Testpmd是dpdk自带的测试工具,也可以被看做一个APP。当运行testpmd时,可以展示和验证网卡支持的各种PMD相关功能。
1-testpmd的基础代码
包括testpmd的启动运行,参数解析,设备的检测和配置。包括如下文件
config.c //这个文件名可能有些误导。实际上,这个文件中包含的是UI相关的配置和显示的代码 cmdline.c bpf_cmd.c cmdline_flow.c cmdline_mtr.c cmdline_tm.c
2-转发功能代码
为了方便对PMD功能的测试,testpmd中预设了若干种不同的转发模式。不同的转发模式意味着testpmd对收到的包进行了不同的处理,然后将其发送甚至是丢弃
//转发模式的设计是一种简化问题的思路。 //简单的切换转发模式可以规避复杂的难以实现的配置。 //包括以下文件,每个文件是一种单独的转发模式 csumonly.c flowgen.c icmpecho.c ieee1588fwd.c iofwd.c macfwd.c macswap.c rxonly.c softnicfwd.c txonly.c
基础代码
Main函数
testpmd的执行过程
rte_eal_init :对DPDK运行环境的初始化
set_def_fwd_config :进行转发相关的默认配置。
1,set_default_fwd_lcores_config
- 实际上是对配置的逻辑core的信息进行记录,包括socket相关的信息
2, set_def_peer_eth_addrs
- 设置了一个默认的以太网地址,用于转发时填写以太帧头的目的地址
3, set_default_fwd_ports_config
- 简单的将前面解析出来的port的信息记录下来。主要是明确有几个port,以便后续的处理。
launch_args_parse
这个函数对参数进行字符串的匹配,以获取配置信息。在这一阶段,获取的信息只是记录下来,以供后续的处理
init_config:参数进行初始配置
1、 运行DPDK的逻辑core的配置
2、 收发包所需要的mbuf的配置
3、 设备的设置。在这里是将配置信息存放在适当的地方,下面进行使能设备的时候才会将其真正的设置到硬件中生效。
4、 转发引擎的配置。
start_port
用户接口CLI
- CLI是command line interface的简写 作为一个轻量级的测试工具,testpmd的人机交互功能比较弱而有限,不需要复杂的图形界面就可以完成。因此使用CLI的好处也是比较明显的,可以控制项目的大小,防止在非核心的功能上花费过多的精力。
CLI举例
CLI都是比较类似的,简单的说,实现的就是解析字符串并将其和某个API关联起来,然后执行API的过程。
如端口信息显示
testpmd> show port info 0********************* Infos for port 0 ********************* MAC address: 3C:FD:FE:9D:25:8C Device name: 0000:07:00.0 Driver name: net_i40e Connect to socket: 0 memory allocation on the socket: 0 Link status: up Link speed: 10000 Mbps Link duplex: full-duplex MTU: 1500 Promiscuous mode: enabled Allmulticast mode: disabled Maximum number of MAC addresses: 64 Maximum number of MAC addresses of hash filtering: 0 VLAN offload:strip offfilter offqinq(extend) off Hash key size in bytes: 52 Redirection table size: 512 Supported flow types:ipv4-fragipv4-tcpipv4-udpipv4-sctpipv4-otheripv6-fragipv6-tcpipv6-udpipv6-sctpipv6-otherl2_payload Minimum size of RX buffer: 1024 Maximum configurable length of RX packet: 9728 Maximum number of VMDq pools: 64 Current number of RX queues: 1 Max possible RX queues: 320 Max possible number of RXDs per queue: 4096 Min possible number of RXDs per queue: 64 RXDs number alignment: 32 Current number of TX queues: 1 Max possible TX queues: 320 Max possible number of TXDs per queue: 4096 Min possible number of TXDs per queue: 64 TXDs number alignment: 32
数据结构介绍
每个CLI都对应一个数据结构变量,这存在cmdline.c文件中。“show port info”的数据结构变量是:
cmdline_parse_inst_t cmd_showport = {.f =cmd_showport_parsed,.data =NULL,.help_str= "show|clear port ""info|stats|xstats|fdir|stat_qmap|dcb_tc|cap""<port_id>",.tokens= {(void*)&cmd_showport_show,(void*)&cmd_showport_port,(void*)&cmd_showport_what,(void*)&cmd_showport_portnum,NULL,}, };
cmd_showport”包含四个部分:
1.f。应该是指function,即CLI所执行的函数。
2.data。除了CLI之外,可以传递给执行函数的参数。因为它不是通过CLI传递的,可以看做不是属于UI的一部分,一般也不使用,置为空。
3.help_str。帮助信息。从帮助信息看,此CLI承担的功能不仅仅是显示端口的信息,它还可以显示统计信息等,并且也能够清空统计信息等。当然,这只是帮助信息声称的功能,是不是真正是这些功能呢?下面的详细分析会进一步说明。
4.tokens。描述了构成CLI的各个字符串。我们可以看到,这个CLI由4个字符串构成。
- cmd_showport_show有两种可能,“show”或者“clear”。
- cmd_showport_port只能是“port”。
- cmd_showport_what可以是以下任意一个,“info”、“stats”、“xstats”、“fdir”、“stat_qmap”、“dcb_tc”、“cap”
- cmd_showport_portnum则必须是无符号整数。
CLI解析介绍
- 简单的说,当一串字符可以和上述的四个小字符串的组合即tokens匹配时,就执行f所指定的函数。但是,当用户输入一串字符后,testpmd是怎么知道它能够匹配某一个CLI的呢?
上述的变量cmd_showport被放在了数组main_ctx中。
当用户输入一串字符后,程序将会遍历main_ctx数组中所有的变量,判断此字符串是否和数组中的某个变量匹配。
这部分的工作实际上是由librte_cmdline完成的。大致的流程如下:
1.将获取的一串字符分拆成若干子字符串。在分拆时,一串字符中的一个或若干个连续的空格被视为子字符串的间隔。显然字符串的结束符‘\0’被视为结束。
2.将这些子字符串和main_ctx数组中的变量逐个匹配。实际上是将子字符串和变量的tokens域进行匹配。例如如下字符串都可能和cmd_showport匹配。
- a. show port info 0
- b. show port stats 1
- c. clear port xstats 4
- d. clear port fdir 5
- e. …
3.当发现某个变量可以和输入的字符串匹配时,并不会停止,而是继续匹配剩下的变量。当发现还有另外一个变量可以和输入的字符串匹配时,将会报错——含义模糊的命令。这就要求testpmd的代码实现者在设计CLI时要保证不要和已有的CLI雷同。
4.匹配工作完成后,如果只有一个变量和输入的字符串匹配,则通过变量的f域执行处理函数。对于“showport info”是函数cmd_showport_parsed。
5.如果没有任何变量匹配,则报错。
函数执行
- 当CLI的解析完成后,就进入函数执行的阶段。函数执行并不是机械的执行某个动作,实际上有一定的自由度,可以选择需要的操作。
以“showport info”的执行函数为例,尽管变量cmd_showport中的token的组合有很多种,实际上只支持其中有意义的几种。
显示端口信息
如前所述,当用户输入适当的token组合后,testpmd就会进入到显示端口信息的处理。端口信息显示函数port_infos_display是testpmd实现的,通过调用rte_eth的API获取需要的信息,然后打印。