黃 銳,王 銀,楊憲偉,李治輝
(中國電子科技集團公司第三十研究所,四川 成都 610041)
隨著網絡帶寬需求爆發(fā)式的增長,傳輸控制/網際協(xié)議(Transmission Control Protocol/Internet Protocol,TCP/IP)處理占用了越來越多的處理器(Central Processing Unit,CPU)時間,使得計算機在處理萬兆級別的業(yè)務流時無法充分利用CPU的性能[1,2]。因此,通過硬件實現已經十分成熟且與業(yè)務松耦合的底層TCP/IP協(xié)議棧,使CPU更專注于處理業(yè)務是一種高效靈活的做法[3]。
TCP協(xié)議屬于傳輸層協(xié)議,通常運行于網絡層IP協(xié)議之上。IP網絡傳輸數據存在因網絡擁塞和傳輸錯誤導致的報文丟失以及多路由轉發(fā)導致的報文亂序等問題[4]。如果TCP協(xié)議棧對不連續(xù)報文不加處理,直接丟棄,可能會導致網絡擁塞加劇,傳輸效率降低,因此TCP協(xié)議棧需要合理高效地處理亂序報文[5]。
軟件TCP協(xié)議棧通常采用鏈表的方式處理亂序報文[6]。而對于硬件實現的TCP協(xié)議棧如果也采用鏈表的方式處理,那么每個報文都需對鏈表進行搜索匹配等操作,不但復雜度極高,而且處理效率也會受到極大影響,因此需要設計一種符合硬件實現特點的高效亂序重排方法。
本文提出一種適用于現場可編程邏輯陣列(Field Programmable Gate Array,FPGA)實現的TCP/IP硬件協(xié)議棧的亂序重排實現方法,首先簡要介紹TCP/IP硬件協(xié)議棧的架構,然后詳細介紹硬件協(xié)議棧段亂序重排的實現方法。
TCP/IP硬件協(xié)議棧架構如圖1所示。

圖1 TCP硬件協(xié)議棧架構
協(xié)議棧前端包括鏈路層處理模塊萬兆以太網媒體訪問控制器(Medium Access Control,MAC)和IP層協(xié)議處理部分。IP層處理模塊負責提取報文的源IP地址、目的IP地址以及TCP源端口和目的端口信息,匹配TCP連接信息,匹配成功獲取相應的連接索引號后送入TCP處理模塊進行后續(xù)處理。
TCP連接狀態(tài)控制模塊負責TCP連接建立過程中的3次握手及關閉時的4次揮手的狀態(tài)跳轉控制[7]。當TCP連接不處于連接已建立(ESTABLISHED)狀態(tài)時,報文由該模塊處理。TCP接收模塊負責對處于ESTABLISHED狀態(tài)的連接所接收到TCP報文進行處理,該模塊先判斷報文合法性,然后根據已接收數據塊信息對接收報文進行排序。
緩存管理模塊負責對TCP連接的接收和發(fā)送環(huán)形緩沖區(qū)進行讀寫管理,并維護每條連接的讀寫地址偏移和序號(Sequence Number,SN)等相關信息。
亂序重排功能在TCP接收模塊內實現。接收模塊先提取報文的TCP頭部信息,根據SN、長度及接收窗口信息判斷報文是否有效,然后根據接收信息表所記錄的已接收數據信息判斷報文所攜帶數據相對位置,同時計算出新的接收信息表,最后將數據發(fā)送到緩存管理模塊并寫入緩存。
接收信息表數據結構如圖2所示,其記錄了下一個待接收的字節(jié)序號RCV.NXT和不連續(xù)數據塊記錄Qi=(RCV.FSN,RCV.LSN),其中i=[0,1,2]指示數據塊序號,RCV.FSN為數據塊起始字節(jié)序號(First Sequence Number,FSN),RCV.LSN為末尾字節(jié)序號(Last Sequence Number,LSN),如果對應數據塊位置數據無效則FSN及LSN字段均置0。

