1. 程式人生 > >tc流量控制模型

tc流量控制模型

 

linux下tc簡介

Linux從kernel 2.1.105開始支援QOS,不過,需要重新編譯核心。執行 'make config'時將 EXPERIMENTAL_OPTIONS 設定成 'y',並且將 Class Based Queueing (CBQ), Token Bucket Flow, Traffic Shapers 設定為 'y' ,執行 'make dep&#59; make clean&#59; make bzilo',生成新的核心。

在Linux作業系統中流量控制器(TC)主要是在輸出埠處建立一個佇列進行流量控制,控制的方式是基於路由,亦即基於目的IP地址或目的子網的網路號的流量控制。流量控制器TC,其基本的功能模組為佇列、分類和過濾器。Linux核心中支援的佇列有,Class Based Queue ,Token Bucket Flow ,CSZ ,First In First Out ,Priority ,TEQL ,SFQ ,ATM ,RED。這裡我們討論的佇列與分類都是基於CBQ(Class Based Queue)的,而過濾器是基於路由(Route)的。

  配置和使用流量控制器TC,主要分以下幾個方面:分別為建立佇列、建立分類、建立過濾器和建立路由,另外還需要對現有的佇列、分類、過濾器和路由進行監視。 
  其基本使用步驟為:
  1) 針對網路物理裝置(如乙太網卡eth0)繫結一個CBQ佇列;
  2) 在該佇列上建立分類;
  3) 為每一分類建立一個基於路由的過濾器;

4) 最後與過濾器相配合,建立特定的路由表。

先假設一個簡單的環境,如下圖所示:

流量控制器上的乙太網卡(eth0) 的IP地址為192.168.1.66,在其上建立一個CBQ佇列。假設包的平均大小為1000位元組,包間隔傳送單元的大小為8位元組,可接收衝突的傳送最長包數目為20位元組。
  假如有三種類型的流量需要控制:
  1) 是發往主機1的,其IP地址為192.168.1.24。其流量頻寬控制在8Mbit,優先順序為2;
  2) 是發往主機2的,其IP地址為192.168.1.26。其流量頻寬控制在1Mbit,優先順序為1;
  3) 是發往子網1的,其子網號為192.168.1.0,子網掩碼為255.255.255.0。流量頻寬控制在1Mbit,優先順序為6。

1. 建立佇列 
  一般情況下,針對一個網絡卡只需建立一個佇列。

  將一個cbq佇列繫結到網路物理裝置eth0上,其編號為1:0;網路物理裝置eth0的實際頻寬為10 Mbit,包的平均大小為1000位元組;包間隔傳送單元的大小為8位元組,最小傳輸包大小為64位元組。
  ·tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit avpkt 1000 cell 8 mpu 64

2. 建立分類
  分類建立在佇列之上。一般情況下,針對一個佇列需建立一個根分類,然後再在其上建立子分類。對於分類,按其分類的編號順序起作用,編號小的優先;一旦符合某個分類匹配規則,通過該分類傳送資料包,則其後的分類不再起作用。

1) 建立根分類1:1;分配頻寬為10Mbit,優先級別為8。
·tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit maxburst 20 allot 1514 prio 8 avpkt 1000 cell 8 weight 1Mbit

  該佇列的最大可用頻寬為10Mbit,實際分配的頻寬為10Mbit,可接收衝突的傳送最長包數目為20位元組;最大傳輸單元加MAC頭的大小為1514位元組,優先級別為8,包的平均大小為1000位元組,包間隔傳送單元的大小為8位元組,相應於實際頻寬的加權速率為1Mbit。

2)建立分類1:2,其父分類為1:1,分配頻寬為8Mbit,優先級別為2。
·tc class add dev eth0 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 8Mbit maxburst 20 allot 1514 prio 2 avpkt 1000 cell 8 weight 800Kbit split 1:0 bounded

  該佇列的最大可用頻寬為10Mbit,實際分配的頻寬為 8Mbit,可接收衝突的傳送最長包數目為20位元組;最大傳輸單元加MAC頭的大小為1514位元組,優先級別為1,包的平均大小為1000位元組,包間隔傳送單元的大小為8位元組,相應於實際頻寬的加權速率為800Kbit,分類的分離點為1:0,且不可借用未使用頻寬。

3)建立分類1:3,其父分類為1:1,分配頻寬為1Mbit,優先級別為1。
·tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 10Mbit rate 1Mbit maxburst 20 allot 1514 prio 1 avpkt 1000 cell 8 weight 100Kbit split 1:0

  該佇列的最大可用頻寬為10Mbit,實際分配的頻寬為 1Mbit,可接收衝突的傳送最長包數目為20位元組;最大傳輸單元加MAC頭的大小為1514位元組,優先級別為2,包的平均大小為1000位元組,包間隔傳送單元的大小為8位元組,相應於實際頻寬的加權速率為100Kbit,分類的分離點為1:0。

4)建立分類1:4,其父分類為1:1,分配頻寬為1Mbit,優先級別為6。
·tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 10Mbit rate 1Mbit maxburst 20 allot 1514 prio 6 avpkt 1000 cell 8 weight 100Kbit split 1:0

  該佇列的最大可用頻寬為10Mbit,實際分配的頻寬為 64Kbit,可接收衝突的傳送最長包數目為20位元組;最大傳輸單元加MAC頭的大小為1514位元組,優先級別為1,包的平均大小為1000位元組,包間隔傳送單元的大小為8位元組,相應於實際頻寬的加權速率為100Kbit,分類的分離點為1:0。

