王德勁,杜 仲
(1.光纖通信技術和網絡國家重點試驗實,湖北 武漢 430074;2.武漢郵電科學研究院,湖北 武漢 430074)
無線局域網運用越來越廣泛,保證網絡的穩定性和網絡帶寬的有效利用十分重要。AP作為用戶通過無線網絡接入Internet的橋接器,透傳二層數據包。Ebtables是以太網橋防火墻,工作在數據鏈路層,可用來過濾數據鏈路層數據包。本文基于Linux操作系統,利用Ebtalbes二層打標功能,結合開源工具TC filter對數據包進行分類,再利用分類的隊列對數據包進行整形,構建了一個可以從數據鏈路層進行流量控制的系統。
Linux操作系統的TC(Traffic Control)工具用于Linux內核的流量控制,主要通過在輸出端口建立一個隊列來實現。一般只限制網卡發送的數據包,而不限制接收的數據包,即“控發不控收”。
Linux流量控制方式包括整形、調度、策略、丟棄和標記[1]。整形就是通過延遲隊列中的數據包的發送使其發送速率控制在一個固定的水平以下。而調度是對隊列中數據包的發送順序進行排列或重排。先入先出隊列(FIFO)是最常見的調度器。決策器能計算并限制某個特定隊列的流量,當網絡流量超過預設值時,決策器就開始采取某種預設的操作,從而將流量限制在某個范圍。決策器最直接的操作是丟棄數據包。標記是一種對數據包進行一些修改的操作。
流量的處理由3種對象控制,即排隊規則(qdisc)、類(class)和過濾器(filter)。隊列用來控制網絡的收發速度,通過隊列,Linux可以將網絡數據包緩存起來,然后根據用戶的設置,在盡量不中斷連接(如TCP)的前提下來平滑網絡流量。qdisc分為可分類的和不可分類的,可分類的qdisc包括CBQ(基于類的隊列)、分層的令牌桶(HTB)和基于優先級的隊列(PRIO),其中HTB是本系統所采用的排隊類型。類存在于可分類的qdisc之下,不同的類別中可以包含更深入的qdisc,即子類,通過這些細分的qdisc還可以為進入隊列的數據包進一步排隊。通過設置各種類別數據包的離隊次序,qdisc還可以為網絡數據流設置優先級。過濾器是Linux流量控制系統中最復雜的對象,它是連接各個流量控制核心組件的紐帶。過濾器最簡單和最常見的用法就是對數據包進行分類。
HTB是基于令牌、桶以及分層的思想。令牌就像通行證,數據包只有在擁有令牌的情況下才能出隊。系統以一定的速率產生令牌并填到桶中,直到桶滿為止。這種思想的優點在于,如果令牌產生的數量大于其被消耗的數量,令牌將會被積累起來,這樣不僅能保證在較長一段時間內網絡流量在限定值以下,又能處理大速率的突發數據傳輸[1]。分層是通過類實現的,類可以有子類。通過層次共享,當子類流量超過了某個值時,可以向其父類租借令牌,如果直接父類不能滿足,則繼續向上借用,直到子類借到需要的令牌或達到根節點為止[2]。HTB租借模型如圖1所示。

圖1 HTB租借模型
在HTB租借模型中,父節點下的兄弟節點確保速率必須得到保證,葉子節點或子分類必須向其父對象歸還借用的令牌,層層向上直到根分類。
AP是無線局域網中的橋接器,在硬件平臺上,給它配置一塊ETH網卡和一塊WiFi網卡。AP通過ETH卡的eth0口與有線網相連。一塊WiFi卡可以創建多個虛AP(用athn表示,n可以是0到MAX_ATH之間的任一數值,MAX_ATH為能創建的最大虛AP個數),每個虛AP對應一個ESSID,用于被STA關聯。eth0和athn之間通過建立一個橋接器(這里用br0表示)橋接在一起。
只要給出合法的參數,流量控制系統就能對ESSID的上下行流量都進行有效的控制。上行流中,數據先進入athn,然后上橋br0,再由br0轉入有線口eth0發送出去。下行流則相反,數據先經過eth0,進入br0,然后再通過無線口athn發送出去。整個過程,數據都在二層傳輸,因此要對數據包進行過濾和標記,需要使用以太網防火墻工具Ebtables,流量控制工具TC才能根據標記對數據包進行整形。Linux內核2.6版以上都內置了 Ebtables和iproute2(iproute2包含了TC工具)。
Ebtables的配置包括表、鏈和規則。表是內置且固定的,共有filter,nat和broute這3種。filter用于對數據包進行過濾,nat用于地址轉換,broute決定數據包是在數據鏈路層轉發還是在網絡層轉發,默認是在數據鏈路層轉發。表包含鏈,broute有 BROUTING鏈;filter有 FORWARD,INPUT和 OUTPUT 鏈;nat有 PREROUTING,OUTPUT和POSTROUTING鏈[3]。一般對數據作標記是在filter的FORWARD進行。每條鏈中有一系列規則,每個規則定義了一些過濾選項。進入鏈中的數據包都會匹配這些項,一但匹配成功就會執行對應的操作,最常用的操作是ACCEPT和DROP,即接收匹配的數據包,丟棄不匹配的。
流量控制功能以接口的方式實現,接口需要輸入“struct qos{char essid[128];int ratev;int ceilv;int priv;};”結構的一個數組和“int num”表示數組元素個數的兩個參數,num的最大值為MAX_ATH。對于一個essid,ratev為系統為其確保的帶寬,ceilv為其最高可占用帶寬,priv為其搶占帶寬的能力,priv數值越小搶占能力越強。
程序主要分為兩步,第一步將ESSID映射為athn,第二步對相應的網口實施整形操作。在上行流中,需要在athn口標記數據包,然后在eth0口對數據包進行整形。在下行流中則相反。由于上下行流量控制算法思想類似,這里只給出上行流量控制程序流程圖,如圖2所示。

