令瑞林 李峻峰 李 丹
(清華大學計算機科學與技術系 北京 100084)
基于多核平臺的高速網絡流量實時捕獲方法
令瑞林 李峻峰 李 丹
(清華大學計算機科學與技術系 北京 100084)
(lrl14@mails.tsinghua.edu.cn)
隨著互聯網上應用的豐富和網絡帶寬的增長,帶來的安全問題也與日劇增,除了傳統的垃圾郵件、病毒傳播、DDoS攻擊外,還出現了新型的隱蔽性強的攻擊方式.網絡探針工具是一種部署在局域網出口處的旁路設備,能夠收集當前進出網關的全部流量并進行分析,而網絡探針工具中最重要的模塊就是數據包的捕獲.傳統的Linux網絡協議棧在捕獲數據包時有諸多性能瓶頸,無法滿足高速網絡環境的要求.介紹了基于零拷貝、多核并行化等技術的多種新型的數據包捕獲引擎,并基于Intel DPDK平臺設計并實現了一個可擴展的數據包捕獲系統,它能夠利用接收端擴展(receiver-side scaling, RSS)技術實現多核并行化的數據包捕獲、模塊化的上層處理流程.除此之外,還討論了更有效、更公平的將數據包分發到不同的接收隊列所應使用的Hash函數.經過初步的實驗驗證,該系統能夠實現接近線速的收包并且多個CPU核心間實現負載均衡.
數據包捕獲;接收端擴展;多核;DPDK平臺;Hash函數
隨著通信技術的發展,互聯網早已成為了全球資源的共享平臺,實現了人與機、人與人、物與物之間的互聯.互聯網的繁榮發展與其標準化的基因是分不開的,任何想要接入互聯網的設備都需要遵循既定的通訊協議.但也正是這種標準化和通用化導致了其安全性受到威脅.攻擊者通過標準的協議與被攻擊對象交互,實現其竊取信息或破壞系統等目的.除此以外,網絡病毒借助電子郵件附件、網頁文件下載等手段進行傳播,不僅會導致網絡傳輸效率降低、網絡中斷,甚至還會竊取用戶的核心數據,大量的垃圾郵件也會影響個人和企業的正常生活和工作.根據調查,87%以上的病毒通過電子郵件進入企業,危害極其普遍、嚴重[1].
網絡數據包的實時采集和分析,對于網絡的服務商和管理方有十分重要的安全意義.網絡的服務商能夠通過分析當前網絡上的流量來預測網絡的流量情況,同時這些數據能夠用于優化網絡配置,配置出最優的路由路徑和負載均衡策略[2].對于網絡的管理者,能夠通過采集的數據分析出入網絡的流量的安全態勢,及時發現可能對內網信息系統造成破壞的攻擊行為以及從內向外發生的數據泄露.但網絡流量的實時采集是個有挑戰性的問題,尤其是在網絡帶寬不斷增長的背景下,高性能的數據包采集系統需要在有限的時間內完整地收集和處理網絡上產生的大量數據,并完成可能的管理或控制,而高速網絡環境中流量分析系統的基礎是能夠無丟失地捕獲網絡數據包[2].
隨著服務器網卡速率的提升,目前服務器中通常配有10 Gbps的網卡,因此,數據包捕獲系統的實現不僅有傳統的基于硬件方案,也有基于軟件的方案.使用定制化的硬件設備進行數據包捕獲的方案優點是,性能相對較好,能夠支持高帶寬的網絡;但缺點則是系統的功能模塊相對固定、擴展性差,且硬件成本很高.因此,低成本且擴展性好的軟件實現就成了大多數網絡服務商選擇的解決方案.在高速網絡環境下(如大型IDC、云數據中心等),傳輸的數據量比一般傳統的局域網高出幾個數量級.這就要求基于軟件的數據包捕獲系統能夠達到高效性和完整性的要求,能及時處理高速網絡上的數據.
Linux網絡協議棧是處理網絡數據包的典型系統,它包含了從物理層直到應用層的全過程.其處理流程為:首先驅動向上層模塊發出請求,通知協議棧有數據到達;然后協議棧通過系統調用對數據包的網絡層協議數據進行處理,它會將網卡驅動的接收緩沖隊列中的數據包拷貝到操作系統的接收隊列中;接著調用傳輸層的接收函數進行傳輸層的數據處理.如果此時系統接收隊列中沒有需要的數據包時,操作系統會讓當前的處理進程進入休眠狀態,等待系統接收隊列中到達新的數據包,當休眠的處理進程被系統喚醒,它會從接收隊列獲得所需的數據包,處理完畢以后通過調用read函數,將數據包從內核緩沖區拷貝到用戶態的應用緩沖區[3].在這個過程中,數據包首先從網卡驅動的緩沖隊列拷貝到協議棧的接收隊列,再從協議棧的接收隊列拷貝到應用程序的內存空間.數據包從下向上的過程中進行了2次拷貝及多層系統調用處理.
從上述分析可以看出,由于Linux內核協議棧的主要目標是實現通用的網絡服務,所以在設計上存在固有的缺陷,大量的中斷和數據包的多次拷貝都是普遍認為的“病因”所在.針對這些問題,研究人員們設計了許多高性能的數據包捕獲引擎,這些引擎在技術上有許多共通之處,如零拷貝、批處理等.但這些引擎的功能較為單一,不能直接用來開發復雜的網絡功能設備.
1.1 Linux網絡協議棧的報文處理
Linux內核協議棧對數據包處理過程主要分為3個步驟[4]:1)DMA傳輸及網卡中斷設置[5];2)中斷處理程序拷貝數據包;3)netfilter進行路由判決,其上的鉤子函數處理數據包,并將數據包交給傳輸層的函數處理.
通過分析研究者們發現,Linux內核協議棧在數據包的收發過程中進行了2次數據包的內存拷貝,這2次拷貝操作的時間開銷占了整個處理過程時間開銷的65%,此外層間傳遞的系統調用時間也占據了8%~10%[6].
數據拷貝會造成巨大時間開銷的原因主要有2方面:
1) 數據拷貝過程需要占用總線,而設備中的總線帶寬資源是有限的,同時,數據的拷貝都是按照一定的位寬度逐字(32位操作系統中字寬為4 B)進行的,大量的數據拷貝操作將消耗大量的CPU周期;
2) cache命中率和CPU訪問cache的效率將會下降.拷貝操作的過程中,原cache里緩存的cache行將被待拷貝的數據沖掉,而逐字拷貝會產生頻繁的cache行替換,從而造成cache命中率降低,可以看出協議棧處理數據包時的拷貝操作是協議棧性能的主要瓶頸[7].
NAPI(New API)是Linux2.6內核之后采用的一種提高數據包處理性能的新技術,其核心就是使用中斷和輪詢組合收包,如圖1所示.NAPI的假設場景是,一旦網卡開始接收到數據包,數據包就會以高頻率到達,換言之,就是針對一直有數據包到達的網絡環境做了優化,主要改進[8]為:網卡在接收到第1個數據包時將觸發硬件中斷,中斷處理函數會將該網卡加入到設備輪詢表中,同時,為了防止后續到達的數據包觸發頻繁的硬件中斷,需要設置該中斷使之不再接收中斷請求(Rx IRQ);隨后,操作系統會觸發一個軟中斷,軟中斷的處理函數將對輪詢表上的設備進行輪詢,檢查是否有數據包到達并處理;直到本次處理的CPU時間片用盡或者數據包的處理過程結束,網卡才重新設置中斷屏蔽位開中斷接收中斷請求.