3. 建立過濾器
過濾器主要服務於分類。一般只需針對根分類提供一個過濾器,然後為每個子分類提供路由對映。

1) 應用路由分類器到cbq佇列的根,父分類編號為1:0;過濾協議為ip,優先級別為100,過濾器為基於路由表。
·tc filter add dev eth0 parent 1:0 protocol ip prio 100 route

2) 建立路由對映分類1:2, 1:3, 1:4
·tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 2 flowid 1:2
·tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 3 flowid 1:3
·tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 4 flowid 1:4

4.建立路由
該路由是與前面所建立的路由對映一一對應。
1) 發往主機192.168.1.24的資料包通過分類2轉發(分類2的速率8Mbit)
·ip route add 192.168.1.24 dev eth0 via 192.168.1.66 realm 2

2) 發往主機192.168.1.30的資料包通過分類3轉發(分類3的速率1Mbit)
·ip route add 192.168.1.30 dev eth0 via 192.168.1.66 realm 3

3)發往子網192.168.1.0/24的資料包通過分類4轉發(分類4的速率1Mbit)
·ip route add 192.168.1.0/24 dev eth0 via 192.168.1.66 realm 4

  注:一般對於流量控制器所直接連線的網段建議使用IP主機地址流量控制限制,不要使用子網流量控制限制。如一定需要對直連子網使用子網流量控制限制,則在建立該子網的路由對映前,需將原先由系統建立的路由刪除,才可完成相應步驟。

5. 監視
  主要包括對現有佇列、分類、過濾器和路由的狀況進行監視。
1)顯示佇列的狀況

簡單顯示指定裝置(這裡為eth0)的佇列狀況
·tc qdisc ls dev eth0
qdisc cbq 1: rate 10Mbit (bounded,isolated) prio no-transmit

詳細顯示指定裝置(這裡為eth0)的佇列狀況
·tc -s qdisc ls dev eth0
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)顯示分類的狀況

簡單顯示指定裝置(這裡為eth0)的分類狀況
·tc class ls dev eth0
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 8Mbit prio 2
class cbq 1:3 parent 1:1 rate 1Mbit prio 1
class cbq 1:4 parent 1:1 rate 1Mbit prio 6

詳細顯示指定裝置(這裡為eth0)的分類狀況
·tc -s class ls dev eth0
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 8Mbit prio 2
Sent 628829 bytes 3130 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 4137 undertime 0
class cbq 1:3 parent 1:1 rate 1Mbit prio 1
Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 159654 undertime 0
class cbq 1:4 parent 1:1 rate 1Mbit prio 6
Sent 5552879 bytes 8076 pkts (dropped 0, overlimits 0)
borrowed 3797 overactions 0 avgidle 159557 undertime 0

  這裡主要顯示了通過不同分類傳送的資料包,資料流量,丟棄的包數目,超過速率限制的包數目等等。其中根分類(class cbq 1:0)的狀況應與佇列的狀況類似。
  例如,分類class cbq 1:4傳送了8076個數據包,資料流量為5552879個位元組,丟棄的包數目為0,超過速率限制的包數目為0。

顯示過濾器的狀況
·tc -s filter ls dev eth0
filter parent 1: protocol ip pref 100 route
filter parent 1: protocol ip pref 100 route fh 0xffff0002 flowid 1:2 to 2
filter parent 1: protocol ip pref 100 route fh 0xffff0003 flowid 1:3 to 3
filter parent 1: protocol ip pref 100 route fh 0xffff0004 flowid 1:4 to 4

這裡flowid 1:2代表分類class cbq 1:2,to 2代表通過路由2傳送。

顯示現有路由的狀況
·ip route
192.168.1.66 dev eth0 scope link
192.168.1.24 via 192.168.1.66 dev eth0 realm 2
202.102.24.216 dev ppp0 proto kernel scope link src 202.102.76.5
192.168.1.30 via 192.168.1.66 dev eth0 realm 3
192.168.1.0/24 via 192.168.1.66 dev eth0 realm 4
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.66
172.16.1.0/24 via 192.168.1.66 dev eth0 scope link
127.0.0.0/8 dev lo scope link
default via 202.102.24.216 dev ppp0
default via 192.168.1.254 dev eth0

  如上所示,結尾包含有realm的顯示行是起作用的路由過濾器。

6. 維護
  主要包括對佇列、分類、過濾器和路由的增添、修改和刪除。
  增添動作一般依照"佇列->;分類->;過濾器->;路由"的順序進行;修改動作則沒有什麼要求;刪除則依照"路由->;過濾器->;分類->;佇列"的順序進行。

1)佇列的維護
一般對於一臺流量控制器來說,出廠時針對每個乙太網卡均已配置好一個隊列了,通常情況下對佇列無需進行增添、修改和刪除動作了。

2)分類的維護

增添
增添動作通過tc class add命令實現,如前面所示。

修改
修改動作通過tc class change命令實現,如下所示:
·tc class change dev eth0 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 7Mbit maxburst 20 allot 1514 prio 2 avpkt 1000 cell 8 weight 700Kbit split 1:0 bounded
對於bounded命令應慎用,一旦新增後就進行修改,只可通過刪除後再新增來實現。

