簡介
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 off filter off qinq(extend) off Hash key size in bytes: 52 Redirection table size: 512 Supported flow types: ipv4-frag ipv4-tcp ipv4-udp ipv4-sctp ipv4-other ipv6-frag ipv6-tcp ipv6-udp ipv6-sctp ipv6-other l2_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獲取需要的信息,然後打印。