r>[0046]圖1為本發(fā)明實(shí)施例提供的轉(zhuǎn)發(fā)報文的方法流程圖;
[0047]圖2為本發(fā)明實(shí)施例提供的轉(zhuǎn)發(fā)報文的裝置結(jié)構(gòu)示意圖。
【具體實(shí)施方式】
[0048]為了使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面將結(jié)合附圖對本發(fā)明作進(jìn)一步地詳細(xì)描述,顯然,所描述的實(shí)施例僅僅是本發(fā)明一部分實(shí)施例,而不是全部的實(shí)施例。基于本發(fā)明中的實(shí)施例,本領(lǐng)域普通技術(shù)人員在沒有做出創(chuàng)造性勞動前提下所獲得的所有其它實(shí)施例,都屬于本發(fā)明保護(hù)的范圍。
[0049]圖1,為本發(fā)明實(shí)施例提供的一種轉(zhuǎn)發(fā)報文的方法流程圖。如圖1所示,該方法可包括:
[0050]S101、內(nèi)核態(tài)接收進(jìn)程將網(wǎng)卡接收到的報文存儲于共享內(nèi)存中并通知用戶態(tài)進(jìn)程。
[0051]S102、用戶態(tài)進(jìn)程將共享內(nèi)存的物理地址映射到用戶態(tài)進(jìn)程的虛擬地址后,從共享內(nèi)存中提取報文并對報文進(jìn)行處理。
[0052]S103、用戶態(tài)進(jìn)程將處理后的報文存儲于共享內(nèi)存中并通知內(nèi)核態(tài)發(fā)送進(jìn)程。
[0053]S104、內(nèi)核態(tài)發(fā)送進(jìn)程將處理后的報文通過相應(yīng)的網(wǎng)卡發(fā)送。
[0054]其中,共享內(nèi)存為內(nèi)核態(tài)在初始化時分配的。具體的,內(nèi)核態(tài)在初始化時,可分配一定容量的第一塊連續(xù)的物理內(nèi)存用于構(gòu)建共享內(nèi)存,并可進(jìn)一步地將所分配的連續(xù)的物理內(nèi)存進(jìn)行劃分。例如,內(nèi)核態(tài)在初始化時,可分配大小為16M的連續(xù)物理內(nèi)存用于構(gòu)建共享內(nèi)存,進(jìn)一步地,還可將所分配的16M的連續(xù)物理內(nèi)存分為8K個內(nèi)存塊,這樣可計(jì)算出每個內(nèi)存塊的大小為2K,并將大小為2K的內(nèi)存塊用于存儲內(nèi)核態(tài)接收進(jìn)程接收到的報文。
[0055]內(nèi)核態(tài)在初始化時,除了分配一定容量的連續(xù)的物理內(nèi)存用于構(gòu)建共享內(nèi)存之夕卜,還分配第二塊連續(xù)的物理內(nèi)存用于構(gòu)建接收隊(duì)列和發(fā)送隊(duì)列。其中,所構(gòu)建的接收隊(duì)列用于存儲內(nèi)核態(tài)接收進(jìn)程所接收的報文的內(nèi)存塊地址,所構(gòu)建的發(fā)送隊(duì)列用于存儲內(nèi)核態(tài)發(fā)送進(jìn)程處理后的報文的內(nèi)存塊地址。例如,假設(shè)內(nèi)核態(tài)在初始化時,分配大小為16M的連續(xù)物理內(nèi)存用于構(gòu)建共享內(nèi)存,并將所分配的16M的連續(xù)物理內(nèi)存分為8K個內(nèi)存塊,進(jìn)一步假設(shè)IK個內(nèi)存塊的地址需要用一個隊(duì)列進(jìn)行保存,這時,內(nèi)核態(tài)在初始化時,除了分配大小為16M的連續(xù)物理內(nèi)存用于構(gòu)建共享內(nèi)存之外,還需分配另一塊內(nèi)存用于保存8個接收隊(duì)列和8個發(fā)送隊(duì)列,其中,8個接收隊(duì)列可以為:為qos[l]、qos[2]、qos[3]、qos[4]、qos[5]、qos[6]、qos[7]、qos[8] ;8 個發(fā)送隊(duì)列可以為:qos[9]、qos[10]、qos[ll]、qos [12]、qos [13]、qos [14]、qos [15]、qos [16]。
[0056]具體的,在將報文的內(nèi)存塊地址存儲至接收隊(duì)列中時,可根據(jù)內(nèi)核態(tài)接收進(jìn)程所接收的報文的源IP地址和目的IP地址進(jìn)行哈希運(yùn)算;根據(jù)哈希運(yùn)算后所得到的值,確定內(nèi)核態(tài)接收隊(duì)列的隊(duì)列值;根據(jù)確定的內(nèi)核接收隊(duì)列的隊(duì)列值,將報文的內(nèi)存塊地址存儲至相應(yīng)的接收隊(duì)列中,以保證報文的同源同宿。
[0057]其中,哈希運(yùn)算就是在接收到報文以后,首先分別從報文的源IP地址、目的IP地址的32位二進(jìn)制數(shù)中提取固定位置、固定數(shù)量的二進(jìn)制數(shù),比如12位到20位共9位數(shù),然后將這組數(shù)進(jìn)行異或操作,并根據(jù)隊(duì)列數(shù)進(jìn)行取余數(shù)操作。這樣,就可以將不同的報文存儲到不同的接收隊(duì)列中,同時也保證了報文的同源同宿。
[0058]此外,內(nèi)核態(tài)在初始化時,除了分配一定容量的第一塊連續(xù)的物理內(nèi)存用于構(gòu)建共享內(nèi)存、以及第二塊連續(xù)的物理內(nèi)存用于構(gòu)建接收隊(duì)列、發(fā)送隊(duì)列之外,還可分配第三塊連續(xù)的物理內(nèi)存,用于存儲接收隊(duì)列的頭指針和尾指針以及發(fā)送隊(duì)列的頭指針和尾指針。
[0059]例如,假設(shè)內(nèi)核態(tài)在初始化時,分配大小為16M的連續(xù)物理內(nèi)存用于構(gòu)建共享內(nèi)存和另一塊內(nèi)存用于保存8個接收隊(duì)列和8個發(fā)送隊(duì)列。進(jìn)一步假設(shè)8個接收隊(duì)列分別為:qos [I]、qos [2]、qos [3]、qos [4]、qos [5]、qos [6]、qos [7]、qos [8] ;8 個發(fā)送隊(duì)列分別為:qos [9]、qos [10]、qos [11]、qos [12]、qos [13]、qos [14]、qos [15]、qos [16];進(jìn)一步假設(shè)上述8個接收隊(duì)列的頭指針和尾指針分別為:為qos[l].head、qos[2].head、qos[3].head、qos[4].head、qos[5].head、qos[6].head、qos[7].head、qos[8].head、qos [I].tail、qos[2].tail、qos[3].tail、qos[4].tail、qos[5].tail、qos[6].tail、qos[7].tail、qos[8].tail ;上述8個發(fā)送隊(duì)列的頭指針和尾指針分別為:為qos[9].head、qos[10].head、qos[11].head、qos[12].head、qos[13].head、qos[14].head、qos[15].head、qos [16].head、qos [9].tail、qos [10].tail、qos [I I].tail、qos [12].tail、qos [13].tail、qos[14].tail、qos[15].tail、qos[16].tail。
[0060]這時,內(nèi)核態(tài)在初始化時,還需分配另一塊連續(xù)的物理內(nèi)存,用于存放上述8個接收隊(duì)列的頭指針和尾指針以及上述8個發(fā)送隊(duì)列的頭指針和尾指針。
[0061 ]內(nèi)核態(tài)在初始化時,不僅分配第一塊連續(xù)的物理內(nèi)存用于構(gòu)建共享內(nèi)存、第二塊連續(xù)的物理內(nèi)存用于構(gòu)建接收隊(duì)列和發(fā)送隊(duì)列以及第三塊連續(xù)的物理內(nèi)存用于儲接收隊(duì)列的頭指針和尾指針以及發(fā)送隊(duì)列的頭指針和尾指針,而且還記錄所分配的第一塊連續(xù)的物理內(nèi)存的首地址、第二塊連續(xù)的物理內(nèi)存的首地址以及第三塊連續(xù)的物理內(nèi)存的首地址。這樣,用戶態(tài)進(jìn)程通過記錄的所分配的第一塊連續(xù)的物理內(nèi)存的首地址、第二塊連續(xù)的物理內(nèi)存的首地址以及第三塊連續(xù)的物理內(nèi)存的首地址,能夠讀取到第一塊連續(xù)的物理內(nèi)存的首地址及其大小、第二塊連續(xù)的物理內(nèi)存的首地址及其大小以及第三塊連續(xù)的物理內(nèi)存的首地址及其大小。并且,在用戶態(tài)進(jìn)程讀取到第一塊連續(xù)的物理內(nèi)存的首地址及其大小、第二塊連續(xù)的物理內(nèi)存的首地址及其大小以及第三塊連續(xù)的物理內(nèi)存的首地址及其大小后,通過調(diào)用系統(tǒng)函數(shù)使得第一塊連續(xù)的物理內(nèi)存的地址與用戶態(tài)進(jìn)程的虛擬地址建立映射關(guān)系,這樣,用戶態(tài)進(jìn)程可通過建立的映射關(guān)系,對內(nèi)存塊中存儲的報文進(jìn)行處理,因此,用戶態(tài)進(jìn)程可直接訪問到內(nèi)核態(tài)接收到的報文,從而避免了將報文從內(nèi)核態(tài)到用戶態(tài)的拷貝,提高了報文的轉(zhuǎn)發(fā)速度,同時,也節(jié)約了系統(tǒng)資源。
[0062]上述步驟SlOl中,內(nèi)核態(tài)接收進(jìn)程將網(wǎng)卡接收到的報文存儲于共享內(nèi)存并通知用戶態(tài)進(jìn)程,具體為:內(nèi)核態(tài)接收進(jìn)程從內(nèi)存池中申請內(nèi)存塊,將網(wǎng)卡接收到的報文存儲于申請到的內(nèi)存塊中,并將申請到的內(nèi)存塊的地址插入到接收隊(duì)列的隊(duì)尾;用戶態(tài)進(jìn)程輪詢接收隊(duì)列,從接收隊(duì)列頭部讀取內(nèi)存塊的地址,直至接收隊(duì)列為空;在接收隊(duì)列為空時,用戶態(tài)進(jìn)程進(jìn)入睡眠狀態(tài),直至接收隊(duì)列非空時喚醒用戶態(tài)進(jìn)程??梢钥闯?,采用等待喚醒機(jī)制以及中斷輪詢相結(jié)合的方式,減去了空閑時CPU的開銷,從而提高了報文的轉(zhuǎn)發(fā)速度和系統(tǒng)資源利用