刪除
刪除動作只在該分類沒有工作前才可進行,一旦通過該分類傳送過資料,則無法刪除它了。因此,需要通過shell檔案方式來修改,通過重新啟動來完成刪除動作。

3)過濾器的維護

增添
增添動作通過tc filter add命令實現,如前面所示。

修改
修改動作通過tc filter change命令實現,如下所示:
·tc filter change dev eth0 parent 1:0 protocol ip prio 100 route to 10 flowid 1:8

刪除
刪除動作通過tc filter del命令實現,如下所示:
·tc filter del dev eth0 parent 1:0 protocol ip prio 100 route to 10

4)與過濾器一一對映路由的維護

增添
增添動作通過ip route add命令實現,如前面所示。

修改
修改動作通過ip route change命令實現,如下所示:
·ip route change 192.168.1.30 dev eth0 via 192.168.1.66 realm 8

刪除
刪除動作通過ip route del命令實現,如下所示:
·ip route del 192.168.1.30 dev eth0 via 192.168.1.66 realm 8
·ip route del 192.168.1.0/24 dev eth0 via 192.168.1.66 realm 4

linux下TC控制流量文件c

轉載:自己寫的流量控制檔
自己寫的流量控制檔 tc2
歡迎轉發交流,但請註明原出處資訊.powered by KindGeorge.
http://kindgeorge.at.3322.org
#!/bin/bash
#
指令碼檔名: tc2
#########################################################################################
#
TC(Traffic Control)解決ADSL寬頻速度瓶頸技術 Ver.1.0 powered by KindGeorge
http://kindgeorge.at.3322.org#

#########################################################################################
#
此指令碼經過實驗通過,更多的資訊請參閱http://lartc.org
#tc+iptables+HTB+SFQ
#
#
.什麼是ADSL? ADSLAsymmetric Digital Subscriber Loop,非對稱數字使用者環路)
#用最簡單的話的講,就是採用上行和下行不對等頻寬的基於ATM的技術.
#
舉例,我們最快的其中一條ADSL頻寬是下行3200Kbit,上行只有320Kbit.頻寬通常用bit表示.
#
#1
、下行3200K 意味著什麼?
#因為 1Byte=8Bit ,一個位元組由8個位(bit)組成,一般用大寫B表示Byte,小寫b表示Bit.
#
所以 3200K=3200Kbps=3200K bits/s=400K bytes/s.
#2
上行320K 意味著什麼?
# 320K=320Kbps=320K bits/s=40K bytes/s.
#
就是說,個人所能獨享的最大下載和上傳速度,整條線路在沒任何損耗,最理想的時候,
#
下載只有400K bytes/s,上傳只有最大40K bytes/s的上傳網速.
#
這些都是理想值,但現實總是殘酷的,永遠沒有理想中那麼好.至少也有損耗,何況內部網有幾十臺
#電腦一起瘋狂上網.
#
#3.ADSL
上傳速度對下載的影響
#(1)TCP/IP協議規定,每一個封包,都需要有acknowledge訊息的回傳,也就是說,傳輸的資料,
#需要有一個收到資料的訊息回覆,才能決定後面的傳輸速度,並決定是否重新傳輸遺失
#的資料。上行的頻寬一部分就是用來傳輸這些acknowledge(確認)資料模鄙閒懈涸毓?
#
大的時候,就會影響acknowledge資料的傳送速度,並進而影響到下載速度。這對非對稱
#數字環路也就是ADSL這種上行頻寬遠小於下載頻寬的連線來說影響尤為明顯。
#(2)試驗證明,當上傳滿載時,下載速度變為原來速度的40%,甚至更低.因為上載檔案(包括ftp
#
上傳,發郵件smtp),如果較大,一個人的通訊量已經令整條adsl變得趨向飽和,那麼所有的資料
#包只有按照先進先出的原則進行排隊和等待.這就可以解釋為什麼網內其中有人用ftp上載檔案,
#
或傳送大郵件的時候,整個網速變得很慢的原因。
#
#
.解決ADSL速度之道
#1. 為解決這些速度問題,我們按照資料流和adsl的特點,對經過線路的資料進行了有規則的分流.
#
把本來在adsl modem上的瓶頸轉移到我們linux路由器上,可以把頻寬控制的比adsl modem上的小一點,
#
這樣我們就可以方便的用tc技術對經過的資料進行分流和控制.
#
我們的想象就象馬路上的車道一樣,有高速道,還有小車道,大車道.需要高速的syn,ack,icmp等走
#高速道,需要大量傳輸的ftp-data,smtp等走大車道,不能讓它堵塞整條馬路.各行其道.
#2. linux
下的TC(Traffic Control)就有這樣的作用.只要控制得當,一定會有明顯的效果.
#tc
iptables結合是最好的簡單運用的結合方法.
#
我們設定過濾器以便用iptables對資料包進行分類,因為iptables更靈活,而且你還可以為每個規則設
#置計數器. iptablesmangle鏈來mark資料包,告訴了核心,資料包會有一個特定的FWMARK標記值(hanlde x fw)
#表明它應該送給哪個類( classid x : x),prio是優先值,表明哪些重要資料應該優先通過哪個通道.
#
首先選擇佇列,cbqhtb是不錯的選擇,經過實驗,htb更為好用,所以以下指令碼採用htb來處理
#3. 一般系統預設的是fifo的先進先出佇列,就是說資料包按照先來先處理的原則,如果有一個大的數
#據包在前面,#那麼後面的包只能等前面的發完後才能接著發了,這樣就算後面即使是一個小小的ack,
#
也要等待了,這樣上傳就影響了下載,就算你有很大的下載頻寬也無能為力.
#HTB(Hierarchical Token Bucket,
分層的令牌桶)
#
更詳細的htb參考
http://luxik.cdi.cz/~devik/qos/htb/