圖2 上行流量控制程序流程圖
為AP板燒寫Linux 2.6版內核和簡單流量控制測試程序。搭建的測試網絡需要一臺普通PC、兩臺筆記本計算機(STA1和STA2)和一個AP。在AP的ath0和ath1口分別建立ESSID:TC_TEST1,TC_TEST2。ath0,ath1 都通過br0 與eth0橋接在一起。STA1與TC_TEST1通過無線關聯(稱為pair1),STA2與TC_TEST2關聯(稱為pair2)。PC與AP的eth0口通過有線直接相連。為方便測試,在測試過程中將通過eth0的上行流量始終限制為800 bit/s。采用chariot作為網絡吞吐量測試工具,測試時間為1 min。
在未作任何其他流量限制前,上行吞吐量變化曲線如圖3所示。由圖可知,兩者的曲線除了在最開始的一小段時間內有點變化外,后面都重疊在一起且幾乎是平線。出現這種現象的原因是,eth0口的上行流量被限制在800 bit/s,且兩條流量的優先級是一樣的。

圖3 無流控下的上行吞吐量
在簡單測試程序中,給流量控制接口傳入參數“struct essid_qos[]={{TC_TEST1,200,600,1},{TC_TEST2,200,600,2}},num=2”。對流量進行限速后,吞吐量曲線出現了明顯的變化,如圖4所示。此時pair1的曲線要高于 pair2,chariot計算出 pair1的吞吐量平均值為0.387 Mbit/s,pair2 的為0.376 Mbit/s。造成這種差異性,是因為雖然系統給TC_TEST1和TC_TEST2分配的確保帶寬和最高可占用帶寬都一樣,但是給TC_TEST1設置的優先級要高于TC_TEST2,即TC_TEST1帶寬搶占能力更強。

圖4 限速后的上行吞吐量
從圖4可以看出,兩曲線的形狀具有互補性,即當兩線同時達到某個不高的峰時,它們會同時下降,且pair2下降得更快。這種現象以及上面給出的pair1和pair2的吞吐量平均值反映了帶寬的共享問題。在程序中,給TC_TEST1和TC_TEST2提供的確保帶寬都為200 bit/s,但實際上,它們的均值超過了這個數字,說明都向父類租借了一部分帶寬。而父類的總空閑帶寬是一定的,當它把這部分帶寬租借給了其中一個,就無法同時滿足另一個,出現了吞吐量曲線互補的現象。通過命令行可以查看帶寬的租借情況,圖5顯示的是TC_TEST1的帶寬租借情況。lended表示向外借出了多少數據包數,borrowed表示從外借入了多少數據包數。

C_TEST1帶寬租借情況(截圖)
由實驗數據和分析可知,采用Linux流量控制工具Ebtables和TC能有效控制無線接入點中ESSID的上下行流量。在無線帶寬有限的前提下,不僅能夠防止ESSID用戶之間發生的帶寬爭奪,保證帶寬分配的公平性,還可以將用戶分成不同的類別等級,給特權用戶較多的帶寬,同時限制普通用戶的帶寬。也可以做到在某類用戶不使用帶寬時,將空閑的帶寬租借給其他用戶,這樣能夠達到充分利用有限資源的目的。
[1]MARTIN A.Brown traffic control howto[EB/OL].[2011-08-22].http://tldp.org/HOWTO/Traffic-Control-HOWTO/index.html.
[2]Manual:HTB.[EB/OL].[2011-08-22].http://wiki.mikrotik.com/wiki/Manual:HTB.
[3]Ebtables/iptables interaction on a Linux-based bridge[EB/OL].[2011-08-20].http://ebtables.sourceforge.net/br_fw_ia/br_fw_ia.html.