圖2 接收信息表數據結構
RCV.NXT表示已確認接收數據區(qū)。記錄的不連續(xù)數據塊位于RCV.NXT至RCV.NXT+WIN_SIZE之間,WIN_SIZE為接收窗口大小。Q0,Q1,Q2這3個數據塊序號為遞增排列。緩存信息表記錄該條連接緩存內已寫入的數據長度WRLEN、已讀出的數據長度RDLEN以及下一個待接收的字節(jié)編號FSN及其地址FADDR。
亂序重排的關鍵是判斷新接收數據所處的相對位置,并對數據塊記錄進行重新排序,確保Q0~Q2按發(fā)送的先后順序排列。
首先,根據前端IP層處理模塊匹配得到的連接索引號,讀取對應的接收信息表。先判斷報文是否處于有效窗口內,同時判斷接收信息表記錄的數據塊是否有效。對于接收到的TCP報文,其起始數據序號為SN,數據長度為LEN,如果RCV.NXT+WIN_SIZE≤SN或SN+LEN≤RCV.NXT,則報文無效,丟棄[8]。對于數據塊Qi,如果RCV.FSN與RCV.LSN相等,則該數據塊無效,后續(xù)處理忽略該數據塊。
其次,比較新收數據塊與已接收數據塊關系。SN=RCV.NXT時記為B1,RCV.NXT< SN<RCV.FSN0時記為B2,RCV.FSN0≤SN≤ RCV.LSN0記為B3,RCV.LSN0<SN<RCV.FSN1記為B4,RCV.FSN1≤SN≤RCV.LSN1記為B5,RCV.LSN1<SN<RCV.FSN2記為B6,RCV.FSN2≤SN≤RCV.LSN2記為B7,RCV.FSN2<SN時報文無效。
SN+LEN=RCV.NXT時報文無效,RCV.NXT<SN+LEN<RCV.FSN0時記為E1,RCV.FSN0≤SN+LEN≤RCV.LSN0記為E2,RCV.LSN0<SN+LEN<RCV.FSN1記為E3,RCV.FSN1≤ SN+LEN≤ RCV.LSN1記為E4,RCV.LSN1<SN+LEN<RCV.FSN2記為E5,RCV.FSN2≤ SN+LEN ≤ RCV.LSN2記為E6,RCV.FSN2<SN+LEN時記為E7。
再次,根據比較結果更新數據塊記錄,如表1、表2所示。

表1 數據塊記錄計算(E1~E4)

表2 數據塊信息計算(E5~E7)
最后,將合法數據發(fā)送到緩存管理模塊。緩存管理模塊根據數據塊起始SN值與緩存信息表FSN值之差計算出數據塊,寫入偏移OFFSET=SN-FSN,數據寫入地址為Wraddr=FADDR+OFFSET。
接收信息表用FPGA內部RAM存儲,數據接口為64位寬,TCP接收模塊根據連接索引號讀出全部數據需要5個時鐘周期,分析TCP報文與讀表并行進行,位置比較與數據塊記錄重新生成需要3個時鐘周期,生成緩存管理模塊所需信息需要2個時鐘周期,再加上狀態(tài)控制需要2個時鐘周期,因此每個報文除了處理數據外還需要額外的12個時鐘周期。假設TCP報文長度為常見的1 480字節(jié),數據處理接口為128位寬,則數據處理需要93個時鐘周期[9]。系統(tǒng)時鐘頻率為250 MHz,此時報文處理能力為2.38 M/s,遠大于萬兆網絡每秒最大報文量0.8 M。假設TCP報文長度為最小的576字節(jié),則數據處理需要36個時鐘周期,此時報文處理能力為5.2 M/s,而此時萬兆網絡每秒最大報文量2 M。即使考慮最差情形,即報文不攜帶數據,該情形下報文處理能力為17.8 M/s,而萬兆網絡報文量為16 M/s,依然能滿足要求。上述分析表明進行端亂序重排的TCP接收模塊處理性能可以滿足萬兆網絡所有情形下的處理要求。
TCP硬件協(xié)議棧利用Intel Stratix V FPGA實現,將其配置為服務端,并將內部數據接收和發(fā)送接口環(huán)回。以Dell Precision T7610工作站為客戶端,用Intel X520-SR2萬兆網卡與服務端連接,使用自行編寫的測試軟件對TCP硬件協(xié)議棧性能進行測試。
測試結果表明,FPGA實現的TCP硬件協(xié)議棧數據收發(fā)速率達到9.388 Gb/s,即包含本文所述亂序重排實現方法的TCP接收模塊處理性能滿足要求。
本文先簡要介紹一種基于FPGA的TCP硬件協(xié)議棧的架構,對其中的TCP段亂序重排的數據結構及實現方法進行詳細說明,最后對其性能進行了分析及測試,結果表明利用該方法實現的TCP協(xié)議棧處理能力達到10 Gb/s。本方法具有邏輯簡單、處理高效及資源消耗低等優(yōu)點,但存在的不足是不連續(xù)數據塊記錄只有3個,當到達的互不相鄰的報文超過3個時只能丟棄等待重傳,不過該問題出現的概率極低,可以通過增加不連續(xù)數據塊記錄數量來優(yōu)化[10]。