#HTB就象CBQ一樣工作,但是並不靠計算閒置時間來整形。它是一個分類的令牌桶過濾器。它只有很少的引數
#他的分層(Hierarchical)能夠很好地滿足這樣一種情況:你有一個固定速率的鏈路,希望分割給多種不同的
#用途使用,為每種用途做出頻寬承諾並實現定量的頻寬借用。
#4. 結構簡圖:
#~~~~~~ |
#~~~~~ __1:__
#~~~~ |~~~~~ |
#~ _ _ _1:1~~~ 1:2_ _ _ _ _ _ _ _
# | ~ ~ | ~ ~ ~ | ~ ~ | ~ ~ | ~ ~ |
#1:11~1:12~~1:21~1:22~1:23~1:24
#
優先順序是1:11 1:12 1:21 1:22 1:23 1:24
#
#--------------------------------------------------------------------------------------------
#5.
根據上面的例子,開始指令碼
#通常adslpppoe連線,的得到的是ppp0,所以公網網絡卡上綁了ppp0
#
關於引數的說明
#(1)rate: 是一個類保證得到的頻寬值.如果有不只一個類,請保證所有子類總和是小於或等於父類.
#(2)ceil: ceil
是一個類最大能得到的頻寬值.
#(3)prio:
是優先權的設定,數值越大,優先權越小.如果是分配剩餘頻寬,就是數值小的會最優先取得剩餘
#的空閒的頻寬權.
#
具體每個類要分配多少rate,要根據實際使用測試得出結果.
#
一般大資料的話,控制在50%-80%左右吧,ceil最大建議不超過85%,以免某一個會話佔用過多的頻寬.
#rate
可按各類所需分配,
#1:11
是很小而且最重要的資料包通道,當然要分多點.甚至必要時先全部佔用,不過一般不會的.所以給全速.
#1:12
是很重要的資料道,給多點,最少給一半,但需要時可以再多一點.
#rate
規劃 1:2 = 1:21 + 1:22 + 1:23 + 1:24 一般總數在50%-80%左右
#1:21 http,pop是最常用的啦,為了太多人用,而導致堵塞,我們不能給得太多,也不能太少.
#1:22
我打算給smtp,優先低於1:21 以防發大的附件大量佔用頻寬,
#1:23
我打算給ftp-data,1:22一樣,很可能大量上傳檔案,所以rate不能給得太多,而當其他有剩時可以給大些,ceil設定大些
#1:24 是無所謂通道,就是一般不是我們平時工作上需要的通道了,給小點,防止這些人在妨礙有正常工作需要的人
#上行 uplink 320K,設定稍低於理論值
DEV="ppp0"
UPLINK=300
#
下行downlink 3200 k 大概一半左右,以便能夠得到更多的併發連線
DOWNLINK=1500
echo "==================== Packetfilter and Traffic Control
流量控制 By 網路技術部 Ver. 1.0===================="
start_routing() {
echo -n "
佇列設定開始start......"
#1.
增加一個根佇列,沒有進行分類的資料包都走這個1:24是預設類:
tc qdisc add dev $DEV root handle 1: htb default 24
#1.1
增加一個根隊下面主幹類1: 速率為$UPLINK k
tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit ceil ${UPLINK}kbit prio 0
#1.1.1
在主幹類1下建立第一葉子類,這是一個最高優先權的類.需要高優先和高速的包走這條通道,比如SYN,ACK,ICMP
tc class add dev $DEV parent 1:1 classid 1:11 htb rate $[$UPLINK]kbit ceil ${UPLINK}kbit prio 1
#1.1.2
在主類1下建立第二葉子類 ,這是一個次高優先權的類。比如我們重要的crm資料.
tc class add dev $DEV parent 1:1 classid 1:12 htb rate $[$UPLINK-150]kbit ceil ${UPLINK-50}kbit prio 2
#1.2
在根類下建立次幹類 classid 1:2 。此次幹類的下面全部優先權低於主幹類,以防重要資料堵塞.
tc class add dev $DEV parent 1: classid 1:2 htb rate $[$UPLINK-150]kbit prio 3
#1.2.1
在次幹類下建立第一葉子類,可以跑例如http,pop.
tc class add dev $DEV parent 1:2 classid 1:21 htb rate 100kbit ceil $[$UPLINK-150]kbit prio 4
#1.2.2
在次幹類下建立第二葉子類。不要太高的速度,以防發大的附件大量佔用頻寬,例如smtp
tc class add dev $DEV parent 1:2 classid 1:22 htb rate 30kbit ceil $[$UPLINK-160]kbit prio 5
#1.2.3
在次幹類下建立第三葉子類。不要太多的頻寬,以防大量的資料堵塞網路,例如ftp-data,
tc class add dev $DEV parent 1:2 classid 1:23 htb rate 15kbit ceil $[$UPLINK-170]kbit prio 6
#1.2.4
在次幹類下建立第四葉子類。無所謂的資料通道,無需要太多的頻寬,以防無所謂的人在阻礙正務.
tc class add dev $DEV parent 1:2 classid 1:24 htb rate 5kbit ceil $[$UPLINK-250]kbit prio 7
#
在每個類下面再附加上另一個佇列規定,隨機公平佇列(SFQ),不被某個連線不停佔用頻寬,以保證頻寬的平均公平使用:
#SFQ(Stochastic Fairness Queueing,隨機公平佇列),SFQ的關鍵詞是會話”(或稱作”)
#主要針對一個TCP會話或者UDP流。流量被分成相當多數量的FIFO佇列中,每個佇列對應一個會話。
#資料按照簡單輪轉的方式傳送, 每個會話都按順序得到傳送機會。這種方式非常公平,保證了每一
#個會話都不會沒其它會話所淹沒。SFQ之所以被稱為隨機,是因為它並不是真的為每一個會話建立
#一個佇列,而是使用一個雜湊演算法,把所有的會話對映到有限的幾個佇列中去。
#引數perturb是多少秒後重新配置一次雜湊演算法。預設為10
tc qdisc add dev $DEV parent 1:11 handle 111: sfq perturb 5
tc qdisc add dev $DEV parent 1:12 handle 112: sfq perturb 5
tc qdisc add dev $DEV parent 1:21 handle 121: sfq perturb 10
tc qdisc add dev $DEV parent 1:22 handle 122: sfq perturb 10
tc qdisc add dev $DEV parent 1:23 handle 133: sfq perturb 10
tc qdisc add dev $DEV parent 1:24 handle 124: sfq perturb 10
echo "
佇列設定成功.done."
echo -n "
設定包過濾 Setting up Filters......"
#
這裡設定過濾器,handle iptablesmark的值,讓被iptables mangle鏈做了mark的不同的值選擇不同的通
#classid,prio 是過濾器的優先級別.
tc filter add dev $DEV parent 1:0 protocol ip prio 1 handle 1 fw classid 1:11
tc filter add dev $DEV parent 1:0 protocol ip prio 2 handle 2 fw classid 1:12
tc filter add dev $DEV parent 1:0 protocol ip prio 3 handle 3 fw classid 1:21
tc filter add dev $DEV parent 1:0 protocol ip prio 4 handle 4 fw classid 1:22
tc filter add dev $DEV parent 1:0 protocol ip prio 5 handle 5 fw classid 1:23
tc filter add dev $DEV parent 1:0 protocol ip prio 6 handle 6 fw classid 1:24
echo "
設定過濾器成功.done."
########## downlink ##########################################################################
#6.
下行的限制:
#
設定入隊的規則,是因為把一些經常會造成下載大檔案的埠進行控制,不讓它們來得太快,導致堵塞.來得太快
#的就直接drop,就不會浪費和佔用機器時間和力量去處理了.
#(1).
把下行速率控制在大概1000-1500k左右,因為這個速度已經足夠用了,以便能夠得到更多的併發下載連線
tc qdisc add dev $DEV handle ffff: ingress
tc filter add dev $DEV parent ffff: protocol ip prio 50 handle 8 fw police rate ${DOWNLINK}kbit burst 10k drop flowid :8
}
#(2).
如果內部網資料流不是很瘋狂的話,就不用做下載的限制了,#符號遮蔽上面兩行即可.
#(3).
如果要對任何進來資料的資料進行限速的話,可以用下面這句:
#tc filter add dev $DEV parent ffff: protocol ip prio 10 u32 match ip src 0.0.0.0/0 police rate ${DOWNLINK}kbit burst 10k drop flowid :1
###############################################################################################
#7.
開始給資料包打標記,往PREROUTING鏈中新增mangle規則:
start_mangle() {
echo -n "
開始給資料包打標記......start mangle mark......"
#(1)
把出去的不同類資料包(dport)mark上標記1--6.讓它走不同的通道
#(2)把進來的資料包(sport)mark上標記8,讓它受到下行的限制,以免速度太過快而影響全域性.
#(3)
每條規則下根著return的意思是可以通過RETURN方法避免遍歷所有的規則,加快了處理速度
##設定TOS的處理:
#iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK --set-mark 1
#iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN
#iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK --set-mark 4
#iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN
#iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j MARK --set-mark 5
#iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j RETURN
##
提高tcp初始連線(也就是帶有SYN的資料包)的優先權是非常明智的:
iptables -t mangle -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN
######icmp,
ping有良好的反應,放在第一類吧.
iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p icmp -j RETURN
# small packets (probably just ACKs)
長度小於64的小包通常是需要快些的,一般是用來確認tcp的連線的,
#
讓它跑快些的通道吧.也可以把下面兩行遮蔽,因為再下面有更多更明細的埠分類.
#iptables -t mangle -A PREROUTING -p tcp -m length --length :64 -j MARK --set-mark 2
#iptables -t mangle -A PREROUTING -p tcp -m length --length :64 -j RETURN
#ftp
放第2,因為一般是小包, ftp-data放在第5,因為一般是大量資料的傳送.
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport ftp -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport ftp -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport ftp-data -j MARK --set-mark 5
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport ftp-data -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp-data -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport ftp-data -j RETURN
##
提高ssh資料包的優先權:放在第1,要知道ssh是互動式的和重要的,不容待慢哦
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 22 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 22 -j RETURN
#
##smtp
郵件:放在第4,因為有時有人傳送很大的郵件,為避免它堵塞,讓它跑4道吧
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 25 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 25 -j RETURN
#iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j MARK --set-mark 8
#iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 25 -j RETURN
## name-domain server
:放在第1,這樣連線帶有域名的連線才能快速找到對應的地址,提高速度的一法
iptables -t mangle -A PREROUTING -p udp -m udp --dport 53 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p udp -m udp --dport 53 -j RETURN
#
## http
:放在第3,是最常用的,最多人用的,
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -j MARK --set-mark 3
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 80 -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 80 -j RETURN
##pop
郵件:放在第3
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 110 -j MARK --set-mark 3
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 110 -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 110 -j RETURN
## https
:放在第3
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 443 -j MARK --set-mark 3
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 443 -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 443 -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 443 -j RETURN
## Microsoft-SQL-Server
:放在第2,我這裡認為較重要,一定要保證速度的和優先的.
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1433 -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1433 -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 1433 -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 1433 -j RETURN
## voip
, 提高,語音通道要保持高速,才不會斷續.
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1720 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1720 -j RETURN
iptables -t mangle -A PREROUTING -p udp -m udp --dport 1720 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p udp -m udp --dport 1720 -j RETURN
## vpn ,
用作voip,也要走高速路,才不會斷續.
iptables -t mangle -A PREROUTING -p udp -m udp --dport 7707 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p udp -m udp --dport 7707 -j RETURN
##
放在第1,因為我覺得它在我心中很重要,優先.
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 7070 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 7070 -j RETURN
## WWW caching service
:放在第3
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 8080 -j MARK --set-mark 3
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 8080 -j RETURN
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 8080 -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 8080 -j RETURN
##
提高本地資料包的優先權:放在第1
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 22 -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p tcp -m tcp --dport 22 -j RETURN
iptables -t mangle -A OUTPUT -p icmp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -p icmp -j RETURN
#
本地small packets (probably just ACKs)
iptables -t mangle -A OUTPUT -p tcp -m length --length :64 -j MARK --set-mark 2
iptables -t mangle -A OUTPUT -p tcp -m length --length :64 -j RETURN
#(4).
PREROUTING中新增完mangle規則後,用這條規則結束PREROUTING表:
##也就是說前面沒有打過標記的資料包將交給1:24處理。
##實際上是不必要的,因為1:24是預設類,但仍然打上標記是為了保持整個設定的協調一致,而且這樣
#還能看到規則的包計數。
iptables -t mangle -A PREROUTING -i $DEV -j MARK --set-mark 6
echo "
標記完畢! mangle mark done!"
}
#-----------------------------------------------------------------------------------------------------
#8.
取消mangle標記用的自定義函式
stop_mangle() {
echo -n "
停止資料標記 stop mangle table......"
( iptables -t mangle -F && echo "ok." ) || echo "error."
}
#9.
取消佇列用的
stop_routing() {
echo -n "(
刪除所有佇列......)"
( tc qdisc del dev $DEV root && tc qdisc del dev $DEV ingress && echo "ok.
刪除成功!" ) || echo "error."
}
#10.
顯示狀態
status() {
echo "1.show qdisc $DEV (
顯示上行佇列):----------------------------------------------"
tc -s qdisc show dev $DEV
echo "2.show class $DEV (
顯示上行分類):----------------------------------------------"
tc class show dev $DEV
echo "3. tc -s class show dev $DEV (
顯示上行佇列和分類流量詳細資訊):------------------"
tc -s class show dev $DEV
echo "
說明:設定總佇列上行頻寬 $UPLINK k."
echo "1. classid 1:11 ssh
dns、和帶有SYN標記的資料包。這是最高優先權的類包並最先類 "
echo "2. classid 1:12
重要資料,這是較高優先權的類。"
echo "3. classid 1:21 web,pop
服務 "
echo "4. classid 1:22 smtp
服務 "
echo "5. classid 1:23 ftp-data
服務 "
echo "6. classid 1:24
其他服務 "
}
#11.
顯示幫助
usage() {
echo "
使用方法(usage): `basename $0` [start | stop | restart | status | mangle ]"
echo "
引數作用:"
echo "start
開始流量控制"
echo "stop
停止流量控制"
echo "restart
重啟流量控制"
echo "status
顯示佇列流量"
echo "mangle
顯示mark標記"
}
#----------------------------------------------------------------------------------------------
#12.
下面是指令碼執行引數的選擇的控制
#
kernel=`eval kernelversion`
case "$kernel" in
2.2)
echo " (!) Error: won't do anything with 2.2.x
不支援核心2.2.x"
exit 1
;;
2.4|2.6)
case "$1" in
start)
( start_routing && start_mangle && echo "
開始流量控制! TC started!" ) || echo "error."
exit 0
;;
stop)
( stop_routing && stop_mangle && echo "
停止流量控制! TC stopped!" ) || echo "error."
exit 0
;;
restart)
stop_routing
stop_mangle
start_routing
start_mangle
echo "
流量控制規則重新裝載!"
;;
status)
status
;;
mangle)
echo "iptables -t mangle -L (
顯示目前mangle表表標記詳細):"
iptables -t mangle -nL
;;
*) usage
exit 1
;;
esac
;;
*)
echo " (!) Error: Unknown kernel version.
check it !"
exit 1
;;
esac
#
.結束語
#1. 如果要支援htb,請到相關網站下載有關補丁.
#
此指令碼是參考http://lartc.org
http://luxik.cdi.cz/~devik/qos/htb/
http://www.docum.org/docum.org
#
和聽取chinaunix.netC++版主JohnBull"Linux的高階路由和流量控制北京沙龍講座錄音
#及關於,經過不斷除錯得出的總結結果,在此感謝所有作出貢獻的人.
#2. iptables,
http://www.iptables.org/ .iptables v1.2.7a tcRed hat linux 9.0下自帶的版本.
#3.
此指令碼已經在Red Hat Linux 9.0核心2.4.20,內網約70臺頻繁上網機器的環境下執行數月,事實證明良好.
#4.
如果ADSL頻寬不同或有變,調節相關rate引數及ceil引數即可.
#5.
還有,如果結合IMQ,IMQ(Intermediate queueing device,中介佇列裝置)把上行和下行都進行分類控制
#就更理想了,但要支援IMQ,就要重新編譯核心.關於補丁和更多的文件請參閱imq網站http://www.linuximq.net/
#6.
歡迎轉載,但請保留原出處 powered by KindGeorge.
http://kindgeorge.at.3322.org
#7. 除了ADSL,還可以進行其他寬頻的控制.
#8.
如果看誰老是在網內搞鬼,經常佔滿頻寬,就把它列為黑名單,並派到"無所謂的資料通道",以防無所謂的人
#在阻礙正務: iptables -t mangle -I PREROUTING 1 -s 192.168.xxx.xxx -j MARK --set-mark 6
# iptables -t mangle -I PREROUTING 2 -s 192.168.xxx.xxx -j RETURN
#9.
使用方法: 整篇文件拷貝後,chmod +x tc2 ,
#
執行指令碼: ./tc2 start (或其他引數start | stop | restart | status | mangle )即可
#如果想每次在ppp啟動時就啟動,則在/etc/ppp/ip-up 檔案裡面加上一句: /路徑/tc2 restart
#10.
結合web介面的流量監測就更完美了,以下彙總
#用免費流量監控進行流量監測相關例子可以參閱:http://blog.chinaunix.net/article.php?articleId=15921&blogId=4543
echo "script done!"
exit 1
#end----------------------------------------------------------------------------------------

