Linux內核TC工具鏈路帶寬設計--HTB隊列規定及簡單的過濾器介紹

1 HTB(Hierarchical Token Bucket, 分層的令牌桶)服務器

      HTB 使用令牌和存儲桶的概念,以及基於類的系統和過濾器,以容許對流量進行復雜和精細的控制。藉助複雜的借用模型,HTB 能夠執行各類複雜的流量控制技術。該隊列規則容許用戶定義所使用的令牌和桶的特徵,並容許用戶以任意方式嵌套這些桶。當與分類方案結合使用時,能夠很是精細地控制流量。HTB 很是適用於這種狀況:若是有一個固定速率的鏈路,但願分割給多種不一樣的用途使用,爲每種用途作出帶寬承諾並實現定量的帶寬借用。HTB 不一樣於 CBQ 的是並不靠計算閒置時間來整形。它是一個分類的令牌桶過濾器。tcp

 

1.1 HTB 的參數介紹spa

defaultcode

      每一個 HTB 隊列的可選參數,默認值爲 0,其意義是任何未分類的流量以物理網卡的速率出隊,徹底繞過鏈接到根隊列的任何分類。若是指定了 default 的值,未分類(不能和 filter 匹配)的流量(默認的)會被送到這個參數所指定的類中。blog

rate隊列

      用來設置限制傳輸的流量速率。ip

ceil路由

      用來設置限制傳輸流量的最大所需速率。若是須要設置共享帶寬,則需使用此參數。這個參數能夠被認爲至關於「可突發帶寬」it

burstio

      桶的大小。前面在討論不可分類的隊列規則時提到過令牌桶過濾器 TBF,桶的概念就是其中的令牌,用於處理數據的傳輸時必要的參數,若是須要具體瞭解能夠參考前面的內容

cburst

      這是 ceil 桶的大小。在等待更多的令牌到來以前,HTB 會使 cburst 字節出列。這裏涉及令牌流與數據流的概念與關係,具體可參考前面不可分類的隊列規定

quantum

      每輪當前的類能發送的字節數,這是用來控制租借帶寬的關鍵參數。其默認計算 quantum = rate / r2q。quantum 必須大於 1500 小於 60000。quantum 只在 class 的流量超過了 rate 可是沒有超過 ceil 時使用,它的值越小,帶寬共享的效果就越好。

 

1.2 配置範例 

      這個配置把 WEB 服務器的流量控制爲 5Mbps、SMTP 流量控制在 3Mbps。並且兩者一共不得超過 6Mbps,互相之間容許借用帶寬。

# sudo tc qdisc add dev enp0s5 root handle 1: htb default 30


# sudo tc class add dev enp0s5 parent 1:0 classid 1:1 htb rate 6Mbit burst 15k 

# sudo tc class add dev enp0s5 parent 1:1 classid 1:10 htb rate 5Mbit burst 15k


# sudo tc class add dev enp0s5 parent 1:1 classid 1:20 htb rate 3Mbit ceil 6Mbit burst 15k 

# sudo tc class add dev enp0s5 parent 1:1 classid 1:30 htb rate 1kbit ceil 6Mbit burst 15k 

      在那些類的下方放置 SFQ: 

# sudo tc qdisc add dev enp0s5 parent 1:10 handle 10: sfq perturb 10 

# sudo tc qdisc add dev enp0s5 parent 1:20 handle 20: sfq perturb 10 

# sudo tc qdisc add dev enp0s5 parent 1:30 handle 30: sfq perturb 10 

      添加過濾器,直接把流量導向相應的類:

# U32="sudo tc filter add dev enp0s5  protocol ip parent 1:0 prio 1 u32" 

# $U32 match ip dport 80 0xffff flowid 1:10


# $U32 match ip sport 25 0xffff flowid 1:20 

      若是 10: 和 20: 都獲得了保證的速率,剩下的就是分割了,它們借用的比率是 5:3。未被分類的流量被送到了 30:,僅有一點點帶寬,可是卻能夠任意借用剩下的帶寬。由於其內部使用了 SFQ,而能夠公平發包。

 

      控制服務器對外的速度爲 20Mbit,服務器只能向外發 20Mbit 的數據包。

# sudo tc qdisc del dev enp0s5 root 2> /dev/null > /dev/null

# sudo tc qdisc add dev enp0s5 root handle 1: htb

# sudo tc class add dev enp0s5 parent 1:0 classid 1:1 rate 100Mbit ceil 100Mbit

# sudo tc class add dev enp0s5 parent 1:1 classid 1:10 rate 20Mbit ceil 20Mbit

# sudo tc qdisc add dev enp0s5 parent 1:10 sfq perturb 10

# sudo tc filter add dev enp0s5 protocol ip parent 1:0 prio 2 u32 match ip dst 192.168.224.60 flowid 1:1

# sudo tc filter add dev enp0s5 protocol ip parent 1:0 prio 2 u32 match ip dst 0.0.0.0/0 flowid 1:10

      上面的命令中建立了兩個分類,第一個分類的速率爲 100Mbit,假設服務器的 IP 爲 192.168.224.60,第一個過濾器是用來處理髮往服務器的數據包,讓全部發往服務器的數據包由 1:1 直接處理,至關於不受限制。而發往其餘目標主機的數據包由 1:10 處理,即服務器只能向外發送 20Mbit 的數據包。若是這裏只建立了一個分類,即上面的 1:10,則全部沒有被分類的數據包會被網卡直接處理,也能達到不對其限制的目的,可是發往服務器的數據包也會被 1:10 所處理,但這並非咱們所須要的,所以須要再建立一個分類,用來單獨處理髮往服務器的數據包,使其不受限制,這個分類的速率能夠盡情的設置很大。

 

