專利名稱:Linux系統(tǒng)上以太網(wǎng)卡快速捕包的方法
技術(shù)領(lǐng)域:
本發(fā)明涉及計算機通信領(lǐng)域,具體涉及一種Linux系統(tǒng)上以太網(wǎng)卡快速捕包的方法。2、 技術(shù)背景目前局域網(wǎng)應(yīng)用十分廣泛,以太網(wǎng)是局域網(wǎng)的一種,也是局域網(wǎng)的主流方式。在以太網(wǎng)上 可傳輸ip包實現(xiàn)和tcp/ip互聯(lián)網(wǎng)的連接。而在網(wǎng)絡(luò)管理、網(wǎng)絡(luò)檢測中,需要對傳輸?shù)木W(wǎng)絡(luò)數(shù) 據(jù)包進行捕獲,進而分析網(wǎng)絡(luò)流量、對指定源地址和目的地址的通信進行監(jiān)控和入侵檢測等。 為了提高監(jiān)控速度等性能,需要對數(shù)據(jù)包完全或者盡可能完全的捕獲。在Linux系統(tǒng)上,傳統(tǒng)的以太網(wǎng)卡驅(qū)動和內(nèi)核的網(wǎng)絡(luò)處理棧受到以太網(wǎng)卡中斷調(diào)度、數(shù)據(jù) 包在內(nèi)核中和由內(nèi)核向用戶區(qū)復制次數(shù)過多的影響,收包速度還不十分理想。目前Linux系統(tǒng) 上的鏈路包通用的捕獲方式是通過PK一SOCKET類型的套接字(socket)進行數(shù)據(jù)包接收的,它 是在Linux協(xié)議棧的底層的netif—receive—skb函數(shù)中將剛收自網(wǎng)卡的鏈路包復制一份,而使 用該類型的套接字接收數(shù)據(jù)到用戶區(qū)時還需要復制一次。此外目前Linux系統(tǒng)內(nèi)核的網(wǎng)絡(luò)協(xié)議 棧兼顧速度和普遍通用性,它接收網(wǎng)卡設(shè)備數(shù)據(jù)包的一些方式,影響了對網(wǎng)卡設(shè)備進行捕包速 度,具體表現(xiàn)在(1) 非NAPI方式是完全由網(wǎng)卡中斷觸發(fā)對數(shù)據(jù)包的接收,在高頻率來包時網(wǎng)卡中斷處理 調(diào)度需要較大的cpu資源消耗。(2) NAPI方式結(jié)合網(wǎng)卡中斷觸發(fā)和主動查詢接收,雖然大大減少了中斷調(diào)度次數(shù),但是每 次輪詢有固定時間(1個系統(tǒng)時鐘周期腿絲)限制,超出該時間值將結(jié)束接收,這樣難以保證 輪詢結(jié)束后不丟包。(3) 無論是非NAPI方式還是NAPI方式,對于每一個接收到DMA接收緩存區(qū)的數(shù)據(jù)包,都 需要申請緩存空間,不能重復使用,而申請和釋放緩存空間雖然由系統(tǒng)高效的內(nèi)存管理模塊完 成,但其計算量也不可忽視。(4) 無論是非NAPI方式還是NAPI方式,接收到的數(shù)據(jù)包緩存隊列長度十分有限,當數(shù)據(jù) 包處理速度不均勻時很容易緩存區(qū)滿而丟包,而如果在用戶區(qū)增加擴大緩存,還需要做一次拷 貝。由于Linux系統(tǒng)的傳統(tǒng)捕包方式在速度、性能上的局限性,需要一種更快更優(yōu)的捕包方法。 3、發(fā)明內(nèi)容為了提高使用以太網(wǎng)卡捕包的收包率和性能,本發(fā)明提供了一種應(yīng)用在Linux系統(tǒng)上的以太網(wǎng)卡快速捕包的方法。本發(fā)明提供的以太網(wǎng)卡快速捕包方法的步驟為-(1) 在以太網(wǎng)卡驅(qū)動中,在模塊加載時注冊一個混雜設(shè)備(m/'sce//aA7eous ofev/'ce),記為misc—dev,定義該設(shè)備的open, release,腿ap, ioctl操作函數(shù),其中醒ap函數(shù)將用于將指定 網(wǎng)卡的環(huán)形接收描述符緩存區(qū)和數(shù)據(jù)包接收緩存區(qū)映射給用戶區(qū)的程序,ioctl函數(shù)用于為用戶 區(qū)程序提供移動指定網(wǎng)卡的環(huán)形接收描述符緩存區(qū)接收尾指針以使網(wǎng)卡能夠持續(xù)收包的功能。 相應(yīng)的,在模塊卸載時要注銷該混雜設(shè)備。(2) 在以太網(wǎng)卡驅(qū)動中,在模塊加載時定義一個全局結(jié)構(gòu)變量,記為g—map—dev,用于保 存該系列(驅(qū)動)的所有網(wǎng)卡設(shè)備的環(huán)形接收描述符個數(shù)及其緩存區(qū)虛擬地址、數(shù)據(jù)包接收緩 存區(qū)的虛擬地址,在混雜設(shè)備misc—dev的mmap函數(shù)中使用該全局變量g一map—dev獲取緩存區(qū) 虛擬地址轉(zhuǎn)換為物理地址并向用戶區(qū)映射。相應(yīng)的,在模塊卸載時要釋放該全局結(jié)構(gòu)變量。(3) 在以太網(wǎng)卡驅(qū)動中,使用pci—alloc—consistent函數(shù)分配接收描述符緩存區(qū)和數(shù)據(jù) 包接收緩存區(qū),這種方式使緩存區(qū)可以同時從網(wǎng)卡和CPU兩個方向訪問。這兩個緩存區(qū)對于網(wǎng) 卡是可直接內(nèi)存訪問(Direct Memory Access)方式傳輸?shù)?。同時把緩存區(qū)的虛擬地址保存到 步驟(2)中說明的全局結(jié)構(gòu)變量g—map—dev中。相應(yīng)的,釋放緩存區(qū)的時候(停止網(wǎng)卡、重置 網(wǎng)卡)使用pci—free—consistent函數(shù)。(4) 在用戶區(qū),定義一系列鏈表結(jié)構(gòu)的緩存區(qū),以實現(xiàn)數(shù)據(jù)包緩存的重復使用和減少包處 理線程之間取包時的鎖沖突。緩存區(qū)分為兩種組別包接收緩存組和包處理緩存組。對于有N個網(wǎng)卡設(shè)備捕包和M個包 處理緩存組的配置,將定義((2 + M)xN + (4 x M))個緩存區(qū),即N個接收緩存組和M個包處 理緩存組,每個接收緩存組包含2+M個緩存區(qū),每個包處理緩存組包含4個緩存區(qū)。其中的每 個緩存區(qū)是以鏈表結(jié)構(gòu)組織,每個鏈表元素為一個固定大小的數(shù)據(jù)包緩存及其狀態(tài)(實際接收 的數(shù)據(jù)包長度)。每個接收緩存組由2個空閑緩存區(qū)組成的兩級空閑緩存區(qū)和M個接收緩存區(qū)組成,空閑緩 存區(qū)用于收集存放已處理過的釋放的包緩存準備重復使用,接收緩存區(qū)用于存放接收的數(shù)據(jù)包, 每個網(wǎng)卡接收的數(shù)據(jù)包按照均分方式或者按照數(shù)據(jù)包內(nèi)容分為M類,投放到M個接收緩存區(qū)中。每個包處理緩存組由2個待處理緩存區(qū)組成的兩級待處理緩存區(qū)、1個處理中緩存區(qū)、1 個已處理緩存區(qū)組成。(5) 在用戶區(qū),對每個捕包網(wǎng)卡啟動一個線程捕包,稱為捕包線程。(6) 捕包及包緩存流通流程為捕包程序向外提供pktcap—open, pktcap—close, pktcap—get_onepkt—block, pktcap一get—onepkt—noblock, pktcap—free—onepkt接口函數(shù),對于N個捕包網(wǎng)卡、M個包處理緩存組和K個包緩存的配置,在pkt cap—open函數(shù)中,首先申請K 個包緩存,每個包緩存大于以太網(wǎng)包最大值(一般為1500)即可,將K個包緩存平均分布在N 個一級空閑緩存區(qū)中。然后啟動N個捕包線程,每個線程將使用一個網(wǎng)卡和一個包接收緩存組。 在每個捕包線程運行開始時,關(guān)閉所使用的網(wǎng)卡的中斷,調(diào)用混雜設(shè)備misc—dev的mmap函數(shù) 將對應(yīng)網(wǎng)卡的DMA接收描述符緩存區(qū)和DMA包接收緩存區(qū)的物理地址映射到用戶區(qū),調(diào)用混雜 設(shè)備的ioctl函數(shù)獲取和設(shè)置網(wǎng)卡的接收狀態(tài)(對于intel prol00和prol000系列網(wǎng)卡,是獲 取DMA接收描述符首指針位置、設(shè)置DMA接收描述符尾指針位置),然后進入數(shù)據(jù)包査詢接收 循環(huán)(7)首先査詢當前DMA接收描述符的狀態(tài)字,判斷該包是否接收完成,[l]若否則睡眠一 段時間,睡眠時間長短根據(jù)DMA接收描述符個數(shù)和網(wǎng)卡帶寬而定,對于1000Mb帶寬,4096個接 收描述符的情況,為保證睡眠期間不會因為DMA接收緩存區(qū)滿而丟包,睡眠時間t—slc印應(yīng)小 于以滿帶寬接收4096/2個最小包的時間,即t—sle印:(64x8x4096/2)/ (10,1048ins,其中 64為以太網(wǎng)包的最小長度,單位字節(jié)。[2]若當前包己接收完成,則將數(shù)據(jù)包復制接收到接收緩 存區(qū)。首先判斷一級空閑緩存區(qū)有無緩存,[2. l]有則將網(wǎng)卡DMA接收緩存中數(shù)據(jù)包內(nèi)容復制到 一級空閑緩存區(qū)的第一個緩存,然后根據(jù)均分原則或者按照數(shù)據(jù)包內(nèi)容對該包進行分類,均分 原則是對于本網(wǎng)卡,每次將數(shù)據(jù)包到M個接收緩存區(qū)的1個,循環(huán)投放從第1個到第M個,而 根據(jù)數(shù)據(jù)包內(nèi)容分類的方法,可以對ip包的源地址、目的地址、源端口和目的端口等進行hash 運算再取M的模,得到序號index, 0《index《M-1,再投放到第index+l個接收緩存區(qū)中。然 后判斷該接收緩存區(qū)的緩存?zhèn)€數(shù),大于MM—RECVED個則將該緩存區(qū)的數(shù)據(jù)包轉(zhuǎn)移到第index+l 個二級待處理緩存區(qū),轉(zhuǎn)移前后需要鎖定和解鎖二級待處理緩存區(qū)。[2.2]若一級空閑緩存區(qū)無 緩存,則將二級空閑緩存區(qū)鎖定并將其緩存遷移到一級空閑緩存區(qū)再解鎖,[2.2.1]若從二級空 閑.緩存區(qū)獲取的緩存?zhèn)€數(shù)小于等于NUM一FREEBUF—L2 (NUM—FREEBUF—L2為(T數(shù)十)個則為了防止 空閑緩存區(qū)迅速消耗完又繼續(xù)査詢二級緩存區(qū)形成頻繁鎖定二級緩存區(qū)的惡性循環(huán),睡眠一段 時間,時間的數(shù)量級要小于前述的t—sle印的,大概為lufl0us。睡眠結(jié)束后若一級空閑緩存 區(qū)的緩存不為空,則復制、分類和投放數(shù)據(jù)包,否則不進行復制,即丟棄該包,但設(shè)置該包狀 態(tài)為己接收,重新循環(huán)收包。[2. 2. 2]若從二級空閑緩存區(qū)獲取的緩存?zhèn)€數(shù)大于NUM—FREEBUF一L2, 則復制、分類和投放數(shù)據(jù)包,設(shè)置該包狀態(tài)為已接收,重新循環(huán)收包。上述為捕包線程的收包流程,所使用的用戶區(qū)數(shù)據(jù)包緩存的輸入為二級空閑緩存區(qū),輸出 為一級待處理緩存區(qū)。而數(shù)據(jù)包從二級待處理緩存區(qū)流通到二級空閑緩存區(qū)的流程是每個包處理線程調(diào)用pktcap—get—onepkt_block或者pktcap—get—onepkt_noblock接.口函 數(shù)獲取一個數(shù)據(jù)包,調(diào)用pktcap—free—on印kt釋放數(shù)據(jù)包。其中pktcap—get—onepkt一block函數(shù)為阻塞式獲取,當有數(shù)據(jù)包可用時將立即返回,否則將利用Linux線程的條件變量 pthread—cond—wait等待,直到有捕包線程將已接收數(shù)據(jù)包從接收緩存區(qū)轉(zhuǎn)移到二級待處理緩存 區(qū)并設(shè)置條件變量環(huán)形處理線程。pktcap_get—on印kt一noblock接口函數(shù)為非阻塞式獲取,有數(shù) 據(jù)包則返回數(shù)據(jù)包指針,否則立即返回空指針。每個包處理緩存組雖然可以給多個包處理線程 使用,但是為了減少線程并發(fā)鎖定緩存區(qū)而提高效率,最好只由一個包處理線程使用。pktcap—get—onepkt—block或者pktcap—get一o卿kt—noblock接口函數(shù)將使數(shù)據(jù)包緩存將 從一級待處理緩存區(qū)轉(zhuǎn)移到處理中緩存區(qū)。首先判斷一級待處理緩存區(qū)是否為空,若不為空, 則將一個數(shù)據(jù)包從一級待處理緩存區(qū)轉(zhuǎn)移到處理中緩存區(qū),然后將該數(shù)據(jù)包地址以指針方式返 回。若一級待處理緩存區(qū)為空,則鎖定二級待處理緩存區(qū)并將其數(shù)據(jù)包轉(zhuǎn)移到一級緩存區(qū)再解 鎖,然后從一級待處理緩存區(qū)取一個數(shù)據(jù)包轉(zhuǎn)移到處理中緩存區(qū)并返回該數(shù)據(jù)包指針。包處理線程處理完某個數(shù)據(jù)包后將使用pktcap—free—on印kt接口函數(shù)釋放數(shù)據(jù)包,在函數(shù) 參數(shù)中傳遞該數(shù)據(jù)包的指針。pktcap—free—on印kt接口函數(shù)將使數(shù)據(jù)包緩存從處理中緩存區(qū)轉(zhuǎn) 移到—級空閑緩存區(qū)。首先鎖定處理中緩存區(qū),將數(shù)據(jù)包從處理中緩存區(qū)中脫離,然后解鎖處 理中緩存區(qū),鎖定已處理緩存區(qū),將數(shù)據(jù)包轉(zhuǎn)移到已處理緩存區(qū),然后判斷已處理緩存區(qū)中數(shù) 據(jù)包緩存?zhèn)€數(shù)是否大于NUM—MIN—FREE,大于則鎖定二級空閑緩存區(qū),將己處理緩存區(qū)中所有數(shù)據(jù) 包緩存轉(zhuǎn)移到二級空閑緩存區(qū)再解鎖這兩個緩存區(qū)并返回,否則解鎖已處理緩存區(qū)并返回。本發(fā)明的有益效果是,將以太網(wǎng)卡DMA接收緩存區(qū)映射到用戶區(qū),減少數(shù)據(jù)包到達用戶區(qū) 以及用戶程序的拷貝次數(shù);每個網(wǎng)卡啟動一個線程捕包可實現(xiàn)同時對多網(wǎng)卡進行捕包;關(guān)閉中 斷主動查詢接收,減少中斷處理調(diào)度開銷;定義重復使用的緩存及其管理,減少緩存申請和釋 放的開銷,減少捕包線程、包處理線程之間使用緩存的鎖沖突頻率及其造成的系統(tǒng)資源消耗和 效率下降,實現(xiàn)對以太網(wǎng)數(shù)據(jù)包包括在其上傳輸?shù)膇p包的快速的捕獲。4
圖1為本發(fā)明的快速捕包程序結(jié)構(gòu)示意圖; 圖2為本發(fā)明的包接收緩存組部分的緩存轉(zhuǎn)移流圖; 圖3為本發(fā)明的包處理緩存組部分的緩存轉(zhuǎn)移流圖; 圖4為本發(fā)明的捕包線程流程圖。
具體實施方式
本發(fā)明提供的一種以太網(wǎng)卡快速捕包的方法,具體步驟為1) 將以太網(wǎng)卡DMA接收緩存區(qū)映射到用戶區(qū),減少數(shù)據(jù)包在內(nèi)核區(qū)、內(nèi)核到用戶區(qū)的拷貝 次數(shù)。2) 注冊一個混雜設(shè)備用于將以太網(wǎng)卡DMA接收緩存區(qū)映射到用戶區(qū)和提供對網(wǎng)卡的接收狀態(tài)的設(shè)置和控制。3) 關(guān)閉中斷使用主動査詢方式接收數(shù)據(jù)包,減少中斷處理的調(diào)度帶來的系統(tǒng)開銷。4) 對每個網(wǎng)卡啟動一個線程進行捕包,從而同時對多個網(wǎng)卡進行快速捕包。5) 在程序啟動時分配好指定數(shù)量的數(shù)據(jù)包緩存,實現(xiàn)對數(shù)據(jù)包的緩存,降低包處理速度不 均勻造成的丟包率。6) 在捕包程序運行中重復使用數(shù)據(jù)包緩存,不再每次對每個數(shù)據(jù)包重新申請緩存空間,減 少使用系統(tǒng)分配緩存空間和釋放緩存空間帶來的消耗。7) 對數(shù)據(jù)包緩存區(qū)做了分組,提供對數(shù)據(jù)包的分類,降低線程之間對緩存區(qū)鎖定訪問的沖 突頻率,具體緩存分組和流通方式為-8) 緩存區(qū)分為兩種組別包接收緩存組和包處理緩存組,對于有N個網(wǎng)卡設(shè)備捕包和M 個包處理緩存組的配置,將定義((2 + M)xN + (4 x M))個緩存區(qū),即N個接收緩存組和M個 包處理緩存組,每個接收緩存組包含2+M個緩存區(qū),每個包處理緩存組包含4個緩存區(qū),其中 的每個緩存區(qū)是以鏈表結(jié)構(gòu)組織,每個鏈表元素為一個固定大小的數(shù)據(jù)包緩存及其實際接收的 數(shù)據(jù)包長度。9) 每個捕包線程使用一個包接收緩存組,由2個緩存區(qū)組成的兩級空閑緩存區(qū)和M個接收 緩存區(qū)組成,收包時從一個包接收緩存組的2級空閑緩存區(qū)取得空閑數(shù)據(jù)包緩存,首先從二級 緩存轉(zhuǎn)移全部的緩存到一級緩存上,之后每次只從一級緩存獲取空閑數(shù)據(jù)包緩存直到用完再從 二級空閑緩存轉(zhuǎn)移到一級緩存,對于映射到用戶區(qū)的網(wǎng)卡DMA數(shù)據(jù)接收緩存區(qū)中接收完畢的數(shù) 據(jù)包,拷貝到一個空閑數(shù)據(jù)包緩存上之后,對其按M個類劃分,分類的方法是均分為M組或按 數(shù)據(jù)包內(nèi)容分類,分類完成后投放到一個接收緩存區(qū)上,每個接收緩存區(qū)對應(yīng)一個類,當接收 緩存區(qū)中的數(shù)據(jù)包個數(shù)達到一定量時,轉(zhuǎn)移到對應(yīng)包處理緩存組的第二級待處理緩存區(qū)上。9、根據(jù)權(quán)利要求7所述的Linux系統(tǒng)上以太網(wǎng)卡快速捕包的方法,其特征在于每個包處理緩存 組由2個緩存區(qū)組成的兩級待處理緩存區(qū)、1個處理中緩存區(qū)和1個己處理緩存區(qū)組成,供一個 或多個包處理線程使用, 一個包處理緩存組對應(yīng)一個或多個包處理線程,包處理線程獲取包的 過程是首先從第二級待處理包緩存區(qū)將所有數(shù)據(jù)包轉(zhuǎn)移到第一級待處理包緩存區(qū),之后每次 從第一級待處理包緩存區(qū)取包,每次取一個,且將該數(shù)據(jù)包從第一級待處理包緩存轉(zhuǎn)移到處理 中緩存區(qū),包處理線程處理完一個包后需要把該數(shù)據(jù)包從處理中緩存區(qū)轉(zhuǎn)移到已處理緩存區(qū), 再判斷已處理緩存區(qū)中數(shù)據(jù)包緩存數(shù)目是否達到一定量,達到則將已處理緩存區(qū)中所有數(shù)據(jù)包 緩存轉(zhuǎn)移到一個包接收緩存組的第二級空閑緩存區(qū)上,對于有多個包接收組的情況,循環(huán)投遞 實現(xiàn)平均供給,這樣實現(xiàn)了數(shù)據(jù)包緩存的循環(huán)使用。
權(quán)利要求
1、Linux系統(tǒng)上以太網(wǎng)卡快速捕包的方法,其特征在于,是將以太網(wǎng)卡DMA接收緩存區(qū)映射到用戶區(qū),通過減少數(shù)據(jù)包到達用戶區(qū)以及用戶程序的拷貝次數(shù)和每個網(wǎng)卡啟動一個線程捕包來實現(xiàn)同時對多網(wǎng)卡進行捕包,還通過關(guān)閉中斷主動查詢接收,減少中斷處理調(diào)度開銷,定義重復使用的緩存及其管理,減少緩存申請和釋放的開銷并減少捕包線程和包處理線程之間訪問緩存的沖突,實現(xiàn)對以太網(wǎng)數(shù)據(jù)包包括在其上傳輸?shù)膇p包的快速的捕獲,方法步驟如下(1)在以太網(wǎng)卡驅(qū)動中,在模塊加載時注冊一個混雜設(shè)備miscellaneous device,記為misc_dev,定義該設(shè)備的open,release,mmap,ioctl操作函數(shù),其中mmap函數(shù)將用于將指定網(wǎng)卡的環(huán)形接收描述符緩存區(qū)和數(shù)據(jù)包接收緩存區(qū)映射給用戶區(qū)的程序,ioctl函數(shù)用于為用戶區(qū)程序提供移動指定網(wǎng)卡的環(huán)形接收描述符緩存區(qū)接收尾指針以使網(wǎng)卡能夠持續(xù)收包的功能,相應(yīng)的,在模塊卸載時要注銷該混雜設(shè)備;(2)在以太網(wǎng)卡驅(qū)動中,在模塊加載時定義一個全局結(jié)構(gòu)變量,記為g_map_dev,用于保存該系列的所有網(wǎng)卡設(shè)備的環(huán)形接收描述符個數(shù)及其緩存區(qū)虛擬地址、數(shù)據(jù)包接收緩存區(qū)的虛擬地址,在混雜設(shè)備misc_dev的mmap函數(shù)中使用該全局變量g_map_dev獲取緩存區(qū)虛擬地址轉(zhuǎn)換為物理地址并向用戶區(qū)映射,相應(yīng)的,在模塊卸載時要釋放該全局結(jié)構(gòu)變量;(3)在以太網(wǎng)卡驅(qū)動中,使用pci_alloc_consistent函數(shù)分配接收描述符緩存區(qū)和數(shù)據(jù)包接收緩存區(qū),這種方式使緩存區(qū)同時從網(wǎng)卡和CPU兩個方向訪問;這兩個緩存區(qū)對于網(wǎng)卡直接內(nèi)存訪問Direct Memory Access方式傳輸?shù)?,同時把緩存區(qū)的虛擬地址保存到步驟(2)中說明的全局結(jié)構(gòu)變量g_map_dev中,相應(yīng)的,釋放緩存區(qū)的時候,停止網(wǎng)卡或重置網(wǎng)卡使用pci_free_consistent函數(shù);(4)在用戶區(qū),定義一系列鏈表結(jié)構(gòu)的緩存區(qū),以實現(xiàn)數(shù)據(jù)包緩存的重復使用和減少包處理線程之間取包時的鎖沖突;緩存區(qū)分為兩種組別包接收緩存組和包處理緩存組,對于有N個網(wǎng)卡設(shè)備捕包和M個包處理緩存組的配置,將定義((2+M)×N+(4×M))個緩存區(qū),即N個接收緩存組和M個包處理緩存組,每個接收緩存組包含2+M個緩存區(qū),每個包處理緩存組包含4個緩存區(qū),其中的每個緩存區(qū)是以鏈表結(jié)構(gòu)組織,每個鏈表元素為一個固定大小的數(shù)據(jù)包緩存及其實際接收的數(shù)據(jù)包長度;每個接收緩存組由2個空閑緩存區(qū)組成的兩級空閑緩存區(qū)和M個接收緩存區(qū)組成,空閑緩存區(qū)用于收集存放已處理過的釋放的包緩存準備重復使用,接收緩存區(qū)用于存放接收的數(shù)據(jù)包,每個網(wǎng)卡接收的數(shù)據(jù)包按照均分方式或者按照數(shù)據(jù)包內(nèi)容分為M類,投放到M個接收緩存區(qū)中;每個包處理緩存組由2個待處理緩存區(qū)組成的兩級待處理緩存區(qū)、1個處理中緩存區(qū)、1個已處理緩存區(qū)組成;(5)在用戶區(qū),對每個捕包網(wǎng)卡啟動一個線程捕包,稱為捕包線程;(6)捕包及包緩存流通流程為捕包程序向外提供pktcap_open,pktcap_close,pktcap_get_onepkt_block,pktcap_get_onepkt_noblock,pktcap_free_onepkt接口函數(shù),對于N個捕包網(wǎng)卡、M個包處理緩存組和K個包緩存的配置,在pktcap_open函數(shù)中,首先申請K個包緩存,每個包緩存大于以太網(wǎng)包最大值,一般為1500,將K個包緩存平均分布在N個一級空閑緩存區(qū)中,然后啟動N個捕包線程,每個線程將使用一個網(wǎng)卡和一個包接收緩存組,在每個捕包線程運行開始時,關(guān)閉所使用的網(wǎng)卡的中斷,調(diào)用混雜設(shè)備misc_dev的mmap函數(shù)將對應(yīng)網(wǎng)卡的DMA接收描述符緩存區(qū)和DMA包接收緩存區(qū)的物理地址映射到用戶區(qū),調(diào)用混雜設(shè)備的ioctl函數(shù)獲取和設(shè)置網(wǎng)卡的接收狀態(tài),然后進入數(shù)據(jù)包查詢接收循環(huán);對于intel pro100和pro1000系列網(wǎng)卡,是獲取DMA接收描述符首指針位置、設(shè)置DMA接收描述符尾指針位置;(7)首先查詢當前DMA接收描述符的狀態(tài)字,判斷該包是否接收完成,1)若當前包沒有接收完成,則睡眠一段時間,睡眠時間長短根據(jù)DMA接收描述符個數(shù)和網(wǎng)卡帶寬而定,對于1000Mb帶寬,4096個接收描述符的情況,為保證睡眠期間不會因為DMA接收緩存區(qū)滿而丟包,睡眠時間t_sleep應(yīng)小于以滿帶寬接收4096/2個最小包的時間,即t_sleep=(64x8x4096/2)/(10^9)=1048ms,其中64為以太網(wǎng)包的最小長度,單位字節(jié);2)若當前包已接收完成,則將數(shù)據(jù)包復制接收到接收緩存區(qū);首先判斷一級空閑緩存區(qū)有無緩存,如果有則將網(wǎng)卡DMA接收緩存中數(shù)據(jù)包內(nèi)容復制到一級空閑緩存區(qū)的第一個緩存,然后根據(jù)均分原則或者按照數(shù)據(jù)包內(nèi)容對該包進行分類,均分原則是對于本網(wǎng)卡,每次將數(shù)據(jù)包到M個接收緩存區(qū)的1個,循環(huán)投放從第1個到第M個,而根據(jù)數(shù)據(jù)包內(nèi)容分類的方法,對ip包的源地址、目的地址、源端口和目的端口進行hash運算再取M的模,得到序號index,0≤index≤M-1,再投放到第index+1個接收緩存區(qū)中,然后判斷該接收緩存區(qū)的緩存?zhèn)€數(shù),大于NUM_RECVED個則將該緩存區(qū)的數(shù)據(jù)包轉(zhuǎn)移到第index+1個二級待處理緩存區(qū),轉(zhuǎn)移前后需要鎖定和解鎖二級待處理緩存區(qū);若一級空閑緩存區(qū)無緩存,則將二級空閑緩存區(qū)鎖定并將其緩存遷移到一級空閑緩存區(qū)再解鎖;若從二級空閑緩存區(qū)獲取的緩存?zhèn)€數(shù)小于等于NUM_FREEBUF_L2個則為了防止空閑緩存區(qū)迅速消耗完又繼續(xù)查詢二級緩存區(qū)形成頻繁鎖定二級緩存區(qū)的惡性循環(huán),睡眠一段時間,時間的數(shù)量級要小于前述的t_sleep的,大概為1us-10us;睡眠結(jié)束后若一級空閑緩存區(qū)的緩存不為空,則復制、分類和投放數(shù)據(jù)包,否則不進行復制,即丟棄該包,但設(shè)置該包狀態(tài)為已接收,重新循環(huán)收包;若從二級空閑緩存區(qū)獲取的緩存?zhèn)€數(shù)大于NUM_FREEBUF_L2,則復制、分類和投放數(shù)據(jù)包,設(shè)置該包狀態(tài)為已接收,重新循環(huán)收包。
2、根據(jù)權(quán)利要求1所述的方法,其特征在于,所使用的用戶區(qū)數(shù)據(jù)包緩存的輸入為二級空閑緩存區(qū),輸出為二級待處理緩存區(qū),而數(shù)據(jù)包從二級待處理緩存區(qū)流通到二級空閑緩存區(qū)的 流程是每個包處理線程調(diào)用pktcap_get_or^pkt—block或者pktcap_get—on印kt—noblock接 口函數(shù)獲取一個數(shù)據(jù)包,調(diào)用pktcap—free—on印kt釋放數(shù)據(jù)包,其中pktcap—get—on印kt一block 函數(shù)為阻塞式獲取,當有數(shù)據(jù)包用時將立即返回,否則將利用Linux線程的條件變量 pthread一cond—wait等待,直到有捕包線程將己接收數(shù)據(jù)包從接收緩存區(qū)轉(zhuǎn)移到二級待處理緩存 區(qū)并設(shè)置條件變量環(huán)形處理線程;pktcap—get—on印kt一noblock接口函數(shù)為非阻塞式獲取,有數(shù) 據(jù)包則返回數(shù)據(jù)包指針,否則立即返回空指針;每個包處理緩存組雖然給多個包處理線程使用, 但是為了減少線程并發(fā)鎖定緩存區(qū)而提高效率,由一個包處理線程使用。
3、 根據(jù)權(quán)利要求2所述的方法,其特征在于,pktcap—get—on印kt—block或者 pktcap—get—on印kt—noblock接口函數(shù)將使數(shù)據(jù)包緩存將從二級待處理緩存區(qū)轉(zhuǎn)移到處理中緩 存區(qū);首先判斷一級待處理緩存區(qū)是否為空,若不為空,則將一個數(shù)據(jù)包從一級待處理緩存區(qū) 轉(zhuǎn)移到處理中緩存區(qū),然后將該數(shù)據(jù)包地址以指針方式返回;若一級待處理緩存區(qū)為空,則鎖 定二級待處理緩存區(qū)并將其數(shù)據(jù)包轉(zhuǎn)移到一級緩存區(qū)再解鎖,然后從一級待處理緩存區(qū)取 -個 數(shù)據(jù)包轉(zhuǎn)移到處理中緩存區(qū)并返回該數(shù)據(jù)包指針。
4、 根據(jù)權(quán)利要求2所述的方法,其特征在于,包處理線程處理完某個數(shù)據(jù)包后將使用 pktcap—free—on印kt接口函數(shù)釋放數(shù)據(jù)包,在函數(shù)參數(shù)中傳遞該數(shù)據(jù)包的指針; pktcap_free_0ru3pkt接口函數(shù)將使數(shù)據(jù)包緩存從處理中緩存區(qū)轉(zhuǎn)移到二級空閑緩存區(qū);首先鎖 定處理中緩存區(qū),將數(shù)據(jù)包從處理中緩存區(qū)中脫離,然后解鎖處理中緩存區(qū),鎖定已處理緩存 區(qū),將數(shù)據(jù)包轉(zhuǎn)移到己處理緩存區(qū),然后判斷已處理緩存區(qū)中數(shù)據(jù)包緩存?zhèn)€數(shù)是否大于 NUM—MIN一FREE,大于則鎖定二級空閑緩存區(qū),將已處理緩存區(qū)中所有數(shù)據(jù)包緩存轉(zhuǎn)移到二級空閑 緩存區(qū)再解鎖這兩個緩存區(qū)并返回,否則解鎖已處理緩存區(qū)并返回。
全文摘要
本發(fā)明公開一種Linux系統(tǒng)上使用以太網(wǎng)卡快速捕包的方法,該方法是將以太網(wǎng)卡DMA接收緩存區(qū)映射到用戶區(qū),通過減少數(shù)據(jù)包到達用戶區(qū)以及用戶程序的拷貝次數(shù)和每個網(wǎng)卡啟動一個線程捕包來實現(xiàn)同時對多網(wǎng)卡進行捕包,還通過關(guān)閉中斷主動查詢接收,減少中斷處理調(diào)度開銷,定義重復使用的緩存及其管理,減少緩存申請和釋放的開銷并減少捕包線程、包處理線程之間訪問緩存的沖突,實現(xiàn)對以太網(wǎng)數(shù)據(jù)包包括在其上傳輸?shù)膇p包的快速的捕獲。
文檔編號H04L12/26GK101227341SQ200710115379
公開日2008年7月23日 申請日期2007年12月18日 優(yōu)先權(quán)日2007年12月18日
發(fā)明者吳慶民, 張會健, 施培任, 黃景昌 申請人:浪潮電子信息產(chǎn)業(yè)股份有限公司