linux tc實現ip流量限制

安裝系統:redhat linux as 4  2.6.9

轉載文件1:

  摘要

  tc是個配置Linux核心流量控制的工具

  名字

    tc - 顯示/維護流量控制配置

  摘要

  tc qdisc [ add | change | replace | link ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ]

  tc class [ add | change | replace ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ]

  tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id

  tc [-s | -d ] qdisc show [ dev DEV ]

  tc [-s | -d ] class show dev DEV tc filter show dev DEV

  簡介

  Tc用於Linux核心的流量控制。流量控制包括以下幾種方式:

SHAPING(限制)

  當流量被限制,他的傳輸速率就被控制在某個值以下。限制值能夠大大小於有效頻寬,這樣能夠平滑突發資料流量,使網路更為穩定。shaping(限制)只適用於向外的流量。

SCHEDULING(排程) bitsCN.Com

  通過排程資料包的傳輸,能夠在頻寬範圍內,按照優先順序分配頻寬。SCHEDULING(排程)也只適於向外的流量。

POLICING(策略)

SHAPING用於處理向外的流量,而POLICIING(策略)用於處理接收到的資料。

DROPPING(丟棄)

假如流量超過某個設定的頻寬,就丟棄資料包,不管是向內還是向外。

流量的處理由三種物件控制,他們是:qdisc(排隊規則)、class(類別)和filter(過濾器)。

