Linux 流量控制TC

名稱: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操作系統中的流量控制器TCTraffic Control)用於Linux內核的流量控制,它利用隊列規定建立處理數據包的隊列,並定義隊列中的數據包被髮送的方式, 從而實現對流量的控制。TC模塊實現流量控制功能使用的隊列規定分爲兩類,一類是無類隊列規定, 另一類是分類隊列規定。 無類隊列規定相對簡單,而分類隊列規定則引出了分類和過濾器等概念,使其流量控制功能增強。

無類隊列規定是對進入網絡設備(網卡的數據流不加區分統一對待的隊列規定。使用無類隊列規定形成的隊列能夠 接受數據包以及重新編排、延遲或丟棄數據包。這類隊列規 定形成的隊列可以對整個網絡設備網卡的流量進行整形, 但 不能細分各種情況… 。常用的無類隊列規定主要有pfifo _fast (先進現出TBF ( 令牌桶過濾器SFQ(隨機公平隊列ID (前 向隨機丟包)等等。這類隊列規定使用的流量整形手段主要 是排序、 限速和丟包。

分類隊列規定是對進入網絡設備的數據包根據不同的需求以分類的方式區分對待的隊列規定。 數據包進入一個分類的隊列後, 它就需要被送到某一個類中, 也就是說需要對數據包做分類處理。對數據包進行分類的工具是過濾器,過濾器會返回一個決定,隊列規定就根據這個決定把數據包送入相應的類進行排隊。每個子類都可 以再次使用它們的過濾器進行進一步的分類。直到不需要進一步分類時, 數據包才進入該類包含的隊列排隊。 除了能夠包含其它隊列規定之外, 絕大多數分類的隊列規定還能夠對流量進行整形。 這對於需要同時進行調度如使用 S F Q ) 和流量控制的場合非常有用。

Linux流量控制的基本原理如下圖所示。


接收包從輸入接口(Input Interface)進來後,經過流量限制(Ingress Policing)丟棄不符合規定的數據包,由輸入多路分配器(Input De-Multiplexing)進行判斷選擇:如果接收包的目的是本主機,那麼將該包送給上層處理;否則需要進行轉發,將接收包交到轉發塊(Forwarding Block)處理。轉發塊同時也接收本主機上層(TCPUDP等)產生的包。轉發塊通過查看路由表,決定所處理包的下一跳。然後,對包進行排列以便將它們傳送到輸出接口(Output Interface)。一般我們只能限制網卡發送的數據包,不能限制網卡接收的數據包,所以我們可以通過改變發送次序來控制傳輸速率。Linux流量控制主要是在輸出接口排列時進行處理和實現的。

 

TC規則

3.1、流量控制方式

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

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

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

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

DROPPING(丟棄)
       如果流量超過某個設定的帶寬,就丟棄數據包,不管是向內還是向外。

3.2、流量控制處理對象

流量的處理由三種對象控制,它們是:qdisc(排隊規則)class(類別)filter(過濾器)

QDisc(排隊規則)queueing discipline的簡寫,它是理解流量控制(traffic control)的基礎。無論何時,內核如果需要通過某個網絡接口發送數據包,它都需要按照爲這個接口配置的qdisc(排隊規則)把數據包加入隊列。然後,內核會儘可能多地從qdisc裏面取出數據包,把它們交給網絡適配器驅動模塊。最簡單的QDiscpfifo它不對進入的數據包做任何的處理,數據包採用先入先出的方式通過隊列。不過,它會保存網絡接口一時無法處理的數據包。

QDISC分爲CLASSLESS QDisc和CLASSFUL 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 1band 2之間也是一樣。數據包是按照服務類型(Type of Service,TOS)被分配多三個波段(band)裏面的。

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

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

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

2>無類別QDisc的配置

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

   tc qdisc add dev DEV root QDISC QDISC-PARAMETERS

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

  tc qdisc del dev DEV root 

一個網絡接口上如果沒有設置QDiscpfifo_fast就作爲缺省的QDisc

2)、CLASSFUL QDISC(分類QDisc)

可分類QDISC包括:

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

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

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

3.3、操作原理

(Class)組成一個樹,每個類都只有一個父類,而一個類可以有多個子類。某些QDisc(例如:CBQHTB)允許在運行時動態添加類,而其它的QDisc(例如:PRIO)不允許動態建立類。允許動態添加類的QDisc可以有零個或者多個子類,由它們爲數據包排隊。此外,每個類都有一個葉子QDisc,默認情況下,這個葉子QDisc使用pfifo的方式排隊,我們也可以使用其它類型的QDisc代替這個默認的QDisc。而且,這個葉子葉子QDisc有可以分類,不過每個子類只能有一個葉子QDisc。當一個數據包進入一個分類QDisc,它會被歸入某個子類。我們可以使用以下三種方式爲數據包歸類,不過不是所有的QDisc都能夠使用這三種方式。

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

樹的每個節點都可以有自己的過濾器,但是高層的過濾器也可以直接用於其子類。如果數據包沒有被成功歸類,就會被排到這個類的葉子QDisc的隊中。相關細節在各個QDisc的手冊頁中。

3.4、命名規則

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

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

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

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

3.5、單位

tc命令的所有參數都可以使用浮點數,可能會涉及到以下計數單位。

1)、帶寬或者流速單位:

2)、數據的數量單位:

3)、時間的計量單位:

TC命令

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

add,在一個節點裏加入一個QDisc、類或者過濾器。添加時,需要傳遞一個祖先作爲參數,傳遞參數時既可以使用ID也可以直接傳遞設備的根。如果要建立一個QDisc或者過濾器,可以使用句柄(handle)來命名;如果要建立一個類,可以使用類識別符(classid)來命名。

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

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

replace,對一個現有節點進行近於原子操作的刪除/添加。如果節點不存在,這個命令就會建立節點。

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

例:

、具體操作

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

5.1、基本實現步驟

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

2) 在該隊列上建立分類class

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

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

5.2、環境模擬實例

流量控制器上的以太網卡(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

5.2.1. 建立隊列

一般情況下,針對一個網卡只需建立一個隊列。

將一個cbq隊列綁定到網絡物理設備eth0上,其編號爲1:0;網絡物理設備eth0的實際帶寬爲10 Mbit,包的平均大小爲1000字節;包間隔發送單元的大小爲8字節,最小傳輸包大小爲64字節。

5.2.2. 建立分類

分類建立在隊列之上。

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

1) 創建根分類1:1;分配帶寬爲10Mbit,優先級別爲8

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

2)創建分類1:2,其父分類爲1:1,分配帶寬爲8Mbit,優先級別爲2

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

3)創建分類1:3,其父分類爲1:1,分配帶寬爲1Mbit,優先級別爲1

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

4)創建分類1:4,其父分類爲1:1,分配帶寬爲1Mbit,優先級別爲6

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

5.2.3. 建立過濾器

過濾器主要服務於分類。

一般只需針對根分類提供一個過濾器,然後爲每個子分類提供路由映射。

1) 應用路由分類器到cbq隊列的根,父分類編號爲1:0;過濾協議爲ip,優先級別爲100,過濾器爲基於路由表。

2) 建立路由映射分類1:2, 1:3, 1:4

5.2.4.建立路由

該路由是與前面所建立的路由映射一一對應。

1) 發往主機192.168.1.24的數據包通過分類2轉發(分類2的速率8Mbit)

2) 發往主機192.168.1.30的數據包通過分類3轉發(分類3的速率1Mbit)

3)發往子網192.168.1.0/24的數據包通過分類4轉發(分類4的速率1Mbit)

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

5.2.5. 監視

主要包括對現有隊列、分類、過濾器和路由的狀況進行監視。

1)顯示隊列的狀況

簡單顯示指定設備(這裏爲eth0)的隊列狀況

·tc qdisc ls dev eth0

詳細顯示指定設備(這裏爲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:2to 2代表通過路由2發送。

顯示現有路由的狀況

·ip route

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

5.2.6. 維護

主要包括對隊列、分類、過濾器和路由的增添、修改和刪除。

增添動作一般依照"隊列->分類->過濾器->路由"的順序進行;修改動作則沒有什麼要求;刪除則依照"路由->過濾器->分類->隊列"的順序進行。

六、dms小組應用場景一個實例

前面的內容大多是查找的一些資料,下面將介紹一下dms曾經用到的一個腳本實例,腳本如下:

說明:

tc qdisc add dev eth1 root handle 1: prio用以立一個root(注,這裏的root不是指linuxroot用戶,僅僅單純指“根”這一概念)優先級隊列,句柄爲1對於tc隊列的構成及原理請詳見參考資料[1],上面講得非常透徹),此隊列所作用的網卡接口爲eth1

tc qdisc add dev eth1 parent 1:1 handle 10: netem delay `expr $randdelay`ms distribution normal loss $randloss% 用以在根隊列下建立一個子隊列,子隊列的句柄爲10(當然也可以指定爲其他,一般爲了方便查看,根隊列爲1位數,子隊列爲兩位……),這個子隊列的作用是調用netem模塊讓通過的網絡流量延遲,並按一定的丟包率丟包。(注:netemlinux中的另一個模塊,並不是內嵌於tc工具中,tc僅僅是調用這模塊,所以man tc是看不到相關於netem的信息的,關於netem的使用,詳見參考資料[5]

需要再說明一點是,爲什麼這裏要建一個子隊列。可以看到,我們的目標是針對相關的端口進行流量控制,但子隊列現在的功能是對所有的流量都起作用,因此,需要掛載一個過濾器(filter),對流量進行一個過濾,但在tc中,filter是不能直接掛在根隊列上的。

tc filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip dport 32123 0xffff flowid 1:1子隊列上掛載一個filter,所有通過子隊列1:1的流量,都會被過濾,只有滿足filter條件的流量纔會從該子隊列中通過,這個條件爲“目的地址爲32123IP地址無限制”

發佈了65 篇原創文章 · 獲贊 58 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章