dpdk-pdump 是什麼
dpdk-pdump 是 dpdk 提供的一個工具。它可以可以作爲 secondary 程序運行,能夠捕獲 dpdk 的端口的數據包。
編譯 dpdk-pdump
dpdk-pdump 工具的源碼位於 dpdk 源碼根目錄下的 ./app/pdump 目錄中,不需要像 examples 中的 demo 一樣單獨編譯,它會在編譯 dpdk 的同時也被編譯,我們可以在編譯生成的 app 目錄中找到這個程序。
在我的虛擬機中,編譯 dpdk 後,它的位置如下:
/home/longyu/dpdk-stable-17.05.2/x86_64-native-linuxapp-gcc/app/dpdk-pdump
使用 dpdk-pdump
dpdk-pdump 的用法如下:
usage: ./dpdk-pdump [EAL options] – --pdump ‘(port= | device_id=),(queue=<queue_id>),(rx-dev= | tx-dev=,[ring-size=default:16384],[mbuf-size=default:2176],[total-num-mbufs=default:65535]’ [–server-socket-path=default:/var/run/.dpdk/ (or) ~/.dpdk/] [–client-socket-path=default:/var/run/.dpdk/ (or) ~/.dpdk/]
dpdk-pdump 需要依賴一個 dpdk primary 進程,我就以 l2fwd 命令作爲 dpdk primary 進程。
有了 dpdk primary 進程之後,根據我的環境,我使用如下命令行啓動 dpdk-pdump
sudo ./dpdk-pdump -n 4 -- --pdump 'port=0,queue=*,rx-dev=./rx-pcap'
no driver for pcap 的問題
我第一次執行上面的命令時程序異常終止,錯誤信息如下:
EAL: no driver found for eth_pcap_rx_0
EAL: Driver, cannot attach the device
通過搜索,我發現上面的錯誤是因爲在編譯 dpdk 時沒有啓用 PCAP 相關的功能所致,參考鏈接如下:
dpdk-pdump-no-driver-found-for-net-pcap
根據網頁中的回答我對 .config 文件做了如下修改以使能 PCAP 的相關功能:
longyu@longyu-pc:~/dpdk-stable-17.05.2/x86_64-native-linuxapp-gcc$ grep 'PCAP' .config
# Compile software PMD backed by PCAP files
CONFIG_RTE_LIBRTE_PMD_PCAP=y
CONFIG_RTE_PORT_PCAP=y
這之後重新編譯後繼續測試,這個問題得到了解決,可又遇到了一個新的問題。
無法與 primary server 端通信的問題
解決了 pcap driver 的問題後,我重新執行 dpdk-pdump 時新的報錯信息如下:
PDUMP: failed to send to server:No such file or directory,
pdump_create_client_socket:702 PDUMP: client request for pdump
enable/disable failed PDUMP: failed to send to server:No such file or
directory, pdump_create_client_socket:702 PDUMP: client request for
pdump enable/disable failed
通過閱讀官方網頁中的說明,我發現了問題所在。官方的說明中提到 dpdk-pdump 工具只能與初始化了 packet capture framework 的主程序通信,而 packet capture framework 的初始化需要修改程序的源碼。
在 dpdk 提供的工具中,testpmd 工具的源碼中添加了 packet capture framework 的初始化代碼,我查看相關代碼,找到了如下源碼行:
diag = rte_eal_init(argc, argv);
if (diag < 0)
rte_panic("Cannot init EAL\n");
#ifdef RTE_LIBRTE_PDUMP
/* initialize packet capture framework */
rte_pdump_init(NULL);
#endif
上面的代碼會在 RTE_LIBRTE_PDUMP 宏定義時執行 rte_pdump_init 函數來進行必要的初始化,RTE_LIBRTE_PDUMP 功能在 .config 中進行配置,默認爲開啓。
.config 中與 RTE_LIBRTE_PDUMP 功能相關的配置如下:
# Compile architecture we compile for. pdump library
CONFIG_RTE_LIBRTE_PDUMP=y
當使用能了這個參數後,編譯目錄下的頭文件 rte_config.h 中會定義 RTE_LIBRTE_PDUMP 宏,相關的代碼如下:
#undef RTE_LIBRTE_PDUMP
#define RTE_LIBRTE_PDUMP 1
我按照上面的描述修改了 dpdk-pdump 程序的源碼後,終於能夠正常執行了!
查看 dump 出的數據包文件
dpdk-pdump 中已經對 dump 出的原始數據包進行了轉化,我們可以直接使用 tcpdump 的 -r 選項來查看生成的文件。
我指定 dpdk-pdump dump 端口接收到的包,指定存儲文件爲 ./rx-pcap。我只需要執行下面的命令就可以看到接收到的數據包的詳細信息。
sudo tcpdump -r ./rx-pcap
總結
dpdk 提供的程序在使用時可能會遇到一些問題,解決這些問題的一般步驟如下:
- 查看依賴的功能是否開啓(修改 .config 文件)
- 修改必要的源代碼以執行必要的初始化工作
- 重新編譯後再次執行