QDISC(排隊規則)
  QDisc(排隊規則)是queueing discipline的簡寫,他是理解流量控制(traffic control)的基礎。無論何時,核心假如需要通過某個網路介面傳送資料包,他都需要按照為這個介面配置的qdisc(排隊規則)把資料包加入佇列。然後,核心會盡可能多地從qdisc裡面取出資料包,把他們交給網路介面卡驅動模組。

最簡單的QDisc是pfifo他不對進入的資料包做任何的處理,資料包採用先入先出的方式通過佇列。但是,他會儲存網路介面一時無法處理的資料包。

CLASS(類)
  某些QDisc(排隊規則)能夠包含一些類別,不同的類別中能夠包含更深入的QDisc(排隊規則),通過這些細分的QDisc還能夠為進入的佇列的資料包排隊。通過配置各種類別資料包的離隊次序,QDisc能夠為配置網路資料流量的優先順序。

FILTER(過濾器)
  filter(過濾器)用於為資料包分類,決定他們按照何種QDisc進入佇列。無論何時資料包進入一個劃分子類的類別中,都需要進行分類。分類的方法能夠有多種,使用fileter(過濾器)就是其中之一。使用filter(過濾器)分類時,核心會呼叫附屬於這個類(class)的任何過濾器,直到返回一個判決。假如沒有判決返回,就作進一步的處理,而處理方式和QDISC有關。   需要注意的是,filter(過濾器)是在QDisc內部,他們不能作為主體。