Fig. 1 Methodology of NAPI圖1 NAPI原理圖
然而,隨著網卡緩存空間和CPU處理能力的增強,在千兆速率的網絡上使用NAPI技術己經能夠很好地支持各類數據包的處理.但是隨著萬兆網卡的普及和主干網絡帶寬的提升,數據包捕獲及處理能力的瓶頸就轉移到網卡驅動以及內核協議棧的處理能力上,頻繁的軟中斷處理和數據包拷貝操作會大量消耗CPU資源,這些資源消耗在萬兆網絡環境下顯得尤為明顯.如何高效地處理數據包內容,減少系統不必要的資源開銷,優化數據包處理過程中的CPU利用率,成為數據包捕獲技術的主要研究方向[8].
1.2 性能瓶頸識別與分析
由1.1節的分析可知,僅有NAPI技術是不足以完成在高速網絡上的流量捕獲這樣一個具有挑戰性的任務,這是因為Linux協議棧體系結構中的固有缺陷降低了性能.經過大量的代碼分析和性能測試,研究者們已經確定協議棧的5個主要問題[9-12]:
1) 針對單個數據包級別的資源分配和釋放.每當一個數據包到達網卡,系統就會分配一個分組描述符用于存儲數據包的信息和頭部,直到分組傳送到用戶態空間,其描述符才被釋放.分配和釋放描述符的過程在高達14.88 Mpps的環境下是一個顯著的時間上的開銷.此外,sk_buff龐大的數據結構中的大部分信息對于大多數網絡任務而言都是無用的.如文獻[9]中指出,每個分組的sk_buff的分配消耗近1 200個CPU周期,而釋放需要1 100個周期.事實上,對于一個大小為64 B的分組,sk_buff相關操作消耗了整個接收處理的CPU利用率的63%[9].
2) 流量的串行訪問.現代網卡包括多個硬件的接收端擴展(receiver-side scaling, RSS)隊列可以將分組按照五元組散列函數分配到不同的接收隊列.使用這種技術,分組的捕獲過程可以被并行化,因為每個RSS隊列可以映射到一個特定的CPU核,并且可以對應相應的NAPI線程.這樣整個捕獲過程就可以做到并行化.但是問題出現在之上的層次,Linux中的協議棧在網絡層和傳輸層需要分析合并的所有數據包,如圖2所示.由此引起了降低系統性能的2個問題:①所有流量在一個單一模塊中被處理,產生性能瓶頸;②用戶進程不能夠從一個單一的RSS隊列接收消息.這就造成了上層應用無法利用現代硬件的并行化處理能力,這種在用戶態分配流量先后序列的過程降低了系統的性能,丟失了驅動層面所獲得的加速.此外,從不同隊列合并的流量可能會產生額外的亂序分組[13].

