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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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'

抓包脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/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 $@