CLASSLESS QDisc(不可分類QDisc)
  無類別QDISC包括:

[p|b]fifo

 使用最簡單的qdisc,純粹的先進先出。只有一個引數:limit,用來配置佇列的長度,pfifo是以資料包的個數為單位;bfifo是以位元組數為單位。

   pfifo_fast

在編譯核心時,假如打開了高階路由器(Advanced Router)編譯選項,pfifo_fast就是系統的標準QDISC。他的佇列包括三個波段(band)。在每個波段裡面,使用先進先出規則。而三個波段(band)的優先順序也不相同,band 0的優先順序最高,band 2的最低。假如band 0裡面有資料包,系統就不會處理band 1裡面的資料包,band 1和band 2之間也是相同。資料包是按照服務型別(Type of Service,TOS)被分配多三個波段(band)裡面的。 [url]www.bitsCN.com[/url]

Red

red是Random Early Detection(隨機早期探測)的簡寫。假如使用這種QDISC,當頻寬的佔用接近於規定的頻寬時,系統會隨機地丟棄一些資料包。他很適合高頻寬應用。

Sfq

sfq是Stochastic Fairness Queueing的簡寫。他按照會話(session--對應於每個TCP連線或UDP流)為流量進行排序,然後迴圈傳送每個會話的資料包。