Fig. 2 Bottleneck in standard Linux network stack when using multi-queue圖2 使用多隊列的傳統Linux協議棧中的瓶頸
3) 從驅動到用戶態的數據拷貝.從網卡收到數據包到應用取走數據的一次DMA過程中,存在至少2次數據包的復制:從驅動中DMA的訪問內存到內核的數據包緩存,以及從內核數據包緩存到應用程序.一次復制操作的消耗取決于數據包長度,一般為500~2 000個CPU周期之間[11].上述過程中更糟糕的是,當數據包很小時,逐包復制的效率更加低下,這是由于每個操作恒定的開銷引起的.
4) 內核到用戶空間的上下文切換.從應用程序的視角來看,它需要執行系統調用來接收每個分組.每個系統調用包含一次從用戶態到內核態的上下文切換,隨之而來的是大量的CPU時間消耗.在每個數據包上執行系統調用時產生的上下文切換可能消耗近1 000個CPU周期[11].
5) 缺少內存本地化.例如,當接收一個64 B分組時,cache未命中造成了額外13.8%的CPU周期的消耗[12].另外,在一個基于NUMA的系統中,內存訪問的時間取決于訪問的存儲節點.因此,cache未命中在跨內存塊訪問環境下會產生更大的內存訪問延遲,從而導致性能下降.
由于當前的協議棧和應用程序中都不能很好地利用網卡和CPU硬件的新特性.我們總結了目前高性能報文捕獲引擎中常用的提高捕獲效率的技術,這些技術能夠克服之前架構的性能限制.
1) 預分配和重用內存資源.這種技術包括:開始分組接收之前,預先分配好將要到達的數據包所需的內存空間用來存儲數據和元數據(分組描述符).尤其體現在,在加載網卡驅動程序時就分配好N個描述符隊列(每個硬件隊列和設備一個).需要注意的是這會在驅動程序加載時造成一些額外的時間開銷,但是減少了為每個數據包分配內存空間的開銷.同樣,當一個數據包被傳送到用戶空間,其對應的描述符也不會被釋放,而是重新用于存儲新到達的分組.得益于這一策略,在每個數據包分配/釋放所產生的性能瓶頸得到了消除.此外,也可以通過簡化sk_buff的數據結構來減少內存開銷.
2) 數據包采用并行直接通道傳遞.為了解決序列化的訪問流量,需要建立從RSS隊列到應用之間的直接并行數據通道.這種技術通過特定的RSS隊列、特定的CPU核和應用三者的綁定來實現性能的提升.這個架構也增加了性能的可擴展性,因為新的并行數據通道可以通過在驅動層面增加RSS隊列的數量和CPU核來實現.這種技術也存在一些缺點:①數據包可能會亂序地到達用戶態,從而影響某些應用的性能[13];②RSS使用Hash函數在每個接收隊列間分配流量[14-15].當不同核的數據包間沒有相互關聯時,它們可以被獨立地分析,但如果同一條流的往返數據包被分配到不同的CPU核上時,就會造成低效的跨核訪問.
3) 內存映射.使用這種方法,應用程序的內存區域可以映射到內核態的內存區域,應用能夠在沒有中間副本的情況下讀寫這片內存區域.用這種方式我們可以使應用直接訪問網卡的DMA內存區域,這種技術被稱為零拷貝.但零拷貝也存在潛在的安全問題,向應用暴露出網卡環形隊列和寄存器會影響系統的安全性和穩定性[11].

Fig. 3 PF RING scheme圖3 PF RING機制
4) 數據包的批處理.為了避免對每個數據包的重復操作的開銷,可以使用對數據包的批量處理.這個策略將數據包劃分為組,按組分配緩沖區,將它們一起復制到內核/用戶內存.運用這種技術減少了系統調用以及隨之而來的上下文切換的次數;同時也減少了拷貝的次數,從而減少了平攤到處理和復制每個數據包的開銷.但由于分組必須等到一個批次已滿或定時器期滿才會遞交給上層[16],批處理技術的主要問題是延遲抖動以及接收報文時間戳誤差的增加.
5) 親和性與預取.由于程序運行的局部性原理,為進程分配的內存必須與正在執行它的處理器操作的內存塊一致,這種技術被稱為內存的親和性.還有一些其他的考慮因素是CPU的中斷親和性.CPU親和性是一種技術,它允許進程或線程在指定的處理器核心上運行.在內核與驅動層面,軟件和硬件中斷可以用同樣的方法指定具體的CPU核或處理器來處理,稱為中斷親和力.每當一個線程希望訪問所接收的數據,如果先前這些數據已被分配到相同CPU核的中斷處理程序接收,則它們在本地cache能夠更容易被訪問到.這項策略可以與先前所述的內存局部性共同優化數據的接收過程,充分利用系統的可用資源.
本節中,我們列舉了4個包捕獲引擎,即PF-RING[17],PacketShader[9],Netmap[10]和PFQ[18],它們在數據包捕獲方面相對于Linux原生方法取得了顯著的性能提升.對于每一種收包引擎,我們描述了它的系統架構、使用的何種加速技術、為開發應用提供的API,以及提供的附加功能.
1) PF-RING
PF-RING是一個基于Intel 10 Gbps網卡的數據包捕獲引擎框架.這個引擎實現了內存預分配,并在其處理數據包的整個過程中通過分配RX和PF-RING環形隊列實現重用內存.PF-RING也允許建立從硬件到用戶進程并行接收隊列,即它允許為每個接收隊列分配一個CPU核,可以根據NUMA節點進行內存分配,允許內存親和技術的開發.不同于其他方案,PF-RING實現了完全的零拷貝,它將用戶內存空間映射到驅動的內存空間,使用戶的應用可以直接訪問網卡的寄存器和數據.通過這樣的方式,避免了在內核對數據包緩存,減少了數據包的拷貝次數.但是,如前面所指出的,這種技術的代價是用戶的應用程序可能出現的對于PF-RING API的不正確使用(其明確地不允許不正確的存儲器存取),并造成系統的崩潰.在其余的方案中,直接訪問網卡是有保護機制的.PF-RING的工作過程如圖3所示.一些NAPI的步驟都被換成了零拷貝技術.
2) PacketShader
PacketShader(PS)是開發能夠線速工作的軟件路由器的基礎,是一套新的高度優化流量捕獲的引擎.PS也完全適用于任何涉及采集和處理數據包的一般任務.它使用了內存預分配和重用,具體而言,PS分配了2個內存區域:①用于存儲分組數據;②用于存儲其元數據.每個緩存單元具有對應于一個包的固定大小的區域.用于存放分組數據的每個單元的大小對齊于2 048 B,對應于與標準以太網MTU相鄰的最小2的冪.元數據結構除去了對于許多網絡任務不必要的字段,從208 B壓縮至只有8 B(96%).此外,PS實現了內存映射,使應用直接訪問內核數據包緩沖區,避免了不必要的數據拷貝.在這方面,PS的作者強調了其引擎的性能在支持NUMA數據放置的優勢.同樣,PS在用戶層面也提供了并行化的分組處理,同時能夠隨著CPU核的數目和隊列數目實現擴展性.為了減少每個包的處理開銷,PS在用戶層面實現了批處理.每次批處理請求都將巨大的數據包緩沖區映射到連續內存區域,應用可以從該區域訪問驅動并復制數據.為了減少cache未命中的次數,改進的設備驅動程序會預取當前分組的下一個分組(包括分組數據和分組描述符),如圖4所示:

Fig. 4 PacketShader RX scheme圖4 PacketShader收包機制
3) Netmap
Netmap和PacketShader體系結構的特征有很多相同之處.即在初始化階段預分配大小固定的緩存空間(也為2 048 B),批處理和并行直接數據通路.它也實現了內存映射技術,以允許用戶的應用程序直接訪問內核包緩存(到NIC直接訪問被保護起來)中簡化和優化過的元數據結構,這種簡化的元數據叫做Netmap ring,其結構體包含環的大小,一個指向緩存的指針(當前數據包),緩存中收到的包的數目,或緩存中可用的空槽的數目.在接收和發送時會分別設置有關狀態位、內存中包緩存的偏移值以及元數據信息數組;同時還包含每個數據包的一個存儲位置,包括該數據包的長度、在緩存中的索引和一些標志位.需要注意的是每個RSS隊列,接收和發送都可以使用Netmap ring實現并行化的直接數據通道.
4) PFQ
PFQ是一種新型的數據包捕獲引擎,它允許在應用進程中進行并行化的包捕獲.PFQ的方法與以前的研究不同,區別于完全繞過NAPI的中斷方案或使用DMA映射內存和內核包緩存到用戶空間等對驅動進行重大修改的方案,PFQ允許同時使用改進的和舊式的體系結構.它依照NAPI的方式抓取數據包,但實現了2個新的修改后的內核包緩沖器,使得數據包在進入協議棧之前先進入緩存.首先,PFQ使用了額外的用于存放數據包副本的緩存以防止內核包緩沖器滿了,這些包的拷貝操作是批處理完成的,這樣降低了并發度并增強了訪問內存的局部性.這種修改融合了批處理技術和內存親和力技術.第2點修改,PFQ在內核層大量地使用了并行化,所有的功能都能夠在多個系統核心上并行執行.PFQ實現了一個新的中間層,叫做數據包分流塊(packet steering block),它位于用戶態和批處理隊列之間,向應用提供了一些有趣的功能,它在多個接收的socket間分配流量.這些流量分配由內存映射技術實現,避免了socket和用戶空間之間額外的拷貝.PSB允許捕獲線程將數據包分發給多個socket,從而一個socket可以從不同的包捕獲線程接收流量.這個特性避免了使用并行數據通道的缺點,即不同的流或會話的數據包必須由不同的應用處理而不能共享.
3.1 DPDK數據平面開發套件
Intel DPDK是一套可用于開發數據平面應用庫,定義了控制平面和數據平面功能分離的一種方式[19].控制平面的性能要求小于數據平面的性能要求,數據平面根據控制平面提供的配置來轉發流量.Intel DPDK允許用戶空間的進程使用DPDK所提供的庫直接訪問網卡而無需經過內核.從性能提升的角度來看,有實驗表明在吞吐量方面,相比于Linux內核有10~11倍的性能提升.在本文中,我們采用Intel DPDK作為底層庫.

Fig. 7 A rte_mempool with associated rte_ring圖7 rte_mempool及其關聯的rte_ring
3.1.1 隊列管理
為了管理任何類型的隊列,librte ring提供了rte_ring的環形隊列結構,如圖5所示.這種結構具有以下性質:環形隊列的大小固定,遵循先進先出的原則實現無鎖,支持單/多生產者/消費者的排隊場景.此外,它能夠指定進出隊列的數據包的個數.環形隊列被實現為一張存儲了指向存儲對象的指針的一張表,每個消費者和生產者各使用一對指針指向當前隊列的頭部和尾部進行訪問控制.相比于普通的用長度不限的雙鏈表實現的隊列,rte_ring有2個很大的優勢:1)它是存取時使用無鎖定機制比保護寫這種結構快得多;2)由于在表中保存的是指向數據的指針,減少了由于突發操作和大量數據傳輸導致的cache未命中次數.

Fig. 5 The rte_ring structure圖5 rte_ring結構示意圖[14]
3.1.2 內存管理
EAL可以提供物理內存的映射[14],它會創建一個叫做RTE memseg的描述符的表來將地址上不連續的物理內存映射為可連續訪問的.然后將這些內存分成多個內存區域,如圖6所示.這些區域是構建于DPDK庫之上的應用進一步使用內存的基本單元.Librte_mempool提供的對象之一是rte_mempool.

