tc命令——Linux基於IP進行流量限速

主要參考(全部權利歸原文做者全部):html

      *http://www.cnblogs.com/endsock/archive/2011/12/09/2281519.htmlnode

           *http://blog.163.com/ninja_wk/blog/static/989155620084280154811/web

           *http://www.chinaunix.net/jh/4/16110.htmlapi







1、TC原理 網絡

        

            Linux操做系統中的流量控制器TC(Traffic Control)用於Linux內核的流量控制,主要是經過在輸出端口處創建一個隊列來實現流量控制。session

         接收包從輸入接口進來後,通過流量限制丟棄不符合規定的數據包,由輸入多路分配器進行判斷選擇:dom

         *若是接收包的目的主機是本主機,那麼將該包送給上層處理,不然須要進行轉發,將接收包交到轉發塊(Forwarding Block)處理。spa

         *轉發塊同時也接收本主機上層(TCP、UDP等)產生的包,經過查看路由表,決定所處理包的下一跳。操作系統

         *而後,對包進行排列以便將它們送到輸出接口。.net


         通常只能限制網卡發送的數據包,不能限制網卡接收的數據包,因此能夠經過改變發送次序靠控制傳輸速率。Linux流量控制主要是在輸出接口排列時進行處理和實現的。

         

2、TC規則


       2.一、流量控制方式


       流量控制包括如下幾種方式:


       *SHAPING(限制) 

        ——當流量被限制,它的傳輸速率就被控制在某個值如下。限制值能夠大大小於有效帶寬,這樣能夠平滑突發數據流量,使網絡更爲穩定。shaping(限制)只適用於向外的流量。


       *SCHEDULING(調度)      

      ——經過調度數據包的傳輸,能夠在帶寬範圍內,按照優先級分配帶寬。SCHEDULING(調度)也只適於向外的流量。


       *POLICING(策略)      

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



       *DROPPING(丟棄)      

       ——若是流量超過某個設定的帶寬,就丟棄數據包,不論是向內仍是向外。


      2.二、流量控制處理對象


        流量的處理由三種對象控制,它們是:

           *qdisc(排隊規則)

           *class(類別)

           *filter(過濾器)


        *QDISC(排隊規則)

         ——QDisc(排隊規則)是queueing discipline的簡寫,它是理解流量控制(traffic control)的基礎。不管什麼時候,內核若是須要經過某個網絡接口發送數據包,它都須要按照爲這個接口配置的qdisc(排隊規則)把數據包加入隊列。而後,內核會盡量多地從qdisc裏面取出數據包,把它們交給網絡適配器驅動模塊。最簡單的QDisc是pfifo它不對進入的數據包作任何的處理,數據包採用先入先出的方式經過隊列。不過,它會保存網絡接口一時沒法處理的數據包。


         QDISC的類別以下:


       (1)、CLASSLESS QDisc(不可分類QDisc)


1>無類別QDISC包括:

[p|b]fifo

使用最簡單的qdisc,純粹的先進先出。只有一個參數:limit,用來設置隊列的長度,pfifo是以數據包的個數爲單位;bfifo是以字節數爲單位。


pfifo_fast

在編譯內核時,若是打開了高級路由器(Advanced Router)編譯選項,pfifo_fast就是系統的標準QDISC。它的隊列包括三個波段(band)。在每一個波段裏面,使用先進先出規則。而三個波段(band)的優先級也不相同,band 0的優先級最高,band 2的最低。若是band裏面有數據包,系統就不會處理band 1裏面的數據包,band 1和band 2之間也是同樣。數據包是按照服務類型(Type of Service,TOS)被分配多三個波段(band)裏面的。


red

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


sfq

sfq是Stochastic Fairness Queueing的簡寫。它按照會話(session--對應於每一個TCP鏈接或者UDP流)爲流量進行排序,而後循環發送每一個會話的數據包。


tbf

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


2>不可分類QDisc的配置


若是沒有可分類QDisc,不可分類QDisc只能附屬於設備的根。它們的用法以下:

    tc qdisc add dev DEV root QDISC QDISC-PARAMETERS


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

    tc qdisc del dev DEV root


