http://www.cnblogs.com/bits/archive/2009/03/25/Linux-PF_RING.html
在千兆網環境下,tcpdump丟包率相當高。網上搜了很多制標不治本的方法,比如增大緩衝區,然而緩衝區再大也有塞滿的時候,只能從驅動和硬件下手。好在有“零拷 貝(Zero Copy)”這個東西(說白了也就是通過DMA等方式,省掉從NPF驅動到用戶程序內存空間的一次複製,給CPU減少負擔),而PF_RING正是一個通 過給Linux內核打補丁來實現zero copy的強大工具,於是想給Fedora集成個PF_RING。
沒接觸過Linux內核,網上這方面資料都是Ubuntu
的,和Fedora下有點不同。
摸了近2周才把PF_RING給補上,記錄一下詳細編譯過程,以免以後又走彎路。
另一篇關於Fedora 9下編譯的文章:http://guotie.blogbus.com/logs/29668826.html
本文中的編譯過程, 在Fedora 7和Fedora 9下(實機和虛擬機)
均測試通過(來來回回編譯了內核5遍,不熟也熟了...)
文章中沒有需要單獨下載的壓縮包,內核源碼也建議使用PF_RING自帶的mkpatch.sh來下載(或者下完放到workspace目錄中)
首先,按照正常步驟,下載PF_RING(粗體是要輸入的命令,我的PF_RING存放目錄是 /home/kernel)
:
cd /home/kernel
svn co https://svn.ntop.org/svn/ntop/trunk/PF_RING/
等下載完成後,/home/kernel 下多了一個PF_RING的目錄。
cd PF_RING
# ll
total 36
drwxr-xr-x 3 root root 4096 2009-03-17 16:26 doc
drwxr-xr-x 5 root root 4096 2009-03-17 16:26 kernel
-rwxr-xr-x 1 root root 14678 2009-03-20 22:48 mkpatch.sh
-rw-r--r-- 1 root root 643 2009-03-17 16:26 README
drwxr-xr-x 8 root root 4096 2009-03-17 16:26 userland
uname -a
或者 uname -r
確定內核版本(建議使用一樣的內核源文件編譯,這樣配置起來方便點)
vi mkpatch.sh
修改內核版本號
SUBLEVEL=${SUBLEVEL:-24.7}
默認是-24.7,這裏用你 uname -r 獲取的版本來代替,
例如
# uname -r
顯示
2.6.25
-14.fc9.i686
,
則改成
SUBLEVEL=25
./mkpatch.sh
下載內核到workspace
中,生成目錄linux-2.6.25-1-686-smp-PF_RING
和補丁文件linux-2.6.25-1-686-smp-PF_RING.patch.gz
,如下
# ll
total 60220
drwxr-xr-x 22 root root 4096 2009-03-21 20:43 linux-2.6.25
drwxr-xr-x 21 root root 4096 2008-04-17 10:49 linux-2.6.25-1-686-smp-PF_RING
-rw-r--r-- 1 root root 63254 2009-03-20 22:50 linux-2.6.25-1-686-smp-PF_RING.patch.gz
-rw-rw-r-- 1 zhou zhou 61517918 2009-03-20 22:45 linux-2.6.25.tar.gz
lrwxrwxrwx 1 root root 25 2009-03-20 22:49 PF_RING
-> /home/zhou/kernel/PF_RING
這裏不建議直接用生成的linux-2.6.25-1-686-smp-PF_RING 這個源碼,之前出問題都是在這個上面,還是按PF_RING手冊上說得給乾淨內核打補丁來得穩妥。另外,沒有特殊需要,不建議使用其他教程裏提及的Fedora RPM源碼包(kernel-2.6.25-14.fc9.src.rpm ) ,make時會出現些莫名奇妙的錯誤。
按下面操作把這個目錄給改名掉,然後手動給原始內核打補丁
:
mv linux-2.6.25-1-686-smp-PF_RING
/ linux-2.6.25-1-686-smp-PF_RING
.bak/
zcat linux-2.6.25-1-686-smp-PF_RING
.patch.gz | patch -p0
# 給 linux-2.6.25/
下的源碼打補丁
然後顯示一串被補丁的文件,OK。(注意,如果是乾淨內核,應該不會提示任何是否覆蓋已有patch之類的信息。如果出現這個,建議重新解壓內核打補丁)
這是關鍵一步
,建議仔細檢查一下打補丁的目錄是否是linux-2.6.25/
下的文件!
下面準備編譯內核
,首先給內核加個後綴名,以便標識:
cd linux-2.6.25
# vi Makefile
在這個地方加上一個自定義的後綴(比如-PF_RING)
:
EXTRAVERSION = -PF_RING
配置並編譯內核!(灰色指令是可選的)
make mrproper
# (不建議)
清除以前編譯的內核文件。因爲是新解壓的,保持原始狀態就好,不建議用這個
make oldconfig
# 讀取當前內核的配置(相當重要
,這步能省好多配置工作,而且保證生成的.config能直接使用)
# 其間會提示 PF_RING xxxx [N/y/m/?] (NEW)
,注意按y
選擇把PF_RING
給加進去,其他的選擇按回車默認即可
# 不過注意,如果編譯的內核版本較當前的新,會有很多(NEW)標記的提示,此時要是找不到PF_RING,建議先全部回車跳過
make menuconfig # 如果之前把PF_RING也跳過了,這裏可以進去重新選上
Networking --->
Networking options --->
PF_RING sockets
(NEW)
這裏按y
選上PF_RING,然後保存修改到.config退出。
(PF_RING手冊上說還要選上其他幾個,不過我沒找到... 應該默認是選上了)
- Enable RTIRQ ( if you use it )
- Enable 'Code maturity level options'
- > ' Prompt for development and / or incomplete code / drivers'
- Enable 'Networking options'
- > 'Socket Filtering'
- > 'PF_RING'
- Change any other option you like .
NOTE: if you have a network card ( e . g . Intel 1000 ) that supports NAPI , make
sure you enable it as this will result in great performance .
下面可以開始漫長的內核編譯了(最好完整編譯一次,直接make就行)
:
make
# 相當於 make bzImage modules
(其間會提示幾個警告 ,忽略之... 只要他還在繼續往下編譯,就放着不管好了 )
make modules_install # 安裝編譯好的modules
make install
# 將bzImage添加到grub中,以便用新內核啓動(注意,新添加的內核不是默認啓動項)
(用 make install 可以免去手動複製bzImage並生成initrd
的繁瑣過程,推薦!)
等安裝完成(不用重啓) ,然後編譯PF_RING自帶的程序。首先複製 linux/ring.h 到include中
cd ../..
# 回到 PF_RING/ 下
cp kernel/include/linux/ring.h /usr/include/linux/
cp kernel/include/linux/ring.h /usr/include/ # 有些地方說這裏也要複製一個,感覺不需要
編譯附帶的源碼和libpcap:
cd userland
make
# 直接在userland下make,會自動編譯子目錄裏的所有文件
安裝pf_ring的 lib 和 libpcap-ring:
cd lib/
make install
=*= making library libpfring.so =*=
gcc -shared pfring.o -lpthread -o libpfring.so
cp libpfring.a /usr/local/lib/
cp libpfring.so /usr/local/lib/
cp pfring.h /usr/local/include/
cd ../libpcap-0.9.7-ring/
make install
OK,重啓機器選新內核 啓動,就可以使用PF_RING來抓包了。
注意,剛啓動機器時,ls /proc/net/pf_ring/ 是看不到這個目錄的,只有當需要PF_RING的程序第一次運行時,纔會生成這個目錄以及一個info文件。之前因爲死活找不到這個目錄,還以爲自己編的內核有問題又來了一次...
重啓後這樣測試 PF_RING:
cd /home/kernel/PF_RING/userland/examples
./pfcount # 對應的還有一個 pcount,可以比較丟包率
(注意 :運行 pfcount 和 pf_test 需要root權限,不然會提示 pfring_open error )
另外查看dmesg或/var/log/messages,可以看到PF_RING的信息:
# dmesg | grep RING
[PF_RING] Welcome to PF_RING 3.9.3 # 這一部分是PF_RING初始化時輸出的
[PF_RING] Ring slots 4096
[PF_RING] Slot version 9
[PF_RING] Capture TX Yes [RX+TX]
[PF_RING] IP Defragment No
[PF_RING] Initialized correctly
[PF_RING] registered /proc/net/pf_ring/
[PF_RING] successfully allocated 815104 bytes at 0xd0ad4000 # 以後每次運行PF_RING程序,會輸出這樣的調試信息
[PF_RING] allocated 4115 slots [slot_len=198][tot_mem=815104]
[PF_RING] removed /proc/net/pf_ring/2849-eth0.0