Fig. 6 Distribution of physical memory into segments and zones for further use圖6 物理的大頁內存被分為更小的單元
這種結構是用rte_ring來存儲可通過唯一的名稱確定的固定大小的對象池,如圖7所示.為了提高性能,可以在對象之間添加一個特定填充塊,用來“只裝載在內存不同的通道和等級的每個對象的起始部分”[14].例如,在3層轉發和網絡數據包的流分類中可以使用這種優化,因為對于數據包的處理只需要依賴第1個64 B即可[14].雖然無鎖環狀結構可以被用來實現控制訪問的目的,但多個CPU核心訪問ring的成本可能很高.為了避免在ring處產生瓶頸,每個CPU核心都對rte內存池保有本地高速緩存.當cache全滿或者全空時,會使用批量操作與rte內存池的ring自由交換對象.以此方式,CPU核心可以對多次使用的對象進行快速訪問從而減輕對ring結構的壓力.
3.1.3 緩存管理
任何能夠傳輸網絡數據的應用都可以使用librte mbuf的庫提供的緩沖區rte_mbuf.這些緩沖會在應用程序實際運行之前就被創建出來并存放在內存池中.在運行時,應用現在可以通過指定mbuf來指定訪問某一個mempool.釋放一個rte_mbuf只是將回到它來自的mempool[14].為了容納更大的數據包的元數據,可以將多個rte_mbuf鏈接在一起.如圖8所示,每一個rte_mbuf都包含元數據以及數據包的一部分頭部信息.它還包含一個指向下一個rte_mbuf的指針以實現緩沖區鏈.
需要強調的是,Intel DPDK通過創建環境抽象層(EAL)提供的所有庫,以及訪問包括硬件和存儲器空間的底層資源這些僅僅提供了基本的操作.它不提供類似3層轉發等復雜的功能,使用防火墻或類似TCP或UDP協議,則需要網絡協議棧的全面支持.表1將第2節所述的引擎和DPDK在各種技術方面進行了比較.

Fig. 8 One packet as chain of rte_mbufs圖8 使用多個rte_mbuf存放一個數據包

Table 1 Comparison of High-Performance Packet Capture Engine表1 多種高性能包捕獲方案的比較
Notes: D stands for Driver; K stands for Kernel; K-U stands for Kernel-User interface; √ stands for support; × stands for unsupport.
3.2 系統總體設計
一個完整的數據包捕獲系統不僅僅是包捕獲的引擎,而是涉及具體場景、數據包輸入、存儲、處理等多方面的完整的系統框架,在框架之上有多種功能模塊.一個通用的數據包捕獲系統框架,我們首先按照系統的功能需求,確定系統實現所需的如下目標:
1) 可維護性.數據包捕獲系統應該能夠方便地修改可能存在的bug,補充新的功能模塊以及對性能進行優化,維護的過程中對于原有部分的影響要盡可能的小.
2) 可靠性.數據包捕獲系統是基于其上的各種安全分析模塊的基礎,捕獲系統需要足夠可靠,能夠應對各種非標準格式的數據包.同時不同的功能模塊的故障要進行隔離,不能因為某個模塊的失效而影響正常模塊的工作,擴大了故障的范圍.
3) 靈活性.數據包捕獲系統應在不同的網絡環境中使用不同的配置模式,具體的運行情況依賴于不同的配置.
4) 可重用性.由于數據包捕獲系統中不同部分對數據包格式處理的流程相似性很大,各種業務分析流程也有相似之處,所以在設計時需要盡量將常用的功能模塊化.
系統輸入為來自網絡的數據包,包含各種不同協議和層次的數據包;系統輸出為流量的統計信息和通過提取內容字段等獲得的信息.除了提取數據包的凈荷之外,最原始的通信報文也需要保存下來.系統各個部分描述如下3方面:
1) 接收數據包模塊.負責完成數據包的接收和分類,然后對數據包的各層頭部進行基本的解封裝和提取,剝離頭部后剩下的各層協議的凈荷傳入下一級回調函數.
2) 數據包處理模塊.每一種報文解析的應用就是一種數據包處理模塊,例如解析HTTP協議的HTTP模塊、處理DNS的DNS模塊等,各種不同的模塊需要有統一設計和接口,內部解析邏輯各有區別.本模塊主要用于不同協議的內容進行分析,比如HTTP的請求及響應頭部等.
3) 報文持久化模塊.將原始數據包及解析后的協議相關的結果寫回數據庫,作為分析結果供其他組件使用.

Fig. 10 Packet address transfer process in queue圖10 包地址在隊列中的傳遞流程
3.3 數據包接收
數據包接收使用了Intel的高性能數據包捕獲引擎DPDK.DPDK的應用在初始化階段就分配好所需使用的大頁內存,這些大頁內存被組織成內存池、環形緩存等多種操作單元,供應用程序使用.除了存放數據包的大頁內存,程序初始化時還需要指定程序運行所需的核數等參數.如圖9所示,由于DPDK中采用輪詢代替了中斷進行收包,所以收包模式為程序主動調用rte_eth_rx_burst()接口去接收一定數目的數據包,這就要求我們封裝收包接口,將其封裝為收到一個數據包作為一個事件,進而觸發一系列掛于其上的回調函數對數據包進行處理,從而實現插件式的數據包分析.
由于DPDK是批量接收數據包的,所以在調用一次rx_burst()后,要循環地對每一個接收到的數據包進行處理.我們創建一個local_main()函數作為在每個核上一直運行的主線程,在其中調用rx_burst()并循環處理每個數據包的包頭,根據包頭來調用不同的回調函數進行處理,在處理結束前是阻塞的.

Fig. 9 Workflow of packet capture using DPDK圖9 使用DPDK捕獲數據包的流程
3.4 內存管理子模塊
整個系統中有2個全局的大頁內存池,分別是TCP流報文內存池和普通報文內存池,這里以普通報文內存池為例詳述其實現.為了減少報文復制帶來的性能開銷,我們將報文體存儲在內存池中,而在隊列間僅傳遞報文的地址.報文在接收、處理到銷毀的過程中涉及3個隊列,隊列傳遞流程如圖10所示:
網卡接收到報文后,校驗和正常的報文將進入內存池,其地址將進入待解析隊列,插件調度模塊將調用不同的插件對報文進行解析,解析結果及屬性將填入報文的元數據結構中,處理結束后地址統一進入刪除隊列進行刪除.每個隊列的實現是一個環形緩沖隊列,使用了DPDK中提供的rte_ring來存放地址,實現讀寫無鎖.具體方式如圖11所示:

Fig. 11 Packet buffer queue圖11 報文緩存隊列
3.5 插件式數據包處理
插件式數據包處理是數據包捕獲系統實現擴展能力的關鍵,為了解決報文格式間的差別以及不同處理邏輯間的差別,數據包的上層處理采用插件式設計.由于目前計算機網絡統一采用TCP/IP協議,這就使得不同數據包的處理和解析有了相同的部分,可以采用相同或近似的方式處理網絡報文的每一層協議封裝.為了解決以上關鍵問題,通用的插件式數據包處理設計如圖12所示.
插件式的報文解析模塊,可以很好地解決報文解析過程中針對不同解析目標的適配靈活性,同時分發機制可以帶來很好的可擴展性.插件式的數據包處理可以實現報文處理插件模塊化.將不同的處理功能按照統一的結構化的模板封裝成具有相同接口的插件類,這些類被編譯為不同的動態鏈接庫在需要調用時加載.增加了系統工作流程的靈活性和可維護性,程序按照配置文件的不同加載不同的插件模塊,同時這種方案也可以實現數據包處理管道化.在程序啟動時加載的配置文件中的#route項可以指定每個插件模塊解析后的結果的下一級插件,或者使用#done表示處理當前插件已經是處理的最后一級(處理完成).例如網絡層解析的下一級處理可能是傳輸層解析,如果傳輸層是TCP協議則下一級模塊有可能是HTTP解析,如果是UDP協議則下一級有可能是DNS解析.
3.6 基于RSS的數據包分發
RSS是將到達網卡的數據包分配到不同隊列中的技術[14].它以可擴展的方式允許每個CPU核獨立訪問不同的網卡隊列來接收分組,這樣同時消除了訪問網卡隊列時鎖的爭奪,允許多個不同CPU核的進程并發訪問不同的隊列.然而,現有的RSS機制中的一個問題是它會將同一個TCP連接映射到不同的網卡隊列,具體而言就是映射的隊列取決于數據包的方向.我們在此提出一種對稱RSS的Hash算法,它會將同一TCP連接中的數據包無論它們是上行還是下行都會映射到同一個網卡隊列.
我們首先描述原始的RSS算法,它使用Toeplitz散列函數[15]基于包頭計算散列值,并通過取模操作來決定哪個接收隊列來存儲分組.RSS可以應用到IP/TCP/UDP報頭中的任何字節范圍,但通常而言,一般會散列{源IP,目的IP,源端口,目的端口,協議}組成的五元組.
算法1. RSS Hash值計算算法(Toeplitz)[15].
輸入: 數據包頭部五元組Input[]、隨機密鑰RSK;
輸出: 數據包頭部五元組的Hash值ret.
①ret=0;
② for eachbinInput[] do
③ ifb==1 then
④ret=(left 32 bit ofRSK); /*與RSK高32位異或*/
⑤ end if
⑥ shiftRSKleft 1 bit; /*RSK整體向左滾動1位*/
⑦ end for
算法1是RSS散列函數的偽代碼.INPUT是由網絡層和傳輸層頭部共同組成的五元組,總共12 B.采用40 B(320 b)的隨機密鑰(RSK)與輸入值混合的種子值.因為RSS算法為了快速處理從而實現在網卡的硬件中,直接修改RSS算法使其支持對稱映射較為困難.但是,RSK是設備驅動程序的一部分,并在驅動程序設置網卡時先裝入內存.我們專注于操縱RSK使得Hash函數允許對稱映射.對稱流映射需要產生相同的RSS散列值,即使源和目的IP以及端口號被顛倒.
Hash(srcIP,dstIP,srcPort,dstPort,RSK)=
Hash(dstIP,srcIP,dstPort,srcPort,RSK),
(1)
式(1)是對稱RSS隊列映射的基本條件.我們需要找到條件滿足式(1).我們觀察到,不是每個位的RSK都用于獲取散列值.例如給定一個輸入位,只有32位的RSK用于異或運算.也就是說,對于n位INPUT,只有(n-1)+32位RSK用于生成Hash值.如果INPUT大于或等于290位,RSK將循環到第1位.所以對于INPUT中的特定位,對應于RSK的范圍是固定的.因此,我們可以導出用于計算IPv4/TCP(或UDP)數據包散列值的RSK的位范圍對應關系.例如,INPUT的第1個字節(前8位)對應RSK的前39位;第2個輸入字節(從第9~16位)對應RSK中第9~47位的范圍.通過這種方式,我們計算得到了表2中不同INPUT每個位所對應的RSK的范圍.
設RSK[A:B]表示RSK中從第A位到第B位間的密鑰值.

Table 2 Associated RSK Range When Computing Packet Header Hash Value
使用表2和式(1)我們可以得出式(2).式(2)需要對應于數據包中源和目的IP地址以及源和目標端口范圍的RSK位采用相同的值.如果RSK位范圍滿足此條件,對于2個方向的TCP數據包的RSS Hash值將是相同的.

(2)
進一步將式(2)中的重疊區域拆分后可得到以下3個等式,即式(3):
1)RSK[1:15]=RSK[17:31]=
RSK[33:47]=RSK[49:63]=
RSK[65:79]=RSK[81:95]=
RSK[97:111]=RSK[113:127];
2)RSK[16]=RSK[48]=
RSK[80]=RSK[96]=RSK[112];
3)RSK[32]=RSK[64].
(3)
我們可以求得一個滿足式(3)的RSK的一個示例,如圖13所示:

0xDA650xDB650xDA650xDB650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA650xDA65

Fig. 13 A symmetric Hash satisfied RSK value
圖13 一個滿足對稱Hash要求的RSK密鑰值
我們在Linux上實現了這個高性能的包捕獲系統,它由5 000行左右的C語言代碼和300行左右的Python語言代碼組成,使用了DPDK 2.0版本作為包捕獲引擎,使用MySQL 5.6作為存儲持久化結果的數據庫.我們在CentOS 6.5上部署了整套系統,服務器采用Dell PowerEdge R720,CPU為Intel Xeon E5-2609,內存64 GB(其中大頁內存分配16 GB),硬盤1 TB機械硬盤,網卡為支持DPDK的e1000和Intel 82599兩種型號.我們將系統部署在一個局域網的出口處,以旁路模式部署,如圖14所示,我們在內網中部署了10臺發送數據的服務器,在網關的另一側部署了一臺接收數據的服務器,路由器會將出入局域網的雙向流量進行鏡像后發送給分析系統,分析系統在收到數據包后存儲在本地.在測試中,我們使用DPDK-Pktgen[19]發包工具在10臺發送服務器上向接收服務器發送IP報文,接收端服務器收到這些報文后會直接丟棄.Pktgen能夠產生不同長度的報文,也可以調節發送流量的大小,可以滿足實驗的需要.我們還配置了普通Linux系統網卡驅動和PF-RING上基于libpcap的報文捕獲系統,用來驗證系統在數據包捕獲及多核性能擴展方面的優勢.

Fig. 14 Experiment setting圖14 實驗環境
我們首先測試了在不同輸入流量的條件下,不同引擎的捕獲性能及其多核性能擴展能力.具體實驗方法是分別使用2個CPU核和6個CPU核捕獲報文,測試基于原生Linux,PF-RING和DPDK三種平臺上包捕獲系統的性能.輸入流量的大小從1 Gbps一直增長到10 Gbps,測試的數據包長均為250 B.從圖15中我們可以看到,雙核環境下的原生Linux在輸入流量為1 Gbps左右時就已經有10%左右的丟包,而6核環境下的原生Linux在輸入流量為2 Gbps時也開始產生丟包.PF-RING平臺下的捕獲情況略好于原生Linux,但能夠承受的流量負載也十分有限;而基于DPDK的捕獲系統在雙核環境下運行時就已經取得了不錯的性能,直到輸入流量為3 Gbps時才產生丟包,好于6核環境下的原生Linux與PF-RING引擎;而運行在6核環境下基于DPDK的包捕獲引擎直到輸入流量為7 Gbps時才開始丟包,事實上在實際測試中,該系統在8核環境下就可以達到線速.同時我們還可以看到,基于DPDK的包捕獲系統在不同CPU核數環境下運行時的性能有很大的差異,而原生Linux和PF-RING則不具有這樣的特性,這充分說明了系統性能的可擴展性.

Fig. 15 Traffic loss rate with the increase of traffic load圖15 隨流量增大的丟包率

Fig. 16 Traffic loss rate with the increase of packet size圖16 隨包長增大的丟包率
為了驗證系統在不同數據包長度下的性能,我們將輸入流量固定為5 Gbps,觀察當數據包長度由64 B向1 500 B變化時的丟包率.如圖16所示,在輸入小數據包時,除6核環境下的DPDK包捕獲系統外,丟包率都超過了50%;隨著數據包長度的增大,所有平臺下的丟包率都開始下降,而6核環境下的包捕獲系統的丟包率一直為0.可見我們的系統在處理小包時具有明顯的性能優勢.
為了驗證在使用RSS Hash進行數據包分發的有效性,我們統一開啟8個核來處理流量,在不同流量下監控每個核心的CPU利用率.圖17是在不同流量輸入下CPU每個核的利用率情況.橫軸代表CPU核的編號,縱軸代表每個核的利用率,我們采集流量分別為1 Gbps,3 Gbps,6 Gbps和9 Gbps情況下每個核的利用情況.很顯然隨著流量的增大,每個核的利用率也在上升,但不同核間的利用率基本保持齊平.需要注意的是,DPDK采用的是輪詢模式收包,在此過程中CPU的利用率始終為100%,為了限制其收包線程占用的CPU資源,我們用Sleep()函數為收包線程加入了固定的睡眠時間,Sleep()中參數越大,進程所占用的CPU上界就越低,但過大的睡眠時間會導致丟包.需要注意的是,圖17中的CPU利用率是在不丟包的情況下測量的臨界值.