一個網絡接口上若是沒有設置QDisc,pfifo_fast就做爲缺省的QDisc。


      (2)、CLASSFUL QDISC(分類QDisc)


可分類的QDisc包括:

CBQ

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


HTB

HTB是Hierarchy Token Bucket的縮寫。經過在實踐基礎上的改進,它實現了一個豐富的鏈接共享類別體系。使用HTB能夠很容易地保證每一個類別的帶寬,雖然它也容許特定的類能夠突破帶寬上限,佔用別的類的帶寬。HTB能夠經過TBF(Token Bucket Filter)實現帶寬限制,也可以劃分類別的優先級。


PRIO

PRIO QDisc不能限制帶寬,由於屬於不一樣類別的數據包是順序離隊的。使用PRIO QDisc能夠很容易對流量進行優先級管理,只有屬於高優先級類別的數據包所有發送完畢,纔會發送屬於低優先級類別的數據包。爲了方便管理,須要使用iptables或者ipchains處理數據包的服務類型(Type Of Service,ToS)。



            *CLASS(類)       

            ——某些QDisc(排隊規則)能夠包含一些類別,不一樣的類別中能夠包含更深刻的QDisc(排隊規則),經過這些細分的QDisc還能夠爲進入的隊列的數據包排隊。經過設置各類類別數據包的離隊次序,QDisc能夠爲設置網絡數據流量的優先級。



             *FILTER(過濾器)      

             ——Filter(過濾器)用於爲數據包分類,決定它們按照何種QDisc進入隊列。不管什麼時候數據包進入一個劃分子類的類別中,都須要進行分類。分類的方法能夠有多種,使用fileter(過濾器)就是其中之一。使用filter(過濾器)分類時,內核會調用附屬於這個類(class)的全部過濾器,直到返回一個判決。若是沒有判決返回,就做進一步的處理,而處理方式和QDISC有關。須要注意的是,filter(過濾器)是在QDisc內部,它們不能做爲主體。


         2.三、操做原理


         類(Class)組成一個樹,每一個類都只有一個父類,而一個類能夠有多個子類。某些QDisc(例如:CBQ和HTB)容許在運行時動態添加類,而其它的QDisc(例如:PRIO)不容許動態創建類。容許動態添加類的QDisc能夠有零個或者多個子類,由它們爲數據包排隊。此外,每一個類都有一個葉子QDisc,默認狀況下,這個葉子QDisc使用pfifo的方式排隊,咱們也可使用其它類型的QDisc代替這個默認的QDisc。並且,這個葉子葉子QDisc有能夠分類,不過每一個子類只能有一個葉子QDisc。 當一個數據包進入一個分類QDisc,它會被納入某個子類。

        咱們可使用如下三種方式爲數據包歸類,不過不是全部的QDisc都可以使用這三種方式:


        *tc過濾器(tc filter)

         ——若是過濾器附屬於一個類,相關的指令就會對它們進行查詢。過濾器可以匹配數據包頭全部的域,也能夠匹配由ipchains或者iptables作的標記。


        *服務類型(Type of Service)

        ——某些QDisc有基於服務類型(Type of Service,ToS)的內置的規則爲數據包分類。


        *skb->priority

        ——用戶空間的應用程序可使用SO_PRIORITY選項在skb->priority域設置一個類的ID。

        樹的每一個節點均可以有本身的過濾器,可是高層的過濾器也能夠直接用於其子類。

        若是數據包沒有被成功歸類,就會被排到這個類的葉子QDisc的隊中。相關細節在各個QDisc的手冊頁中。



        2.四、命名規則


           全部的QDisc、類和過濾器都有ID。ID能夠手工設置,也能夠有內核自動分配。ID由一個主序列號和一個從序列號組成,兩個數字用一個冒號分開。


          *QDISC

          ——一個QDisc會被分配一個主序列號,叫作句柄(handle),而後把從序列號做爲類的命名空間。句柄採用象10:同樣的表達方式。習慣上,須要爲有子類的QDisc顯式地分配一個句柄。


          *類(CLASS)

          ——在同一個QDisc裏面的類分享這個QDisc的主序列號,可是每一個類都有本身的從序列號,叫作類識別符(classid)。類識別符只與父QDisc有關,和父類無關。類的命名習慣和QDisc的相同。


          *過濾器(FILTER)

          ——過濾器的ID有三部分,只有在對過濾器進行散列組織纔會用到。詳情請參考tc-filters手冊頁。


          2.五、單位


          tc命令的全部參數均可以使用浮點數,可能會涉及到如下計數單位。

