目前很多企業的內部區域網路已經建立,很多還在區域網路基礎上建立了企業內部的MIS系統和郵件伺服器等,甚至在系統中開展了ApsaraVideo for VOD等資料流量較大的業務。
企業內部網路有足夠的頻寬可以使用。但是,一般在企業接入Internet的部分都是一個有限的流量。為了提高網路的使用品質,保證使用者按照網路中業務設 計的要求來使用整個網路的頻寬,可以從流量控制伺服器的角度分析、最佳化Linux系統,給企業服務帶來便利和高效。
流量控制的基本實現
Linux 作業系統中的流量控制器(TC)主要是通過在輸出連接埠處建立一個隊列來實現流量控制。Linux從2.1.105版核心開始支援流量控制,使用時需要重新 編譯核心。Linux流量控制的基本實現可簡單地由圖1來描述。從圖1可以看出,核心是如何處理接收包、如何產生髮送包,並送往網路的。
圖1 Linux流量控制的基本實現
接收包進來後,由輸入多路分配器(Input De-Multiplexing)進行判斷選擇:如果接收包的目的是本主機,那麼將該包送給上層處理;否則需要進行轉寄,將接收包交到轉寄塊 (Forwarding Block)處理。轉寄塊同時也接收本主機上層(TCP、UDP等)產生的包。轉寄塊通過查看路由表,決定所處理包的下一跳。然後,對包進行排列以便將它 們傳送到輸出介面(Output Interface)。Linux流量控制正是在排列時進行處理和實現的。
圖2 流量控制基本架構
2所示,Linux流量控制主要由三大部分來實現:
◆ 隊列規則(Queue Discipline)
◆ 分類(Classes)
◆ 過濾器(Filters)
因此,Linux流量控制主要分為建立隊列、建立分類和建立過濾器三個方面。其基本實現步驟為:
(1)針對網路物理裝置(如乙太網路卡eth0)綁定一個隊列;
(2)在該隊列上建立分類;
(3)為每一分類建立一個基於路由的過濾器。
流量控制的具體使用
現在對流量控制(TC)的具體使用做個介紹。首先是TC的總用法。
TC命令,核心支援需設定QoS support、QoS and/or fair queueing = y。用法為:
#tc [ OPTIONS ] OBJECT { COMMAND | help }
其中
OBJECT := { qdisc | class | filter }
OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }
下面分別介紹TC中隊列、分類和過濾器的用法。
1.TC中隊列(qdisc)的用法
隊列的使用中,核心支援需設定QoS support、QoS and/or fair queueing = y。用法為:
#tc qdisc [ add | del | replace | change | get ] dev STRING [ handle QHANDLE ] [ root | ingress | parent CLASSID ] [ estimator INTERVAL TIME_CONSTANT ] [ [ QDISC_KIND ] [ help | OPTIONS ] ] #tc qdisc show [ dev STRING ] [ingress] |
其中
QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. } OPTIONS := ... try tc qdisc add <desired QDISC_KIND> help |
CBQ隊列(qdisc cbq)的使用中,核心支援需設定 QoS support、QoS and/or fair queueing、CBQ packet scheduler、Rate estimator = y,用法為:
... cbq bandwidth BPS avpkt BYTES [ mpu BYTES ] [ cell BYTES ] [ ewma LOG ] |
2.TC中分類(class)的用法
分類的使用中,核心支援需設定QoS support、QoS and/or fair queueing、Packet classifier API = y。用法為:
#tc class [ add | del | change | get ] dev STRING [ classid CLASSID ] [ root | parent CLASSID ] [ [ QDISC_KIND ] [ help | OPTIONS ] ] #tc class show [ dev STRING ] [ root | parent CLASSID ] |
其中
QDISC_KIND := { prio | cbq | etc. } OPTIONS := ... try tc class add <desired QDISC_KIND> help TC CBQ分類(class cbq)的用法為: <ccid_nobr> <table width="400" border="1" cellspacing="0" cellpadding="2" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"> <tr> <td bgcolor="e6e6e6" class="code" style="font-size:9pt"> <pre><ccid_code> ... cbq bandwidth BPS rate BPS maxburst PKTS [ avpkt BYTES ] [ minburst PKTS ] [ bounded ] [ isolated ] [ allot BYTES ] [ mpu BYTES ] [ weight RATE ] [ prio NUMBER ] [ cell BYTES ] [ ewma LOG ] [ estimator INTERVAL TIME_CONSTANT ] [ split CLASSID ] [ defmap MASK/CHANGE ] |
3.TC中過濾器(filter)的用法
過濾器的使用中,核心支援需設定QoS support、QoS and/or fair queueing、Packet classifier API = y。用法為:
#tc filter [ add | del | change | get ] dev STRING [ pref PRIO ] [ protocol PROTO ] [ estimator INTERVAL TIME_CONSTANT ] [ root | classid CLASSID ] [ handle FILTERID ] [ [ FILTER_TYPE ] [ help | OPTIONS ] ] #tc filter show [ dev STRING ] [ root | parent CLASSID ] |
其中
FILTER_TYPE := { rsvp | u32 | fw | route | etc. } FILTERID := ... format depends on classifier, see there OPTIONS := ... try tc filter add <desired FILTER_KIND> help |
TC U32過濾器(filter u32)的用法:
... u32 [ match SELECTOR ... ] [ link HTID ] [ classid CLASSID ] [ police POLICE_SPEC ] [ offset OFFSET_SPEC ] [ ht HTID ] [ hashkey HASHKEY_SPEC ] [ sample SAMPLE ] 或 u32 divisor DIVISOR |
其中
SELECTOR := SAMPLE SAMPLE ... SAMPLE := { ip | ip6 | udp | tcp | icmp | u{32|16|8} } SAMPLE_ARGS FILTERID := X:Y:Z |
TC FW過濾器(filter fw)的用法:
... fw [ classid CLASSID ] [ police POLICE_SPEC ]
其中
POLICE_SPEC := ... look at TBF CLASSID := X:Y |
流量控制應用執行個體
假設目前某企業面臨的是一個複雜的網路環境。在該環境中,既包括了100Mb的區域網路,也包括了微波或802.11的無線鏈路網路,其網路拓撲3所示。在這樣的環境下,保證業務資料的流量,實現流量控制,需要對各區域網路的傳輸及商務服務進行控制。
圖3 商業網路拓撲圖
系統採用Linux 2.2.14版核心來支援QoS。首先需要重新編譯核心。運行make config,進行如下設定:
EXPERIMENTAL _OPTIONS = y Class Based Queueing (CBQ) = y QoS and/or fair queueing = y CBQ packet scheduler = y Rate estimator= y Packet classifier API = y |
編譯產生新核心:
#make dep #make clean #make bzImage |
Linux作業系統中,流量控制器(TC)在輸出連接埠處建立一個隊列進行流量控制,控制的方式基於目的IP地址、目的子網的網路號及連接埠號碼,或者基於源IP地址、源子網的網路號及連接埠號碼。
流量控制器TC的準系統模組為隊列、分類和過濾器。Linux核心中支援的隊列有Class Based Queue、Token Bucket Flow、CSZ、First In First Out、Priority、TEQL、SFQ、ATM、RED。這裡討論的隊列與分類都是基於CBQ(Class Based Queue),過濾器則是基於U32和FW。
配置和使用流量控制器TC,除了建立隊列、分類、過濾器和路由外,還需要對現有的隊列、分類、過濾器和ipchains進行監視。
基於3所示的網路環境,現對中心流量控制伺服器進行簡單描述,4所示。
圖4 中心伺服器介面圖
eth1的配置
假設遠端無線網卡(eth1)的IP地址為172.16.32.196,在其上建立一個CBQ隊列,控制所有從無線網卡發出的資料包。假設包的平均大小為1000位元組,包間隔發送單元的大小為8位元組,可接收衝突的發送最長包數目為20位元組。
這裡採用源地址及源連接埠號碼進行控制。假如有三種類型的流量需要控制:
◆ 由本主機發出的業務資料包,源連接埠為7001:7004,流量頻寬控制在100Kb;
◆由本地區域網路發出的資料包,IP地址為192.168.1.26,流量頻寬控制在1.1Mb;
◆發往子網1,子網號為192.168.1.0,子網路遮罩為255.255.255.0,流量頻寬控制在1Mb。
1.建立隊列
一般情況下,針對一個網卡只需建立一個隊列。
將一個CBQ隊資料行繫結到網路物理裝置eth1上,其編號為1:0,實際頻寬為10Mb,包的平均大小為1500位元組,包間隔發送單元的大小為8位元組,最小傳輸包大小為64位元組。
#tc qdisc add dev eth1 root handle 1:0 cbq bandwidth 10Mbit cell 8 avpkt 1500 mpu 64
2.建立分類
分類建立在隊列之上。一般情況下,針對一個隊列需建立一個根分類,然後在其上建立子分類。對於分類,按其分類的編號順序起作用,編號小的優先。一旦符合某個分類匹配規則,通過該分類發送資料包,則其後的分類不再起作用。
(1)建立根分類1:1,分配頻寬為10Mb。
#tc class add dev eth1 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit allot 1514 cell 8 weight 1Mbit maxburst 1 avpkt 1500 bounded
該隊列的最大可用頻寬為10Mb,實際分配的頻寬為10Mb,可接收衝突的發送最長包數目為1位元組,傳輸單元最大值(加MAC頭)大小為1514位元組,優先 層級為8,包的平均大小為1500位元組,包間隔發送單元的大小為8位元組,相應於實際頻寬的加權速率為10Mb。
(2)建立分類1:2,其父分類為1:1,分配頻寬為8Mb。
#tc class add dev eth1 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 1200Kbit allot 1514 cell 8 weight 120Kbit maxburst 1 avpkt 1500 bounded isolated
該隊列的最大可用頻寬為10Mb,實際分配的頻寬為 1.2Mb,可接收衝突的發送最長包數目為1位元組,傳輸單元最大值(加MAC頭)大小為1514位元組,優先順序別為1,包的平均大小為1500位元組,包間隔發 送單元的大小為8位元組,相應於實際頻寬的加權速率為120Kb,獨佔頻寬且不可借用未使用頻寬。
(3)建立分類1:10,其父分類為1:2,分配頻寬為100Kb。
#tc class add dev eth1 parent 1:2 classid 1:10 cbq bandwidth 10Mbit rate 100Kbit allot 1514 cell 8 weight 10Kbit maxburst 1 avpkt 1500
該隊列的最大可用頻寬為10Mb,實際分配的頻寬為 1.2Mb,可接收衝突的發送最長包數目為1位元組,傳輸單元最大值(加MAC頭)大小為1514位元組,優先順序別為1,包的平均大小為1500位元組,包間隔發 送單元的大小為8位元組,相應於實際頻寬的加權速率為10Kb。
(4)建立分類1:20,其父分類為1:2,分配頻寬為1.1Mb。
#tc class add dev eth1 parent 1:2 classid 1:20 cbq bandwidth 10Mbit rate 1100Kbit allot 1514 cell 8 weight 110Kbit maxburst 1 avpkt 1500
該隊列的最大可用頻寬為10Mb,實際分配的頻寬為 1.1Mb,可接收衝突的發送最長包數目為1位元組,傳輸單元最大值(加MAC頭)大小為1514位元組,優先順序別為1,包的平均大小為1500位元組,包間隔發 送單元的大小為8位元組,相應於實際頻寬的加權速率為110Kb。
3.建立過濾器
過濾器主要服務於分類。一般只需針對根分類提供一個過濾器,然後為每個子分類提供一個ipchains映射。
(1)應用FW分類器到分類1:10,父分類編號為1:0,過濾協議為IP,標誌號(handle)為4,過濾器為基於ipchains。
#tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 4 fw classid 1:10
(2)應用FW分類器到分類1:20,父分類編號為1:0,過濾協議為IP,過濾器為基於ipchains。
#tc filter add dev eth1 protocol ip parent 1:0 prio 100 handle 5 fw classid 1:20
4.建立ipchains映射
該路由與前面所建立的路由映射一一對應。
(1)由本機發出的電話資料包通過分類1:10轉寄(分類1:10的速率100Kb)
#ipchains -A output -p udp -i tun0 -s 202.168.200.188/32 7001:7004 -t 0x01 0x10 -m 4
(2)由區域網路發出的資料包通過分類1:20轉寄(分類1:20的速率1.1Mb/s)
#ipchains -A output -i tun0 -s 192.16.188.0/24 -m 5
注意,一般對於流量控制器所直接連接的網段,建議使用IP主機地址流量控制限制,不要使用子網流量控制限制。如一定需要對直連子網使用子網流量控制限制,則在建立該子網的ipchains映射前,需將原先由系統建立的ipchains刪除,才可完成相應步驟。
5.監視
主要包括對現有隊列、分類、過濾器和路由狀況的監視。
(1)顯示隊列的狀況
簡單顯示指定裝置(這裡為eth1)的隊列狀況:
#tc qdisc ls dev eth1 qdisc cbq 1: rate 10Mbit (bounded,isolated) prio no-transmit |
詳細顯示指定裝置(這裡為eth1)的隊列狀況:
#tc -s qdisc ls dev eth1 qdisc cbq 1: rate 10Mbit (bounded,isolated) prio no-transmit Sent 7646731 bytes 13232 pkts (dropped 0, overlimits 0) borrowed 0 overactions 0 avgidle 31 undertime 0 |
這裡主要顯示通過該隊列發送了13232個資料包,資料流量為7646731個位元組,丟棄的包數目為0,超過速率限制的包數目為0。
(2)顯示分類的狀況
簡單顯示指定裝置(這裡為eth1)的分類狀況:
#tc class ls dev eth1 class cbq 1: root rate 10Mbit (bounded,isolated) prio no-transmit class cbq 1:1 parent 1: rate 10Mbit prio no-transmit #no-transmit表示優先順序為8 class cbq 1:2 parent 1:1 rate 1200Kbit prio no-transmit #no-transmit class cbq 1:10 parent 1:2 rate 100Kbit prio 1 class cbq 1:20 parent 1:2 rate 1100Kbit prio 6 |
詳細顯示指定裝置(這裡為eth1)的分類狀況:
#tc -s class ls dev eth1 class cbq 1: root rate 10Mbit (bounded,isolated) prio no-transmit Sent 17725304 bytes 32088 pkts (dropped 0, overlimits 0) borrowed 0 overactions 0 avgidle 31 undertime 0 class cbq 1:1 parent 1: rate 10Mbit prio no-transmit Sent 16627774 bytes 28884 pkts (dropped 0, overlimits 0) borrowed 16163 overactions 0 avgidle 587 undertime 0 class cbq 1:2 parent 1:1 rate 1200Kbit prio no-transmit Sent 628829 bytes 3130 pkts (dropped 0, overlimits 0) borrowed 0 overactions 0 avgidle 4137 undertime 0 class cbq 1:10 parent 1:2 rate 100KMbit prio 1 Sent 0 bytes 0 pkts (dropped 0, overlimits 0) borrowed 0 overactions 0 avgidle 159654 undertime 0 class cbq 1:20 parent 1:1 rate 1100Kbit prio no-transmit Sent 5552879 bytes 8076 pkts (dropped 0, overlimits 0) borrowed 3797 overactions 0 avgidle 159557 undertime 0 |
這裡主要顯示通過不同分類發送的資料包、資料流量、丟棄的包數目、超過速率限制的包數目等。其中根分類(class cbq 1:0)的狀況應與隊列的狀況類似。
例如,分類class cbq 1:20發送了8076個資料包,資料流量為5552879個位元組,丟棄的包數目為0,超過速率限制的包數目為0。
(3)顯示過濾器的狀況
#tc -s filter ls dev eth1 filter parent 1: protocol ip pref 1 fw filter parent 1: protocol ip pref 1 fw handle 0x4 classid 1:10 filter parent 1: protocol ip pref 100 fw filter parent 1: protocol ip pref 100 fw handle 0x5 classid 1:20 |
(4)顯示現有ipchains的狀況
#ip ipchains -L Chain input (policy ACCEPT): target prot opt source destination ports - all ------ anywhere anywhere n/a - all ------ anywhere anywhere n/a - udp ------ anywhere anywhere any -> 7001:7004 Chain forward (policy ACCEPT): Chain output (policy ACCEPT): target prot opt source destination ports - all ------ anywhere anywhere n/a - all ------ anywhere anywhere n/a - udp ------ anywhere anywhere 7001:7004 -> any - udp ------ anywhere anywhere 7001:7004 -> any |
6. 維護
主要包括對隊列、分類、過濾器和路由的增添、修改和刪除。
增添動作一般依照隊列→分類→過濾器→ipchains的順序進行;修改動作沒有什麼特殊要求;刪除則依照ipchains→過濾器→分類→隊列的順序進行。
這裡採用的方法是全部刪除,然後重新設定。刪除命令如下:
#tc qdisc del root dev eth1 #ipchains -F |
eth0的配置
eth0的配置與eth1的配置方法一樣。配置如下(說明略):
#tc qdisc del root dev eth0 #tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit cell 8 avpkt 1500 mpu 64 #tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit allot 1514 cell 8 weight 1Mbit prio 8 maxburst 1 avpkt 1500 bounded #tc class add dev eth0 parent 1:1 classid 1:10 cbq bandwidth 10Mbit rate 1.4Mbit allot 1514 cell 8 weight 140Kbit prio 8 maxburst 1 avpkt 1500 bounded isolated #tc filter add dev eth0 protocol ip parent 1:0 prio 100 handle 3 fw classid 1:10 #ipchains -A output -i eth0 -d 0.0.0.0/0 -m 3 |
通過對企業流量控制伺服器的分析,可以對Linux系統進行簡單改造,以實現對一些特殊業務的流量預分配和業務保證。