Fig. 17 CPU per-core usage under different traffic load圖17 不同流量情況下的每核CPU利用率
本文圍繞高速網絡環境下的數據包捕獲問題,首先分析了傳統網絡協議棧在數據包捕獲方面存在的問題,其次圍繞目前的多種捕獲引擎分析了各自優劣,而后基于DPDK設計并實現了一個高性能可擴展的包捕獲系統,最后對系統的性能做了實驗驗證.數據包捕獲只是網絡流量分析的第1步,要分析網絡上通信的所有會話,必須要對TCP連接進行恢復,以及對各種基于TCP的協議應用層協議進行內容分析,這將是我們下一步的工作.
[1]China Internet Network Information Center. The 34th China Internet Development Statistics Report[R]. Beijing: China Internet Network Information Center, 2014 (in Chinese)
(中國互聯網絡信息中心. 第34次中國互聯網絡發展狀況統計報告[R]. 北京: 中國互聯網絡信息中心, 2014)
[2]Liu Baochen. Research and implementation of a high-performance packet-capture system[D]. Shanghai: Shanghai Jiao Tong University, 2013 (in Chinese)
(劉寶辰. 高性能數據包捕獲系統的研究與實現[D]. 上海: 上海交通大學, 2013)
[3]Risso F, Degioanni L. An architecture for high performance network analysis[C] //Proc of the 6th IEEE Symp on Computers and Communications. Piscataway, NJ: IEEE, 2001: 686-693
[4]McCanne S, Jacobson V. The BSD packet Filter: A new architecture for user-level packet capture[C] //Proc of the 1993 Winter USENIX Technical Conf. Berkeley, CA: USENIX Association, 1993: 120-130
[5]Heberlein L T. A network security monitor[C] //Proc of the IEEE Symp on Research in Security and Privacy. Piscataway, NJ: IEEE, 1990: 296-304
[6]Nie Yuanming, Qiu Ping. Network Information Security Technology[M]. Beijing: Science Press, 2001 (in Chinese)(聶元銘, 丘平. 網絡信息安全技術[M]. 北京: 科學出版社, 2001)
[7]William S. Network Security Element—Application and Standard[M]. Beijing: The People’s Posts and Telecomm-unications Press, 2000
[8]Zhang Nan. Design and implementation of general purpose data collection system based on IP network[D]. Beijing: Beijing University of Posts and Telecommunications, 2014 (in Chinese)
(張楠. 基于IP網絡的通用數據采集系統的設計與實現[D]. 北京: 北京郵電大學, 2014)
[9]Han S, Jang K, Park K S, et al. PacketShader: A GPU-accelerated software router[J]. ACM SIGCOMM Computer Communication Review, 2010, 40(4): 195-206
[10]Rizzo L. Netmap: A novel framework for fast packet I/O[C] //Proc of the 21st USENIX Security Symp (USENIX Security’12). Berkeley, CA: USENIX Association, 2012: 101-112
[11]Liao Guangdeng, Znu X, Bnuyan L. A new server I/O architecture for high speed networks[C] //Proc of Symp on High-Performance Computer Architecture. Piscataway, NJ: IEEE, 2011: 255-265
[12]Papadogiannakis A, Vasiliadis G, Antoniades D. Improving the performance of passive network monitoring applications with memory locality enhancements[J]. Computer Communications, 2012, 35(1): 129-140
[13]Wu Wenji, DeMar P, Crawford M. Why can some advanced Ethernet NICs cause packet reordering?[J]. IEEE Communications Letters, 2011, 15(2): 253-255
[14]Intel. Intel DPDK: Programmers Guide[OL]. [2016-08-24]. http://dpdk.org/doc/guides/prog_guide
[15]Mircosoft. Microsoft: Receive side scaling[OL]. [2016-08-24]. http://msdn.microsoft.com/en-us/library/windows/hardware/ff567236(v=vs.85).aspx
[16]Moreno V, Santiago del Rio P M, Ramos J, et al. Batch to the future: Analyzing timestamp accuracy of high-performance packet I/O engines[J]. IEEE Communications Letters, 2012, 16(11): 1888-1891
[17]Rizzo L, Deri L, Cardigliano A. 10 Gbit/s line rate packet processing using? Commodity hardware: Survey and new proposals[OL]. [2016-09-20]. http://luca.ntop.org/10g.pdf?
[18]Bonelli N, Di Pietro A, Giordano S, et al. On multi-gigabit packet capturing with multi-core commodity hardware[C] //Proc of Int Conf on Passive and Active Network Measurement. Berlin: Springer, 2012: 64-73
[19]Intel DPDK. Data Plane Development Kit Project Page[OL]. [2016-09-12]. http://www.dpdk.org,June 2014


Li Junfeng, born in 1992. PhD candidate. Received his bachelor degree from Xian Jiao Tong University in 2015. PhD candidate in Tsinghua University. His main research interests include on network coding and network performance optimization.

Li Dan, born in 1981. Associate professor. Received his MEn degree and PhD degree from Tsinghua University in 2005 and 2007 respectively, both in computer science. His main research interests include cloud computing, datacenter network and SDN.
Realtime Capture of High-Speed Traffic on Multi-Core Platform
Ling Ruilin, Li Junfeng, and Li Dan
(DepartmentofComputerScienceandTechnology,TsinghuaUniversity,Beijing100084)
With the development of Internet application and the increase of network bandwidth, security issues become increasingly serious. In addition to the spread of the virus, spams and DDoS attacks, there have been lots of strongly hidden attack methods. Network probe tools which are deployed as a bypass device at the gateway of the intranet, can collect all the traffic of the current network and analyze them. The most important module of the network probe is packet capture. In Linux network protocol stack, there are many performance bottlenecks in the procedure of packets processing which cannot meet the demand of high speed network environment. In this paper, we introduce several new packet capture engines based on zero-copy and multi-core technology. Further, we design and implement a scalable high performance packet capture framework based on Intel DPDK, which uses RSS (receiver-side scaling) to make packet capture parallelization and customize the packet processing. Additionally, this paper also discusses more effective and fair Hash function by which data packet can be deliveried to different receiving queues. In evaluation, we can see that the system can capture and process the packets in nearly line-speed and balance the load between CPU cores.
packet capture; receiver-side scaling (RSS); multi-core; DPDK platform; Hash function
in, born in 1992.
his bachelor degree in Beijing University of Posts and Telecommunications. Master candidate in Tsinghua University. His main research interests include data center network, cloud computing and high-performance networking.
2016-11-10;
2017-03-09
國家“八六三”高技術研究發展計劃基金項目(2015AA01A705,2015AA016102);國家自然科學基金優秀青年科學基金項目(61522205) This work was supported by the National High Technology Research and Development Program of China (863 Program) (2015AA01A705, 2015AA016102) and the National Natural Science Foundation of China for Excellent Young Scientists (61522205).
TP391