1》帶寬或者流速單位:

kbps                            千字節/秒

mbps                           兆字節/秒

kbit                             KBits/秒

mbit                            MBits/秒

bps或者一個無單位數字      字節數/秒


2》數據的數量單位:

kb或者k                      千字節

mb或者m                    兆字節

mbit                          兆bit

kbit                           千bit

b或者一個無單位數字       字節數


3》時間的計量單位:

s、sec或者secs                              秒

ms、msec或者msecs                       分鐘

us、usec、usecs或者一個無單位數字    微秒



3、TC命令


         tc可使用如下命令對QDisc、類和過濾器進行操做:

        

        *add

        ——在一個節點裏加入一個QDisc、類或者過濾器。添加時,須要傳遞一個祖先做爲參數,傳遞參數時既可使用ID也能夠直接傳遞設備的根。若是要創建一個QDisc或者過濾器,可使用句柄(handle)來命名;若是要創建一個類,可使用類識別符(classid)來命名。


       *remove

       ——刪除有某個句柄(handle)指定的QDisc,根QDisc(root)也能夠刪除。被刪除QDisc上的全部子類以及附屬於各個類的過濾器都會被自動刪除。


       *change

       ——以替代的方式修改某些條目。除了句柄(handle)和祖先不能修改之外,change命令的語法和add命令相同。換句話說,change命令不能必定節點的位置。


       *replace

       ——對一個現有節點進行近於原子操做的刪除/添加。若是節點不存在,這個命令就會創建節點。


       *link

       ——只適用於DQisc,替代一個現有的節點。



4、具體操做


         Linux流量控制主要分爲創建隊列、創建分類和創建過濾器三個方面。


         4.一、基本實現步驟爲:

         (1) 針對網絡物理設備(如以太網卡eth0)綁定一個隊列QDisc;

         (2) 在該隊列上創建分類class;

         (3) 爲每一分類創建一個基於路由的過濾器filter;

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


        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.30。其流量帶寬控制在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,實際分配的帶寬爲1Mbit,可接收衝突的發送最長包數目爲20字節;最大傳輸單元加MAC頭的大小爲1514字節,優先級別爲6,包的平均大小爲1000字節,包間隔發送單元的大小爲8字節,相應於實際帶寬的加權速率爲100Kbit,分類的分離點爲1:0。


      4.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.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主機地址流量控制限制,不要使用子網流量控制限制。如必定須要對直連子網使用子網流量控制限制,則在創建該子網的路由映射前,需將原先由系統創建的路由刪除,纔可完成相應步驟。


      4.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

       這裏主要顯示了經過該隊列發送了13232個數據包,數據流量爲7646731個字節,丟棄的包數目爲0,超過速率限制的包數目爲0。

     2)顯示分類的情況

     簡單顯示指定設備(這裏爲eth0)的分類情況

·#tc class ls dev eth0

     詳細顯示指定設備(這裏爲eth0)的分類情況

·#tc -s class ls dev eth0

    這裏主要顯示了經過不一樣分類發送的數據包,數據流量,丟棄的包數目,超過速率限制的包數目等等。其中根分類(class cbq 1:0)的情況應與隊列的情況相似。

例如,分類class cbq 1:4發送了8076個數據包,數據流量爲5552879個字節,丟棄的包數目爲0,超過速率限制的包數目爲0。

    顯示過濾器的情況

·#tc -s filter ls dev eth0

    這裏flowid 1:2表明分類class cbq 1:2,to 2表明經過路由2發送。

    顯示現有路由的情況