Tbf

tbf是Token Bucket Filter的簡寫,適合於把流速降低到某個值。

不可分類QDisc的配置

假如沒有可分類QDisc,不可分類QDisc只能附屬於裝置的根。他們的用法如下:

tc qdisc add dev DEV root QDISC QDISC-PARAMETERS

要刪除一個不可分類QDisc,需要使用如下命令:

tc qdisc del dev DEV root

一個網路介面上假如沒有配置QDisc,pfifo_fast就作為預設的QDisc。

CLASSFUL QDISC(分類QDisc)

  可分類的QDisc包括:

CBQ

  CBQ是Class Based Queueing(基於類別排隊)的縮寫。他實現了一個豐富的連線共享類別結構,既有限制(shaping)頻寬的能力,也具備頻寬優先順序管理的能力。頻寬限制是通過計算連線的空閒時間完成的。空閒時間的計算標準是資料包離隊事件的頻率和下層連線(資料鏈路層)的頻寬。

[url]www.bitsCN.com[/url]

HTB

HTB是Hierarchy Token Bucket的縮寫。通過在實踐基礎上的改進,他實現了一個豐富的連線共享類別體系。使用HTB能夠很容易地確保每個類別的頻寬,雖然他也允許特定的類能夠突破頻寬上限,佔用別的類的頻寬。HTB能夠通過TBF(Token Bucket Filter)實現頻寬限制,也能夠劃分類別的優先順序。

PRIO

PRIO QDisc不能限制頻寬,因為屬於不同類別的資料包是順序離隊的。使用PRIO QDisc能夠很容易對流量進行優先順序管理,只有屬於高優先順序類別的資料包全部發送完畢,才會傳送屬於低優先順序類別的資料包。為了方便管理,需要使用iptables或ipchains處理資料包的服務型別(Type Of Service,ToS)。

操作原理

類(Class)組成一個樹,每個類都只有一個父類,而一個類能夠有多個子類。某些QDisc(例如:CBQ和HTB)允許在執行時動態新增類,而其他的QDisc(例如:PRIO)不允許動態建立類。

允許動態新增類的QDisc能夠有零個或多個子類,由他們為資料包排隊。

此外,每個類都有一個葉子QDisc,預設情況下,這個葉子QDisc使用pfifo的方式排隊,我們也能夠使用其他型別的QDisc代替這個預設的QDisc。而且,這個葉子QDisc有能夠分類,但是每個子類只能有一個葉子QDisc。 bitsCN_com

當一個數據包進入一個分類QDisc,他會被歸入某個子類。我們能夠使用以下三種方式為資料包歸類,但是不是任何的QDisc都能夠使用這三種方式。

tc過濾器(tc filter)

  假如過濾器附屬於一個類,相關的指令就會對他們進行查詢。過濾器能夠匹配資料包頭任何的域,也能夠匹配由ipchains或iptables做的標記。

服務型別(Type of Service)

某些QDisc有基於服務型別(Type of Service,ToS)的內建的規則為資料包分類。

skb->priority

  使用者空間的應用程式能夠使用SO_PRIORITY選項在skb->priority域配置一個類的ID。
  樹的每個節點都能夠有自己的過濾器,但是高層的過濾器也能夠直接用於其子類。
  假如資料包沒有被成功歸類,就會被排到這個類的葉子QDisc的隊中。相關細節在各個QDisc的手冊頁中。

命名規則
  任何的QDisc、類和過濾器都有ID。ID能夠手工配置,也能夠有核心自動分配。

  ID由一個主序列號和一個從序列號組成,兩個數字用一個冒號分開。

QDISC

  一個QDisc會被分配一個主序列號,叫做控制代碼(handle),然後把從序列號作為類的名稱空間。控制代碼採用象10:相同的表達方式。習慣上,需要為有子類的QDisc顯式地分配一個控制代碼。

www_bitscn_com

類(CLASS)

在同一個QDisc裡面的類分享這個QDisc的主序列號,但是每個類都有自己的從序列號,叫做類識別符(classid)。類識別符只和父QDisc有關,和父類無關。類的命名習慣和QDisc的相同。

過濾器(FILTER)
  過濾器的ID有三部分,只有在對過濾器進行雜湊組織才會用到。詳情請參考tc-filters手冊頁。

  單位

tc命令的任何引數都能夠使用浮點數,