pdump
简述
类似与tcpdump,可将dpdk的收发报文保存为pcap文件格式。 收包:网卡–>DMA–>rx_ring–>rx_burst–>rx_pkt_burst–>pdump_callback–>app; 发包:app–>tx_burst–>pdump_callback–>tx_pkt_burst–>tx_ring–>DMA–>网卡。
安装及使用
1)安装依赖
yum install -y libpcap-devel
2)修改配置
vim dpdk-stable-19.11.5/config/common_linux
末尾添加CONFIG_RTE_LIBRTE_PMD_PCAP=y
3)重新编译
cd dpdk-stable-19.11.5
export RTE_SDK=/export/servers/dpdk-stable-19.11.5
export RTE_TARGET=x86_64-native-linuxapp-gcc
make -j install T=x86_64-native-linuxapp-gcc(重新编译)
4)使用
vi main.c
添加
#include <rte_pdump.h>
在rte_eal_init()后面增加
#if 1
/* initialize packet capture framework */
rte_pdump_init(NULL);
#endif
make //重新编译应用
5)启动应用程序
6)抓包
/export/servers/dpdk-stable-19.11.5/x86_64-native-linuxapp-gcc/app/dpdk-pdump -- --pdump 'port=0,queue=*,rx-dev=./dpdk0.pcap,tx-dev=./dpdk0.pcap' --pdump 'port=1,queue=*,rx-dev=./dpdk1.pcap,tx-dev=./dpdk1.pcap'
抓包脚本
#!/bin/bash
# Created by tom on 2019/11/21
# Exit immediately if a command exits with a non-zero status.
#set -e
SERVICE_BIN="/export/servers/dpdk-stable-16.11.2/x86_64-native-linuxapp-gcc/app/dpdk-pdump"
usage(){
echo "===================================================================================="
echo "使用说明:"
echo " sh ./pdump.sh help //显示帮助信息"
echo " sh ./pdump.sh start 2 //启动pdump抓取2个网卡的报文并将报文保存在/tmp/dpdk-pdump"
echo " sh ./pdump.sh stop //停止抓包"
echo " sh ./pdump.sh status //显示当前pdump状态"
echo " sh ./pdump.sh save //保存当前抓取的所有报文到/export/pdump目录下"
echo "===================================================================================="
}
init(){
SERVICE="dpdk-pdump"
SHELL_FOLDER=$(cd "$(dirname "$0")";pwd)
cd ${SHELL_FOLDER}
OUT_FOLDER="/tmp/$SERVICE/"
SAVE_FOLDER="/export/pdump/"
FILE_NUM_LIMIT=10
mkdir -p $OUT_FOLDER
mkdir -p $SAVE_FOLDER
#关闭linux内核参数 - ASLR(Address space layout randomization);
#此参数会导致pdump不停的coredump;
echo 0 > /proc/sys/kernel/randomize_va_space
log_rotate
}
is_alive(){
count=`ps -ef | grep "$SERVICE" | grep -v "grep" | wc -l`
if [ $count -ne 0 ]
then
return 0
else
return 1
fi
}
log_rotate(){
count_current=`ls $OUT_FOLDER/*.log $OUT_FOLDER/*.pcap| awk -F'_' '{print $1}' |sort -n|uniq|wc -l`
if [ $count_current -gt $FILE_NUM_LIMIT ]
then
((num_to_delete=$count_current-$FILE_NUM_LIMIT))
item_to_delete=`ls $OUT_FOLDER/*.log $OUT_FOLDER/*.pcap | awk -F'_' '{print $1}' |sort -n|uniq|head -$num_to_delete`
for item in $item_to_delete
do
rm -rf ${item}*
done
fi
}
status(){
if is_alive
then
echo "$(date) $SERVICE is running."
else
echo "$(date) $SERVICE is not running."
fi
}
start(){
if ! is_alive
then
echo "$(date) $SERVICE starting..."
date_str=`date "+%Y%m%d%H%M%S"`
for ((i=0; i<$1; i++))
do
pdump_para_str=$pdump_para_str" --pdump ""port=$i,queue=*,rx-dev=$OUT_FOLDER/${date_str}_port${i}_rx.pcap,tx-dev=$OUT_FOLDER/${date_str}_port${i}_tx.pcap"
done
cd $OUT_FOLDER #如果有core文件,则生成到out_folder目录
nohup $SERVICE_BIN -- $pdump_para_str >> $OUT_FOLDER/${date_str}_dpdk-pdump.log 2>&1 &
sleep 1
if is_alive
then
echo "$(date) $SERVICE start success."
else
echo "$(date) $SERVICE start failed, please find the ERROR in the log [$OUT_FOLDER/${date_str}_dpdk-pdump.log]."
return 1
fi
else
echo "$(date) $SERVICE is already running."
return 0
fi
}
stop(){
if is_alive
then
echo "$(date) $SERVICE stopping ..."
pkill -2 "$SERVICE"
sleep 1
if is_alive
then
echo "$(date) stop(kill -2) $SERVICE failed, now use kill -9..."
pkill -9 "$SERVICE"
sleep 1
if is_alive
then
echo "$(date) stop(kill -9) $SERVICE failed."
return 1
else
echo "$(date) stop(kill -9) $SERVICE succeed."
return 0
fi
else
echo "$(date) stop(kill -2) $SERVICE succeed."
return 0
fi
else
echo "$(date) $SERVICE is already stopped."
return 0
fi
}
save(){
if is_alive
then
stop
fi
date_str=`date "+%Y%m%d%H%M%S"`
mkdir -p $SAVE_FOLDER/${date_str}
\cp $OUT_FOLDER/*.pcap $SAVE_FOLDER/${date_str}/
\cp $OUT_FOLDER/*.log $SAVE_FOLDER/${date_str}/
}
main(){
init
case "$1:$2" in
start:[1-2]) start $2 || exit 0 ;;
stop:) stop || exit 0 ;;
status:) status || exit 0 ;;
save:) save || exit 0 ;;
*) usage ;;
esac
}
main $@