·#ip route

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


5、實例腳本


       5.1 tc限速

# !/bin/sh


touch  /var/lock/subsys/local


echo  1  > /proc/sys/net/ipv4/ip_forward (激活轉發)

route add default  gw  10.0.0.0  (這是加入電信網關,若是你已設了不用這條)

DOWNLOAD=640Kbit    (640/8 =80K ,我這裏限制下載最高速度只能80K
UPLOAD=640Kbit          (640/8 =80K,上傳速度也限制在80K
INET=192.168.0.          (設置網段,根據你的狀況填)
IPS=1                          (這個意思是從192.168.0.1開始)
IPE=200                        (我這設置是從IP192.168.0.1-200這個網段限速,根據自已的須要改)
ServerIP=253                (網關IP
IDEV=eth0
ODEV=eth1

/sbin/tc  qdisc  del  dev  $IDEV root handle 10:
/sbin/tc  qdisc  del  dev  $ODEV  root handle  20:
/sbin/tc  qdisc  add  dev $IDEV  root  handle  10: cbq  bandwidth  100Mbit avpkt  1000
/sbin/tc  qdisc  add  dev  $ODEV  root  handle  20: cbq bandwidth  1Mbit  avpkt  1000
/sbin/tc  class  add  dev $IDEV  parent 10:0  classid  10:1  cbq  bandwidth  100Mbit  rate 100Mbit  allot 1514  weight  1Mbit  prio  8  maxburst  20  avpkt 1000
/sbin/tc  class  add  dev  $ODEV  parent  20:0  classid  20:1 cbq  bandwidth  1Mbit  rate  1Mbit  allot  1514  weitht  10Kbit  prio  8  maxburst  20  avpkt 1000

COUNTER=$IPS
while  [  $COUNTER  -le  $IPE  ]
    do
/sbin/tc  class  add  dev  $IDEV  parent  10:1  classid  10:1$COUNTER  cbq  banwidth  100Mbit  rate  
$DOWNLOAD  allot  1514  weight  20Kbit  prio  5  maxburst  20  avpkt  1000  bounded
/sbin/tc  qdisc  add  dev  $IDEV  parent  10:1$COUNTER  sfq  quantum  1514b  perturb15

/sbin/tc  filter  add  dev  $IDEV  parent  10:0  protocol  ip  prio  100  u32  match  ipdst  $INET$COUNTER  flowid  10:1$COUNTER
      COUNTER=` expr  $COUNTER  +  1  `
done

iptables  -t  nat  -A  POSTROUTING  -o  eth1  - 192.168.0.0/24  -J  MASQUERADE


      5.2 模型

#!/bin/sh
tc qdisc del dev eth7 root &> /dev/null
tc qdisc del dev eth8 root &> /dev/null

#Add qdisc
tc qdisc add dev eth7 root handle 10: htb default 9998
tc qdisc add dev eth8 root handle 10: htb default 9998

#Add htb root node
tc class add dev eth7 parent 10: classid 10:9999 htb rate 1000000kbit ceil 1000000kbit
tc class add dev eth8 parent 10: classid 10:9999 htb rate 1000000kbit ceil 1000000kbit

#Add htb fake default node here
tc class add dev eth7 parent 10:9999 classid 10:9998 htb rate 1000000kbit ceil 1000000kbit
tc class add dev eth8 parent 10:9999 classid 10:9998 htb rate 1000000kbit ceil 1000000kbit

#Add rule node
tc class add dev eth7 parent 10:9999 classid 10:3 htb rate 1kbit ceil 50kbit
tc filter add dev eth7 parent 10: protocol ip handle 3 fw classid 10:3
tc class add dev eth8 parent 10:9999 classid 10:3 htb rate 1kbit ceil 50kbit
tc filter add dev eth8 parent 10: protocol ip handle 3 fw classid 10:3

#Add htb real default node here
tc class change dev eth7 classid 10:9998 htb rate 1kbit ceil 1000000kbit
tc class change dev eth8 classid 10:9998 htb rate 1kbit ceil 1000000kbit

相關文章
相關標籤/搜索