TC 原理介紹
Linux 操作系統中的流量控制器 TC(Traffic Control)用於 Linux 內核的流量控制,主要是通過在輸出端口處建立一個隊列來實現流量控制。Linux流量控制的基本原理如下圖所示。

接收包從輸入接口(Input Interface)進來後,經過流量限制(Ingress Policing)丟棄不符合規定的數據包,由輸入多路分配器(Input De-Multiplexing)進行判斷選擇:如果接收包的目的是本主機,那麼將該包送給上層處理;否則需要進行轉發,將接收包交到轉發塊(Forwarding Block)處理。轉發塊同時也接收本主機上層(TCP、UDP等)產生的包。轉發塊通過查看路由表,決定所處理包的下一跳。然後,對包進行排列以便將它們傳送到輸出接口(Output Interface)。一般我們只能限制網卡發送的數據包,不能限制網卡接收的數據包,所以我們可以通過改變發送次序來控制傳輸速率。Linux 流量控制主要是在輸出接口排列時進行處理和實現的。
TC 規則
1. 流量控制方式
流量控制包括以下幾種方式:
* SHAPING (限制)
* SCHEDULING(調度)
* POLICING(策略)
* DROPPING(丟棄)
2. 流量控制處理對象
流量的處理由三種對象控制,它們是:qdisc (排隊規則)、class (類別) 和 filter (過濾器)。
* QDISC (排隊規則)
* CLASS(類)
* FILTER(過濾器)
3. 操作原理
Classes form a tree, where each class has a single parent. A class may have multiple children. Some qdiscs allow for runtime addition of classes (CBQ, HTB) while others (PRIO) are created with a static number of children. Qdiscs which allow dynamic addition of classes can have zero or more subclasses to which traffic may be enqueued.
Furthermore, each class contains a leaf qdisc which by default has pfifo behaviour though another qdisc can be attached in place. This qdisc may again contain classes, but each class can have only one leaf qdisc.
When a packet enters a classful qdisc it can be classified to one of the classes within. Three criteria are available, although not all qdiscs will use all three:
* tc 過濾器(tc filter)
* 服務類型(Type of Service)
* skb->priority
4. 命名規則
所有的 QDisc、類 和 過濾器 都有ID。ID可以手工設置,也可以有內核自動分配。ID由一個主序列號和一個從序列號組成,兩個數字用一個冒號分開。
* QDISC
* 類(CLASS)
* 過濾器(FILTER)
5、單位
tc 命令的所有參數都可以使用浮點數,可能會涉及到以下計數單位。
* 帶寬或者流速單位:
* 數據的數量單位
* 時間的計量單位
TC 命令
tc 可以使用以下命令對 QDisc、類和過濾器進行操作:
- add
- remove
- change
- replace
- link
命令格式如下:
相關參數說明如下:
具體操作
Linux 流量控制主要分爲建立隊列、建立分類和建立過濾器三個方面。基本實現步驟爲:
環境模擬實例
流量控制器上的以太網卡 (eth1) 的 IP 地址爲 10.5.0.6,在其上建立一個 CBQ (Class Based Queue) 隊列。假設包的平均大小爲 1000 bytes,包間隔發送單元的大小爲 8 byte,可接收衝突的發送最長包數目爲 20 byte。假如有三種類型的流量需要控制:
1. 建立隊列
一般情況下,針對一個網卡只需建立一個隊列。底下命令將一個 cbq 佇列綁定到網絡物理設備 eth1上,其編號爲1:0;網絡物理設備 eth1 的實際帶寬爲10 Mbit,包的平均大小爲 1000 byte;包間隔發送單元的大小爲 8 byte,最小傳輸包大小爲 64 byte。
2. 建立分類
分類建立在隊列之上。一般情況下,針對一個隊列需建立一個根分類,然後再在其上建立子分類。對於分類,按其分類的編號順序起作用,編號小的優先;一旦符合某個分類匹配規則,通過該分類發送數據包,則其後的分類不再起作用。
1) 創建根分類1:1;分配帶寬爲 10Mbit,優先級別爲 8。
2)創建分類1:2,其父分類爲1:1,分配帶寬爲 8Mbit,優先級別爲 2。
3)創建分類1:3,其父分類爲1:1,分配帶寬爲1Mbit,優先級別爲1。
4)創建分類1:4,其父分類爲1:1,分配帶寬爲1Mbit,優先級別爲6。
3. 建立過濾器
過濾器主要服務於分類。一般只需針對 root 分類提供一個過濾器,然後爲每個子分類提供路由映射。
1) 應用路由分類器到 cbq 佇列的 root,父分類編號爲 1:0;過濾協議爲 ip,優先級別爲100,過濾器爲基於路由表。
2) 建立路由映射分類1:2, 1:3, 1:4
4. 建立路由
該路由是與前面所建立的路由映射一一對應。
1) 發往主機 10.5.0.7 的數據包通過分類2轉發 (分類2的速率8Mbit)
2) 發往主機 10.5.0.8 的數據包通過分類3轉發 (分類3的速率1Mbit)
3)發往子網 10.5.1.0/24 的數據包通過分類4轉發 (分類4的速率1Mbit)
注: 一般對於流量控制器所直接連接的網段建議使用IP主機地址流量控制限制,不要使用子網流量控制限制。如一定需要對直連子網使用子網流量控制限制,則在建立該子網的路由映射前,需將原先由系統建立的路由刪除,才可完成相應步驟。
5. 監視
主要包括對現有佇列、分類、過濾器和路由的狀況進行監視。
1)顯示隊列的狀況
2)顯示分類的狀況
3) 顯示過濾器的狀況
4) 顯示現有路由的狀況
如上所示,結尾包含有 realm 的顯示行是起作用的路由過濾器。
6. 維護
主要包括對隊列、分類、過濾器和路由的增添、修改和刪除。增添動作一般依照"隊列->分類->過濾器->路由"的順序進行;修改動作則沒有什麼要求;刪除則依照"路由->過濾器->分類->隊列"的順序進行。
1)隊列的維護
一般對於一臺流量控制器來說,出廠時針對每個以太網卡均已配置好一個隊列了,通常情況下對隊列無需進行增添、修改和刪除動作了。
2)分類的維護
增添: 增添動作通過 tc class add 命令實現,如前面所示。
修改: 修改動作通過 tc class change 命令實現,如下所示:
對於bounded命令應慎用,一旦添加後就進行修改,只可通過刪除後再添加來實現。
刪除: 刪除動作只在該分類沒有工作前纔可進行,一旦通過該分類發送過數據,則無法刪除它了。因此,需要通過shell文件方式來修改,通過重新啓動來完成刪除動作。
3)過濾器的維護
增添: 增添動作通過 tc filter add 命令實現,如前面所示。
修改: 修改動作通過 tc filter change 命令實現,如下所示:
刪除: 刪除動作通過 tc filter del 命令實現,如下所示:
4)與過濾器一一映射路由的維護
增添: 增添動作通過 ip route add 命令實現,如前面所示。
修改: 修改動作通過ip route change命令實現,如下所示:
刪除: 刪除動作通過 ip route del 命令實現,如下所示:
Supplement
* 用 CBQ 進行頻寬管理 (Using Class Based Queueing for bandwidth management)
* 18 commands to monitor network bandwidth on Linux server
沒有留言:
張貼留言