2 使用過濾器對數據包進行分類 

      爲了決定用哪一個類處理數據包,必須調用「分類器鏈」進行選擇。這個鏈中包含了這個分類隊列規定所需的全部過濾器。在前面的隊列規定中已經用到了過濾器對數據分類進行處理了,可是沒有作任何介紹,這裏先對其簡單的說明,後面會對經常使用的過濾器再作稍微詳細的說明。

      重複前面那棵樹: 

      當一個數據包入隊的時候,每個分支處都會諮詢過濾器鏈如何進行下一步。典型的配置是在 1:1 處有一個過濾器把數據包交給 12:,而後 12: 處的過濾器在把包交給 12:2。你能夠把後一個過濾器同時放在 1:1 處,從而提升效率。另外,不能用過濾器把數據包向「上」送。並且,使用 HTB 的時候應該把全部的規則放到根上。再次強調:數據包只能向「下」進行入隊操做,只有出隊的時候纔會上到網卡所在的位置來。他們不會落到樹的最底層後送到網卡。

 

2.1 過濾器的一些簡單範例

      下面咱們就開始,從簡單地匹配一些比較明顯的特徵開始。比方說,咱們有一個 PRIO 隊列規定,叫作「10:」,包含 3 個類,咱們但願把去往 22 口的數據流發送到最優先的頻道中去。應該這樣設置過濾器: 

# sudo tc filter add dev enp0s5 protocol ip parent 10: prio 1 u32 match ip dport 22 0xffff flowid 10:1 


# sudo tc filter add dev enp0s5 protocol ip parent 10: prio 1 u32 match ip sport 80 0xffff flowid 10:1 


# sudo tc filter add dev enp0s5 protocol ip parent 10: prio 2 flowid 10:2 

      上述配置是說:向 enp0s5 上的 10: 節點添加一個 u32 過濾規則,它的優先權是 1,凡是去往 22 端口(精確匹配)的 IP 數據包,發送到頻道 10:1。向 enp0s5 上的 10: 節點添加一個 u32 過濾規則,它的優先權是 1,凡是來自 80 端口(精確匹配)的 IP 數據包,發送到頻道 10:1。向 enp0s5 上的 10: 節點添加一個過濾規則,它的優先權是 2,凡是上面未匹配的 IP 數據包,發送到頻道 10:2。別忘了添加「dev enp0s5」(你的網卡或許叫別的名字),由於每一個網卡的句柄都有徹底相同的命名空間。若是想經過 IP 地址進行篩選,能夠採用以下命令: 


# sudo tc filter add dev enp0s5 parent 10:0 protocol ip prio 1 u32 match ip dst 4.3.2.1/32 flowid 10:1 


# sudo tc filter add dev enp0s5 parent 10:0 protocol ip prio 1 u32 match ip src 1.2.3.4/32 flowid 10:1 


# sudo tc filter add dev enp0s5 protocol ip parent 10: prio 2 flowid 10:2

      這個例子把去往 4.3.2.1 和來自 1.2.3.4 的數據包送到了最高優先的隊列,其它的則送到次高優先的隊列。能夠連續使用 match,若是想匹配來自 1.2.3.4 的 80 口的數據包,能夠作以下配置: 

# sudo tc filter add dev enp0s5 parent 10:0 protocol ip prio 1 u32 match ip src 4.3.2.1/32 match ip sport 80 0xffff flowid 10:1

 

2.2 經常使用到的過濾命令一覽 

      這裏列出的絕大多數命令都根據這個命令改編而來:

# sudo tc filter add dev enp0s5 parent 1:0 protocol ip prio 1 u32 ⋯⋯

      這些是「u32」的匹配,能夠匹配數據包的任意部分。

根據源/目的地址:

      源地址段  'match ip src 1.2.3.0/24'

      目的地址段  'match ip dst 4.3.2.0/24'

      單個 IP 地址使用「/32」做爲掩碼便可。

根據源/目的端口,全部 IP 協議:

      源 'match ip sport 80 0xffff' 

      目的 'match ip dport 80 0xffff' 

根據 IP 協議(tcp, udp, icmp, gre, ipsec) :

      使用 /etc/protocols 所指定的數字。好比: icmp 是 1: 'match ip protocol 1 0xff'。

根據 fwmark:

      可使用 ipchains/iptables 給數據包作上標記,而且這個標記會在穿過網卡的路由過程當中保留下來。若是但願對來自 eth0 並從 eth1 發出的數據包作整形,這就頗有用了。語法是這樣的: 

# sudo tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 6fw flowid 1:1 

      注意,這不是一個 u32 匹配。能夠象這樣給數據包打標記: 

# sudo iptables -A PREROUTING -t mangle -i eth0 -j MARK --set-mark 6

      數字 6 是能夠任意指定的。

按TOS 字段:

      選擇交互和最小延遲的數據流: 

# sudo tc filter add dev enp0s5 parent 1:0 protocol ip prio 10 u32 atch ip tos 0x10 0xff flowid 1:4 

      想匹配大量傳輸的話,使用「0x08 0xff」。 

相關文章
相關標籤/搜索