摘要:結合共享內存和NAPI技術提出了一種基于通用硬件平臺和開源軟件實現的高速網絡鏈路數據包捕獲方案,能夠將數據包的捕獲能力和捕獲效率提升到一個新水平。通過實驗表明,在通用PC服務器上實現該方案完全能夠滿足千兆鏈路的監測需求,數據包處理能力可達到線速148.8萬pps。
關鍵詞:數據包捕獲;共享內存;新的應用編程接口
中圖分類號:TP393.06文獻標志碼:A
文章編號:1001-3695(2008)03-0807-04
網絡測試是了解網絡流量、分析業務性能的重要手段。如何實現高速鏈路流量捕獲分析是目前人們非常關注的問題[1]。數據包捕獲是被動測量的基本過程,一般有三種辦法:a)基于專用硬件的采集方法,如HP/Agilent Advisor[2]、InMon sFlow Probe[3]、Endace DAG[4]等。由于專用硬件可編程性差、價格通常比較昂貴,其性價比往往難以滿足用戶的要求。b)基于網絡處理器的數據包捕獲方法。網絡處理器(network processor,NP)[5]是專門為數據包處理而設計的可編程處理器,專門針對數據包處理部件進行優化,因此數據包的處理能力可以得到大幅度的提升。但是網絡處理器通常價格比較昂貴,而且針對特定硬件進行開發的特點易造成開發難度加大、可移植性差等問題。c)基于通用PC架構,通過普通的網絡接口卡捕獲數據包的方法,如Ethereal[6]、Wireshark[7]等工具。該方法采用通用硬件平臺的實現方式大大節約了成本,但是從網絡鏈路上捕獲數據包,再將捕獲到的數據包從操作系統內核空間拷貝到用戶空間需要占用大量的CPU資源。目前基于該方法實現的工具均不能提供監測百兆以上鏈路線速處理能力。
1研究背景
Libpcap[8]是由美國加州大學勞侖斯實驗室開發的開源數據包捕獲工具,對多種網絡媒介提供良好的支持,并具有可跨平臺移植的優勢,使其自1994年正式發布以來就成為UNIX、類UNIX平臺下開發流量監測分析程序首選的一款數據包捕獲工具。依賴于操作系統,Libpcap為流量監測分析程序提供虛擬的數據包捕獲平臺。通過該平臺流量監測分析程序能夠直接訪問網卡捕獲的數據包,從而簡化程序開發。Libpcap的工作流程可簡要概括如下:a)接收來自操作系統內核空間緩存的數據包。b)對接收到的所有數據包進行過濾規則匹配。如果匹配成功就將數據包拷貝到用戶空間緩存;否則直接丟棄數據包。c)運行在用戶空間的流量監測分析程序調用Libpcap提供的API接口讀取數據包信息。然而,隨著網絡技術的發展和高速網絡鏈路的普及,Libpcap在數據包捕獲性能方面的缺陷也逐漸暴露。探究其原因主要是數據包接收時產生的中斷開銷,將數據包從內核空間拷貝到用戶空間的系統調用和內存拷貝需要消耗大量的CPU資源[8,15],這就使得基于Libpcap實現的流量監測分析程序很難適用于百兆以上鏈路環境中。
隨著千兆網卡和千兆交換機等高速網絡設備逐步進入主流市場,小區寬帶接入網的出口帶寬也紛紛升級到千兆速率,對千兆甚至更高速率鏈路的監測需求已經迫在眉睫。因此,有人提出了基于Linux NetFilter[9]機制實現的動態可掛載內核模塊技術[10]。其基本思想是將數據包的解碼和統計分析等功能實現為一個內核模塊,轉移到操作系統內核中運行,以達到數據包內存零拷貝和減少系統調用開銷的目的。實驗表明此方法與NAPI(new API)技術[11]相結合可以獲得較高的性能,同時也存在諸多缺陷:a)在內核模塊中不能調用C標準函數庫,只能使用內核導出的少量系統調用,這就給監測和分析功能的開發實現帶來了很大的麻煩;b)在內核中開發代碼不僅容易出錯而且不易調試,在程序中隱藏的BUG極有可能會導致系統崩潰,給用戶造成無法估量的嚴重后果;c)出于安全方面的考慮,一般來說用戶會拒絕在某些關鍵機器上運行內核程序。
NAPI技術是為解決中斷活鎖問題(interrupt livelock)[12]而引入的。高速外圍設備的出現給操作系統引入了中斷活鎖問題,主要目的是降低設備對CPU的中斷請求次數。目前在Linux、FreeBSD和Windows等主流操作系統中都采用了一種降低中斷頻率的技術——設備輪詢[13]。采用輪詢技術可以提高系統在重負載時的效率,但在輕負載時會增加系統對設備的響應延遲。中斷技術在輕負載時可減小響應延遲,但在重負載時會引起中斷活鎖。NAPI則是一種中斷與輪詢相結合的技術,在輕負載時系統采用中斷方式處理數據包;在重負載時只中斷一次,隨后采用輪詢的方式處理多個數據包,從而減少中斷次數。實驗表明,在千兆鏈路監測應用中即使采用了NAPI技術,基于Libpcap的數據包捕獲應用其數據包深度分析能力最高只能達到18.5萬pps,丟包率約為87.5%,遠遠不能滿足千兆鏈路的監測需求;基于內核模塊的數據包捕獲應用其數據包深度分析能力達到110萬pps,丟包率約為25%,還不能滿足線速監測的需求。
綜上所述,可在通用硬件平臺上實現的且能夠達到更高性能的、可滿足高速網絡鏈路監測需要的數據包捕獲方法仍舊是迫切需要的。
2基于多空間內存共享高速網絡鏈路數據包捕獲方法
2.1結構
本文所提出的基于多空間內存共享的高速網絡鏈路數據包捕獲方法采用內存映射技術,其關鍵在于采用了可跨越內核空間和用戶空間界限的共享內存作為數據包緩存,減少系統調用次數,實現數據包內存零拷貝,從而縮短了數據包從網卡到流量監測分析程序的傳輸路徑。
如圖1所示,基于多空間內存共享的高速網絡鏈路數據包捕獲方法由三個部分組成,即底層數據包獲取驅動模塊、共享內存管理模塊和上層應用API接口。
系統中實現的數據包處理流程如下:a)底層數據包獲取驅動模塊捕獲數據包;b)通過共享內存管理模塊檢查數據包緩存空間,如果尚有可用的緩存空間,則將數據包通過DMA(directly memory access)通道寫入到共享內存并返回,否則直接丟棄數據包;c)流量監測分析程序調用上層應用API接口訪問共享內存中緩存的數據包,完成數據包處理和分析工作后釋放數據包緩存。
2.2設計與實現
如上所述,基于多空間內存共享的高速網絡鏈路數據包捕獲方法的實現主要包括以下三個部分。
2.2.1底層數據包獲取驅動模塊
底層驅動模塊通過增加驅動程序的部分功能,實現數據包在共享內存中的存儲和管理。新增的功能主要包括:
a)在底層數據包獲取驅動模塊初始化過程中加載共享內存管理模塊,初始化共享內存。
b)區分監測接口和控制接口接收到的數據包。監測接口數據包送到共享內存數據信息域中緩存;控制接口數據包按照正常的數據包處理流程,送入操作系統內核協議棧中接受處理。
c)創建一個字符設備用于共享內存的管理,在字符設備中實現mmap內存映射系統調用的具體方法,mmap系統調用封裝在上層應用API接口中提供給流量監測分析程序調用。
需要補充的是,為了不影響主機的正常通信,這里引入了監測接口和控制接口的概念。其中:監測接口用于被監測鏈路的數據包捕獲;控制接口用于主機的正常通信(如可用于監測系統的配置和管理)。在監測接口上接收從被監測鏈路上偵聽到的數據包并存儲到網卡的板載緩存;底層數據包獲取驅動模塊讀取全局索引數組信息,檢查共享內存管理信息域,判斷數據包是否能夠安全寫入數據信息域中(判斷方法是:如果當前需要被寫入的數據包緩存單元的全局引用計數器skb_cnt_index[i]值為0,說明該緩存單元可以安全覆蓋);如果數據包可以被寫入到共享內存中,底層驅動模塊將數據包通過DMA通道從網卡板載緩存搬運到共享內存數據信息域中存放,并初始化管理信息域中與數據包緩存單元對應的管理單元(對共享內存中的數據信息域和管理信息域的說明詳見2.2.2節)。底層數據包獲取驅動模塊需要初始化的內容包括:a)根據當前系統中已注冊的上層流量監測分析應用的個數初始化全局引用計數器數組中的對應元素,形式化表達式為skb_cnt_index[i] = app_counter;b)將訪問標志字段數組中的對應元素重新置位,形式化表達式為skb_label_index[i] = 0x00。否則,數據包不能夠被寫入到共享內存中,說明共享內存數據信息域產生溢出,底層驅動模塊則直接丟棄收到的數據包。在本實現中修改開源的Intel e10006.3.9[14]網卡驅動程序完成本模塊。
2.2.2共享內存管理模塊
共享內存管理模塊負責向操作系統申請一塊連續的物理內存作為內核空間和用戶空間共享的內存,將申請得到的物理內存劃分為數據信息域和管理信息域。數據信息域用于緩存接收到的數據包,管理信息域則被用于管理數據信息域。該模塊在底層數據包獲取驅動模塊的初始化過程中被加載,在加載過程中會分別對數據信息域和管理信息域進行初始化。此外,流量監測分析程序通過管理信息域中的數據結構向底層數據包獲取驅動模塊注冊自身信息并下達數據包查看請求。
共享內存管理模塊實現從操作系統頁表中查找連續的空閑內存頁面,在查找到的多段連續空閑內存中選擇一個內存段,選擇策略可以按操作系統的內存分配方法實現為最佳匹配、最大匹配和最快匹配,在選出的某一空閑內存段中再劃分出用戶指定數量的頁面并將頁面標記為reserved,操作系統內存調度程序不能將標記頁面交換出物理內存。這就保證了共享內存的專用性。圖2給出共享內存管理模塊的邏輯結構。
定義共享內存大小為MEM_SHARE MB、數據信息域DATA_AREA MB、管理信息域CTRL_AREA MB。這三者滿足MEM_SHARE= DATA_AREA +CTRL_AREA。數據信息域被分割成定長的數據包緩存單元,每單元緩存一個數據包,定義數據包緩存單元長度為PKT_UNIT字節。數據信息域在邏輯上形成一個環形緩沖區循環存放接收到的數據包;管理信息域用來存放數據信息域中的數據包所對應的全局索引數組信息和流量監測分析程序的注冊信息。如表1所示,共包含有四個數據成員信息。其中:skb_cnt_index和skb_label_index數組合稱為全局索引數組信息;app_counter和appname合稱為流量監測分析程序的注冊信息。app_counter最多可支持MAX_APP個應用程序同時注冊運行;appname[MAX_APP][NAME_LEN]應用程序的注冊名稱不允許超過NAME_LEN個字節。skb_cnt_index [DATA_AREA/PKT_UNIT]該計數器初始化為app_counter中的值,此后由流量監測分析程序遞減該計數器到0。skb_label_index [DATA_AREA/PKT_UNIT]該字段初始化為0,此后由流量監測分析程序將該字段的對應標志位置1。
共享內存空間的建立是實現高速網絡鏈路數據包捕獲方法的關鍵。如圖1所示,底層數據包獲取驅動模塊負責寫入數據包到共享內存,流量監測分析程序調用上層應用API接口讀取數據包進行統計和分析,這種情況可視為簡單的單生產者多消費者問題。為避免引入鎖機制帶來的額外開銷,系統實現了免鎖算法,簡言之其通過讀寫指針的協調管理來實現,底層數據包獲取驅動模塊移動寫指針,流量監測分析程序移動讀指針。每當讀指針試圖超越寫指針時就停止讀取動作,掛起讀取進程;反之亦然。通過底層數據包獲取驅動模塊直接向共享內存數據信息域順序循環寫入數據,而位于用戶空間的應用程序調用上層應用API接口訪問共享內存,達到數據包內存零拷貝和消除系統調用開銷的目的。
2.2.3上層應用API接口
類似Libpcap所提供的API接口,上層應用API接口提供了一系列基本功能接口函數。支持的功能主要包括:a)流量監測分析程序向底層數據包獲取驅動模塊注冊信息;b)打開高速網絡數據包捕獲設備;c)設置數據包捕獲設備的默認訪問參數,將共享內存映射到流量監測分析程序;d)用戶可配置數據包捕獲設備的訪問參數,包括數據包讀取的輪詢時間、最大等待時間和最低可返回數據量;e)獲取數據包捕獲設備的訪問參數信息;f)獲取共享內存大小和實時利用率信息;g)從數據包捕獲設備中讀取數據包并返回當前數據包指針;h)標志數據包為已處理狀態,移動當前指針到下一數據包;i)取消共享內存到流量監測分析程序的內存映射;j)關閉數據包捕獲設備;k)流量監測分析程序向底層數據包獲取驅動模塊注銷信息。
利用上述API接口提供的功能,可以實現在用戶空間開發高性能的流量監測分析程序。在滿足高性能和便捷性的同時,相比基于內核模塊的實現方法,應用此方法在用戶空間實現流量監測程序可大大降低對程序開發人員的技能要求,使得開發人員可集中更多的精力在數據的統計分析和顯示部分,有利于縮短軟件開發時間,降低開發成本。
3實驗結果分析
為了驗證本文所提出方法,在本章中對比了Libpcap工具、基于內核模塊的數據包捕獲方法和基于多空間內存共享的數據包捕獲方法的性能。具體配置如表2所示。
需要特別強調的是,按照上述配置在高速鏈路環境下接收數據包,PCI總線等硬件因素不會成為性能瓶頸所在。實驗中使用的PC服務器為x86體系結構,支持64位PCIX總線,主頻133 MHz,計算可得PCIX總線帶寬為133 MHz×64 bit =8 925 478 912 bps=8.312 5 Gbps。由于在實驗過程中PCIX總線上未安裝除千兆網卡以外的任何設備,可以確定PCIX總線帶寬不可能成為數據包捕獲的性能瓶頸。同時,采用的Linux版本支持NAPI并在實驗過程中開啟對NAPI的支持。
3.1數據包捕獲能力測試
實驗1對比Libpcap工具、基于內核模塊的數據包捕獲方法和基于多空間內存共享的數據包捕獲方法的數據包捕獲能力。
數據包處理部分僅實現對捕獲到的每一個數據包遞增包計數器,計算數據包捕獲速率;流量發生器SmartBits 2000的千兆端口發送64 Byte大小的單播MAC幀,產生不同速率的測試流量。
圖3顯示了隨數據包發送速率的增加三種捕獲方法的數據包捕獲能力變化曲線。由此可知,基于多空間內存共享的數據包捕獲方法性能最優,其在千兆鏈路環境下能夠線速捕獲所有數據包;基于內核模塊的數據包捕獲方法性能稍差,最高數據包捕獲速率接近千兆線速達到148.4萬pps,丟包率約為0.27%;Libpcap工具的性能最低,最高數據包捕獲速率僅為18.5萬pps,丟包率約為87.5%。Libpcap工具的性能與另外兩種捕獲方法相比有如此大的差距,分析其原因主要在于Libpcap工具沒有實現數據包內存零拷貝,大部分系統資源都浪費在中斷開銷、將數據包從內核空間移動到用戶空間的系統調用和內存拷貝過程中。
3.2數據包深度分析能力測試
實驗2對比基于Libpcap工具、基于內核模塊的數據包捕獲方法和基于多空間內存共享的數據包捕獲方法的數據包深度分析能力。在實驗1中僅比較了三種方法的數據包捕獲能力,而沒有考慮到不同捕獲方法的數據包捕獲效率。數據包捕獲只是實現流量監測分析的前提步驟,在捕獲完成后還必須對捕獲得到的數據包作大量的分析處理和相關統計等,這些都會消耗大量的計算資源。若數據包捕獲工具在執行數據包捕獲的過程中消耗了大部分系統資源,而僅剩余小部分的系統資源用于對捕獲到的數據包的分析處理和相關統計,結果可想而知,這就會造成一方面是系統花費了大量的開銷用于數據包捕獲;另一方面是底層捕獲到的數據包由于上層處理程序的處理能力不足而被丟棄,導致系統浪費大量的資源作無用功,無法真正提高流量監測分析程序的性能。因此,在比較數據包捕獲工具的性能時必須考慮到數據包捕獲效率指標。實驗2修改了實驗1中的數據包處理部分,增加處理每個數據包的計算量,模擬實際流量監測分析程序中復雜的數據包統計和分析處理運算。由于不同流量監測分析程序的數據包處理計算復雜度不盡相同,為了使實驗結果更易于比較,采用查看數據包的前20 Byte;并將每個字節視為一無符號整形數,依次執行連加、連減和連乘運算(連乘運算中忽略零值),模擬流量監測分析程序的數據包處理運算。
使用修改后的程序重新測試對比了基于三種捕獲方法的數據包深度分析能力,流量發生器所發送的數據包同實驗1。圖 4顯示了隨數據包發送速率的增加三種捕獲方法的數據包深度分析能力變化曲線。在三種捕獲方法中依然是基于多空間內存共享的數據包捕獲方法的數據包處理能力最優,能夠線速捕獲并處理全部數據包;基于內核模塊的數據包捕獲方法的性能居中,最高數據包捕獲速率達到110.7萬pps,丟包率約為25%;Libpcap 工具性能最低,最高數據包捕獲速率僅為18.5萬pps,丟包率約為87.5%。
基于多空間內存共享的數據包捕獲方法與基于內核模塊的數據包捕獲方法相比,在性能上提升了約34.4%。分析其原因在于前者必須在內核空間中為接收到的每一個數據包動態分配、釋放臨時緩存,產生大量的內存管理相關的系統調用開銷。由于所有的數據包都進入位于操作系統內核的TCP/IP協議棧,為所有待處理的數據包排隊、維護數據包處理隊列的開銷也是相當可觀的。
圖5比較了實驗1和2中基于內核模塊的數據包捕獲方法的處理能力。從圖中發現處理能力下降較大,原因在于高速網絡鏈路環境下基于內核模塊的數據包捕獲方法會占用較多的系統資源,造成與上層數據包處理程序相互競爭資源,從而影響數據包的深度分析能力。
綜上所述,采用共享內存與NAPI技術相結合的方式,基于多空間內存共享的數據包捕獲方法能夠將數據包深度分析能力提升約34.4%,其完全能夠滿足千兆鏈路的監測需求,在千兆最小包情況下的處理能力也可以達到線速148.8萬pps。
4結束語
本文針對高速網絡鏈路的監測需求,提出了一種基于多空間內存共享的數據包捕獲方法。與已有方法相比其具有如下優勢:a)共享內存的實現消除了為每個數據包臨時分配、釋放緩存的系統調用開銷,實現數據包內存零拷貝;b)提供可以在用戶空間調用的高性能數據包訪問接口,使得在用戶空間開發高性能的流量監測分析程序成為可能;c)基于通用硬件平臺和開源軟件的實現方式可以大大降低開發成本,有利于開拓市場。從實驗結果上看,該方法能夠大幅提高數據包捕獲性能,達到千兆甚至更高速率下網絡鏈路的監測需求。
參考文獻:
[1]DEGIOANNI L, BALDI M, RISSO F,et al.Profiling and optimization of softwarebased networkanalysis applications[C]//Proc of the 15th Symposium on Computer Architecture and High Performance Computing.Sao Paulo:[s.n.],2003.
[2]Agilent Corporation[EB/OL].[2007-0312].http://www.home.agilent.com.
[3]InMon Corporation[EB/OL].[2007-0312].http://www.inmon.com.
[4]University of Waikato.The DAG project[EB/OL]. [2007-0312]. http://www.endace.com/.
[5]SHAH N.Understanding network processor[D].Berkeley: University of California, 2001.
[6]Ethereal Inc[EB/OL].(2007-03-01).[2007-0312]. http://www.ethereal.com.
[7]Wireshark Inc[EB/OL].(2007-01-28).[2007-0312]. http://www.wireshark.org.
[8]The Tcpdump Group[EB/OL]. (2006-0919).[2007-0312].http://www.tcpdump.org.
[9]WELTE H.The netfilter framework in Linux 2.4[C]//Proc of Linux Kongress 2000.Erlanger:[s.n.],2000. [10]DERI L.Improving passive packet capture:beyond device polling[C]//Proc of SANE 2004.Amsterdam,Netherlands:[s.n.],2004.
[11]ALEXEY K.NAPIhowto.txt[EB/OL].(2002-0216).[2007-0312].http://lwn.net/2002/0321/a/napihowto.php3.
[12]MOGUL J C,REMAKRISHNAN K K.Eliminating receive livelock in an interruptdriven kernel[J].ACM Transactions on Computer System,1997,15(3):217-252.
[13]RIZZO L.Device polling support for FreeBSD[C]//Proc of BSDCon Europe Conference.Brighton:[s.n.],2001.
[14]Open Source Technology Group [EB/OL]. [2007-0312].http://sourceforge.net/projects/e1000/.
[15]DERI L.Passively monitoring networks at gigabit speeds using commodity hardware and open source software[C]//Proc of PAM. San Diego, California:[s.n.],2003.
[16]DEGIOANNI L,VARENNI G.Introducing scalability in network measurement:toward 10Gbps with commodity hardware[C]//Proc of IMC’04.Silicy:[s.n.],2004:25-27.
“本文中所涉及到的圖表、注解、公式等內容請以PDF格式閱讀原文”