Linux tc QOS 詳解


 

 

Linux tc QOS 詳解

Linux tc 詳解

發表於 2013/04/15wy182000

眾所周知,在互聯網誕生之初都是各個高校和科研機構相互通訊,並沒有網絡流量控制方面的考慮和設計,IP協議的原則是盡可能好地為所有數據流服務, 不同的數據流之間是平等的。然而多年的實踐表明,這種原則並不是最理想的,有些數據流應該得到特別的照顧, 比如,遠程登錄的交互數據流應該比數據下載有更高的優先級。

針對不同的數據流采取不同的策略,這種可能性是存在的。並且,隨着研究的發展和深入, 人們已經提出了各種不同的管理模式。IETF已經發布了幾個標准, 如綜合服務(Integrated Services)、區分服務(Diferentiated Services)等。其實,Linux內核從2 2開始,就已經實現了相關的流量控制功能。本文將介紹Linux中有關流量控制的相關概念, 用於流量控制的工具TC的使用方法,並給出幾個有代表性實例。

  一、相關概念

由此可以看出, 報文分組從輸入網卡(入口)接收進來,經過路由的查找, 以確定是發給本機的,還是需要轉發的。如果是發給本機的,就直接向上遞交給上層的協議,比如TCP,如果是轉發的, 則會從輸出網卡(出口)發出。網絡流量的控制通常發生在輸出網卡處。雖然在路由器的 入口處也可以進行流量控制,Linux也具有相關的功能, 但一般說來, 由於我們無法控制自己網絡之外的設備, 入口處的流量控制相對較難。本文將集中介紹出口處的流量控制。流量控制的一個基本概念是隊列(Qdisc),每個網卡都與一個隊列(Qdisc)相聯系, 每當內核需要將報文分組從網卡發送出去, 都會首先將該報文分組添加到該網卡所配置的隊列中, 由該隊列決定報文分組的發送順序。因此可以說,所有的流量控制都發生在隊列中,詳細流程圖見圖1。

clip_image001

圖1報文在Linux內部流程圖

有些隊列的功能是非常簡單的, 它們對報文分組實行先來先走的策略。有些隊列則功能復雜,會將不同的報文分組進行排隊、分類,並根據不同的原則, 以不同的順序發送隊列中的報文分組。為實現這樣的功能,這些復雜的隊列需要使用不同的過濾器(Filter)來把報文分組分成不同的類別(Class)。 這里把這些復雜的隊列稱為可分類(ClassfuI)的隊列。通常, 要實現功能強大的流量控制, 可分類的隊列是必不可少的。因此,類別(class)和過濾器(Filter)也是流量控制的另外兩個重要的基本概念。圖2所示的是一個可分類隊列的例 子。

clip_image002

圖2多類別隊列

由圖2可以看出,類別(CIass)和過濾器(Filter)都是隊列的內部結構, 並且可分類的隊列可以包含多個類別,同時,一個類別又可以進一步包含有子隊列,或者子類別。所有進入該類別的報文分組可以依據不同的原則放入不同的子隊列 或子類別中,以此類推。而過濾器(Filter)是隊列用來對數據報文進行分類的工具, 它決定一個數據報文將被分配到哪個類別中。

  二、使用TC

在Linux中,流量控制都是通過TC這個工具來完成的。通常, 要對網卡進行流量控制的配置,需要進行如下的步驟:

◆ 為網卡配置一個隊列;

◆ 在該隊列上建立分類;

◆ 根據需要建立子隊列和子分類;

◆ 為每個分類建立過濾器。

在Linux中,可以配置很多類型的隊列,比如CBQ、HTB等,其中CBQ 比較復雜,不容易理解。HTB(HierarchicaIToken Bucket)是一個可分類的隊列, 與其他復雜的隊列類型相比,HTB具有功能強大、配置簡單及容易上手等優點。在TC 中, 使用"major:minor"這樣的句柄來標識隊列和類別,其中major和minor都是數字。

對於隊列來說,minor總是為0,即"major:0"這樣的形式,也可以簡寫為"major: 比如,隊列1:0可以簡寫為1:。需要注意的是,major在一個網卡的所有隊列中必須是惟一的。對於類別來說,其major必須和它的父類別或父隊列的 major相同,而minor在一個隊列內部則必須是惟一的(因為類別肯定是包含在某個隊列中的)。舉個例子,如果隊列2:包含兩個類別,則這兩個類別的 句柄必須是2:x這樣的形式,並且它們的x不能相同, 比如2:1和2:2。

下面,將以HTB隊列為主,結合需求來講述TC的使用。假設eth0出口有100mbit/s的帶寬, 分配給WWW 、E-mail和Telnet三種數據流量, 其中分配給WWW的帶寬為40Mbit/s,分配給Email的帶寬為40Mbit/s, 分配給Telnet的帶寬為20Mbit/S。如圖3所示。

需要注意的是, 在TC 中使用下列的縮寫表示相應的帶寬:

◆ Kbps kiIobytes per second, 即"千字節每秒 ;

◆ Mbps megabytes per second, 即"兆字節每秒 ,

◆ Kbit kilobits per second,即"千比特每秒 ;

◆ Mbit megabits per second, 即"兆比特每秒 。

  三、創建HTB隊列

有關隊列的TC命令的一般形式為:

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

首先,需要為網卡eth0配置一個HTB隊列,使用下列命令:

#tc qdisc add dev eth0 root handle 1:htb default 11

這里,命令中的"add 表示要添加,"dev eth0 表示要操作的網卡為eth0。"root 表示為網卡eth0添加的是一個根隊列。"handle 1: 表示隊列的句柄為1:。"htb 表示要添加的隊列為HTB隊列。命令最后的"default 11 是htb特有的隊列參數,意思是所有未分類的流量都將分配給類別1:11。

  四、為根隊列創建相應的類別

有關類別的TC 命令的一般形式為:

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

可以利用下面這三個命令為根隊列1創建三個類別,分別是1:1 1、1:12和1:13,它們分別占用40、40和20mb[t的帶寬。

#tc class add dev eth0 parent 1: classid 1:1 htb rate 40mbit ceil 40mbit

#tc class add dev eth0 parent 1: classid 1:12 htb rate 40mbit ceil 40mbit

#tc class add dev eth0 parent 1: cllassid 1:13 htb rate 20mbit ceil 20mbit

命令中,"parent 1:"表示類別的父親為根隊列1:。"classid1:11"表示創建一個標識為1:11的類別,"rate 40mbit"表示系統

將為該類別確保帶寬40mbit,"ceil 40mbit",表示該類別的最高可占用帶寬為40mbit。

  五、為各個類別設置過濾器

有關過濾器的TC 命令的一般形式為:

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

由於需要將WWW、E-mail、Telnet三種流量分配到三個類別,即上述1:11、1:12和1:13,因此,需要創建三個過濾器,如下面的三個命令:

#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff flowid 1:11

#tc filter add dev eth0 prtocol ip parent 1:0 prio 1 u32 match ip dport 25 0xffff flowid 1:12

#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 23 oxffff flowid 1:13

這里,"protocol ip"表示該過濾器應該檢查報文分組的協議字段。"pr[o 1" 表示它們對報文處理的優先級是相同的,對於不同優先級的過濾器, 系統將按照從小到大的優先級。

順序來執行過濾器, 對於相同的優先級,系統將按照命令的先后順序執行。這幾個過濾器還用到了u32選擇器(命令中u32后面的部分)來匹配不同的數據流。以第一個命令為例, 判斷的是dport字段,如果該字段與Oxffff進行與操作的結果是8O,則"flowid 1:11" 表示將把該數據流分配給類別1:1 1。更加詳細的有關TC的用法可以參考TC 的手冊頁。

  六、復雜的實例

在上面的例子中, 三種數據流(www、Email、Telnet)之間是互相排斥的。當某個數據流的流量沒有達到配額時,其剩余的帶寬並不能被其他兩個數據流所借用。在這里將涉及如何使不同的數據流可以共享一定的帶寬。

首先需要用到HTB的一個特性, 即對於一個類別中的所有子類別,它們將共享該父類別所擁有的帶寬,同時,又可以使得各個子類別申請的各自帶寬得到保證。這也就是說,當某個數據流的實際使 用帶寬沒有達到其配額時, 其剩余的帶寬可以借給其他的數據流。而在借出的過程中,如果本數據流的數據量增大,則借出的帶寬部分將收回, 以保證本數據流的帶寬配額。

下面考慮這樣的需求, 同樣是三個數據流WWW、E-mail和Telnet, 其中的Telnet獨立分配20Mbit/s的帶寬。另一方面,VWVW 和SMTP各自分配40Mbit/s。同時,它們又是共享的關系, 即它們可以互相借用帶寬。如圖3所示。

clip_image003

需要的TC命令如下:

#tc qdisc add dev eth0 root handle 1: htb default 21

#tc class add dev eth0 partent 1: classid 1:1 htb rate 20mbit ceil 20mbit

#tc class add dev eth0 parent 1: classid 1:2 htb rate 80mbit ceil 80mbit

#tc class add dev eth0 parent 1: classid 1:21 htb rate 40mbit ceil 20mbit

#tc class add dev eth0 parent 1:2 classid 1:22 htb rate 40mbit ceil 80mbit

#tc filter add dev eth0 protocol parent 10 prio 1 u32 match ip dport 80 0xffff flowid 1:21

#tc filter add dev eth0 protocol parent 1:0 prio 1 u32 match ip dport 25 0xffff flowid 1:22

#tc filter add dev eth0 protocol parent 1:0 prio 1 u32 match ip dport 23 0xffff flowid 1:1

這里為根隊列1創建兩個根類別,即1:1和1:2,其中1:1對應Telnet數據流,1:2對應80Mbit的數據流。然后,在1:2中,創建兩 個子類別1:21和1:22,分別對應WWW和E-mail數據流。由於類別1:21和1:22是類別1:2的子類別,因此他們可以共享分配的 80Mbit帶寬。同時,又確保當需要時,自己的帶寬至少有40Mbit。

從這個例子可以看出,利用HTB中類別和子類別的包含關系,可以構建更加復雜的多層次類別樹,從而實現的更加靈活的帶寬共享和獨占模式,達到企業級的帶寬管理目的。

QOS 無非就是使用了linux的2個工具, tc 和 iptables ,不管管理界面做的多么垃圾還是多么強大,都是最終翻譯成這2個工具的script去執行,並且無論多么NB的管理界面都有很大的局限性(整半天界面也就 是實現了命令行下的幾個參數的功能而已),所以無法完全發揮這2個工具的作用. 不要以為TOMATO的QOS就很NB,其實就是對這2個工具做了比較好的封裝罷了, 都是linux,用好了,分不出什么高下的. 如果你懂linux shell編程, 並且懂數據挖掘與機器學習的理論 ,你完全可以根據一些算法寫出帶有人工智能特性的QOS腳本,wayos的QOS其實就是這么實現的而已. (美好的展望一下,不多說了,進入正題)

TC是干什么的呢:
TC就是建立數據通道的, 建立的通道有數據包管理方式, 通道的優先級, 通道的速率(這就是限速)

iptables又是干什么的呢?
是決定哪個ip 或者 mac 或者某個應用, 走哪個通道的.

這就是QOS+限速的原理, 大伙明白了吧?

想深入的朋友請看
iptables權威指南1.1.9   http://man.chinaunix.net/network/iptables-tutorial-cn-1.1.19.html
tc命令的介紹和用法 http://wenku.baidu.com/view/324fc91a964bcf84b9d57b01.html

詳細的我就不寫了,看上面的好好學習,這里我就貼出來我的學習成果吧,直接可用的限速腳本:
以下說的是單位是kbps, 跟普通迅雷上看到的下載速度的換算關系是 除以8    1600/8 = 200K ,迅雷上看到的就是200KB/s

本帖隱藏的內容

#現在開始用TC建立數據的上行和下行通道
TCA=”tc class add dev br0″
TFA=”tc filter add dev br0″
tc qdisc del dev br0 root
tc qdisc add dev br0 root handle 1: htb
tc class add dev br0 parent 1: classid 1:1 htb rate 1600kbit            #這個1600是下行總速度
$TCA parent 1:1 classid 1:10 htb rate 200kbit ceil 400kbit prio 2     #這個是10號通道的下行速度,最小200,最大400,優先級為2
$TCA parent 1:1 classid 1:25 htb rate 1000kbit ceil 1600kbit prio 1   #這是我自己使用的特殊25號通道,下行速度最小1000,最大1600,優先級為1, 呵呵,待遇就是不一樣
$TFA parent 1:0 prio 2 protocol ip handle 10 fw flowid 1:10
$TFA parent 1:0 prio 1 protocol ip handle 25 fw flowid 1:25
tc qdisc add dev br0 ingress
$TFA parent ffff: protocol ip handle 35 fw police rate 800kbit mtu 12k burst 10k drop      #這是我自己使用的35號上行通道,最大速度800
$TFA parent ffff: protocol ip handle 50 fw police rate 80kbit mtu 12k burst 10k drop         #這是給大伙使用的50號上行通道,最大速度80

#好了,現在用iptables來覺得哪些人走哪些通道吧,哈哈,由於dd wrt的iptables不支持ip range,所以只能每個IP寫一條語句,否則命令無效

iptables -t mangle -A POSTROUTING -d 192.168.1.22 -j MARK –set-mark 10     #ip為192.168.1.22的走10號通道
iptables -t mangle -A POSTROUTING -d 192.168.1.22 -j RETURN                        #給每條規則加入RETURN,這樣效率會更高.
iptables -t mangle -A POSTROUTING -d 192.168.1.23 -j MARK –set-mark 25      #ip為192.168.1.23的走25號特殊通道,23是我的ip,所以特殊點
iptables -t mangle -A POSTROUTING -d 192.168.1.23 -j RETURN                        #給每條規則加入RETURN,這樣效率會更高.

iptables -t mangle -A PREROUTING -s 192.168.1.22 -j MARK –set-mark 50         #ip為22的走50號上行通道
iptables -t mangle -A PREROUTING -s 192.168.1.22 -j RETURN                        #給每條規則加入RETURN,這樣效率會更高.
iptables -t mangle -A PREROUTING -s 192.168.1.23 -j MARK –set-mark 35        #ip為23的走35號上行通道,我自己的IP.呵呵
iptables -t mangle -A PREROUTING -s 192.168.1.23 -j RETURN                        #給每條規則加入RETURN,這樣效率會更高.

#其他的我就不寫了,大家自己換IP吧,想讓誰走哪個通道,就把IP改了執行,現在發發慈悲,讓大家開網頁的時候走我使用25和35號通道吧,當然你也可以不發慈悲
iptables -t mangle -A PREROUTING -p tcp -m tcp –dport 80 -j MARK –set-mark 35    #http的端口號80,所以dport是80,這是發起http請求的時候
iptables -t mangle -A PREROUTING -p tcp -m tcp –dport 80 -j RETURN
iptables -t mangle -A POSTROUTING -p tcp -m tcp –sport 80 -j MARK –set-mark 25   #http的端口號80,所以sport是80,這是http響應回來的時候
iptables -t mangle -A POSTROUTING -p tcp -m tcp –sport 80 -j RETURN

現在來看看如何限制TCP和UDP的連接數吧,很NB的(不知道標准版本和簡化版是否支持,一下語句不保證可用,因個人路由器環境而定):
iptables -I FORWARD -p tcp -m connlimit –connlimit-above 100 -j DROP           #看到了吧,在FORWARD轉發鏈的時候,所有tcp連接大於100 的數據包就丟棄!是針對所有IP的限制
iptables -I FORWARD -p udp -m limit –limit 5/sec -j DROP   #UDP是無法控制連接數的, 只能控制每秒多少個UDP包, 這里設置為每秒5個,5個已經不少了,10個就算很高了,這個是封殺P2P的利器,一般設置為每秒3~5個比較合理.
如何查看命令是否生效呢?:
執行  iptables -L FORWARD 就可以看到如下結果:
DROP       tcp  –  anywhere             anywhere            #conn/32 > 100
DROP       udp  –  anywhere             anywhere            limit: avg 5/sec bu
如果出現了這2個結果,說明限制連接數的語句確實生效了, 如果沒有這2個出現,則說明你的dd-wrt不支持connlimit限制連接數模塊.

現在我想給自己開個后門,不受連接數的限制該怎么做呢?看下面的:
iptables -I FORWARD -s 192.168.1.23 -j RETURN          #意思是向iptables的FORWARD鏈的最頭插入這個規則,這個規則現在成為第一個規則了,23是我的IP,就是說,只要是我的IP的就不在執行 下面的連接數限制的規則語句了,利用了iptables鏈的執行順序規則,我的IP被例外了.

告訴大家一個查看所有人的連接數的語句:
sed -n ‘s%.* src=\(192.168.[0-9.]*\).*%\1%p’ /proc/net/ip_conntrack | sort | uniq -c    #執行這個就可以看到所有IP當前所占用的連接數

對於上面的腳本,有一些比較疑惑人的地方,現在來講講:
br0 : 這個是一個dd wrt的網橋, 這個網橋橋接了無線和有線的接口, 所以在這上面卡流量,就相當於卡了所有無線和有線的用戶.具體信息可以輸入ifconfig命令進行查看.
規則鏈順序問題 : 在br0上iptables規則鏈的順序是比較奇怪的, 正常的順序 入站的數據包先過 PERROUTING鏈, 出站數據包先過POSTROUTING鏈,但是 dd wrt的br0網橋順序與正常的順序正好相反!
在ddwrt上入站的數據包被當成出站的,出站的數據包被當成入站的,所以上面的腳本會那么寫.

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(調度)
通過調度數據包的傳輸,可以在帶寬范圍內,按照優先級分配帶寬。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里面有數據包,系統就不會處理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的簡寫,適合於把流速降低到某個值。
不可分類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)帶寬的能力,也具有帶寬優先級管理的能力。帶 寬限制是通過計算連接的空閑時間完成的。空閑時間的計算標准是數據包離隊事件的頻率和下層連接(數據鏈路層)的帶寬。
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。
當一個數據包進入一個分類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顯式地分配一個句柄。
類(CLASS)
在同一個QDisc里面的類分享這個QDisc的主序列號,但是每個類都有自己的從序列號,叫做類識別符(classid)。類識別符只與父QDisc有關,和父類無關。類的命名習慣和QDisc的相同。
過濾器(FILTER)
過濾器的ID有三部分,只有在對過濾器進行散列組織才會用到。詳情請參考tc-filters手冊頁。
單位
tc命令的所有參數都可以使用浮點數,可能會涉及到以下計數單位。
帶寬或者流速單位:
kbps
千字節/秒
mbps
兆字節/秒
kbit
KBits/秒
mbit
MBits/秒
bps或者一個無單位數字
字節數/秒
數據的數量單位:
kb或者k
千字節
mb或者m
兆字節
mbit
兆bit
kbit
千bit
b或者一個無單位數字
字節數
時間的計量單位:
s、sec或者secs

ms、msec或者msecs
分鍾
us、usec、usecs或者一個無單位數字
微秒

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

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

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

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

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

歷史
tc由Alexey N. Kuznetsov編寫,從Linux 2.2版開始並入Linux內核。
SEE ALSO
tc-cbq(8)、tc-htb(8)、tc-sfq(8)、tc-red(8)、tc-tbf(8)、tc-pfifo(8)、tc-bfifo(8)、tc-pfifo_fast(8)、tc-filters(8)
Linux從kernel 2.1.105開始支持QOS,不過,需要重新編譯內核。運行make config時將EXPERIMENTAL _OPTIONS設置成y,並且將Class Based Queueing (CBQ), Token Bucket Flow, Traffic Shapers 設置為 y ,運行 make dep; make clean; 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字節,最小傳輸包大小為字節。

tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit avpkt 1000 cell 8 mpu

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,實際分配的帶寬為 Kbit,可接收沖突的發送最長包數目為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 76731 bytes 13232 pkts (dropped 0, overlimits 0)
borrowed 0 overactions 0 avgidle 31 undertime 0

這里主要顯示了通過該隊列發送了13232個數據包,數據流量為76731個字節,丟棄的包數目為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

 

C規則涉及到 隊列(QUEUE) 分類器(CLASS) 過濾器(FILTER),filter划分的標志位可用U32或iptables的set-mark來實現 ) 一般是"控發"不控收 linux下有兩塊網卡,一個eth1是外網,另一塊eth0是內網.在eth0上做HTB。(注 意:filter划分標志位可用u32打標功能或iptables的set-mark功能,如果用iptables來打標記的話,下行速LV在eth0處 控制,但打標應在進入eth0之前進行,所以,“-i eth1";例子:

主要命令就下面三句:創建一個HTB的根

1.tc qdisc add dev eth0 root handle 1: htb default 20創建一個HTB的類,流量的限制就是在這里限制的,並設置突發.

2.tc class add dev eth0 parent 1: classid 1:1 htb rate 200kbit(速率) ceil 200kbit burst 20k(突發流量)

創建一個過濾規則把要限制流量的數據過濾出來,並發給上面的類來限制速度3.tc filter add dev eth0 parent 1: prio 1(優先級) protocol ip u32 match ip sport 80 0xfff flowid 1:1

說明:讓交互數據包保持較低的延遲時間,並最先取得空閑帶寬,比如:

ssh telnet dns quake3 irc ftp控制 smtp命令和帶有SYN標記的數據包,都應屬於這一類。為了保證上行數據流不會傷害下行流,還要把ACK數據包排在隊列前面,因為下行數據的ACK必須同上行流進行竟爭。

TC+IPTABLES+HTB+SFQ

1 tcp/ip 協議規定,每個封包,都需要有ACKNOWLEDGE訊息的回傳,也就是說,傳輸的資料需要有一個收到資料的訊息回復,才能決定后面的傳輸速度,並決定是 否重新傳輸遺失的資料,上行的帶寬一部分就是用來傳輸這些ACK資料的.上行帶寬點用大的時候,就會影響ACK資料的傳送速度,並進而影響到下載速度,

2 試驗證明,當上傳滿載時,下載速度變為原來速度的40%,甚至更低,,因為上載文件(包括ftp上傳,發郵件SMTP),如果較大,一個的通訊量令帶寬超 向包和,那么所有的數據包按照先進先出的原則進行排隊和等待,這就可以解釋為什么網內其中有人用ftp上載文件或發送大郵件的時候,整個網速變得很慢的原 因.

解決速度之道:

1 為了解決這些速度問題,對經過線路的數據進行了有規則的分流.把本來在寬帶上的瓶頸轉移到我們的LINUX路由器上,可以把帶寬控制的比我們購買的帶寬小一點. 這樣,我們就可以方便的用tc技術對經過的數據進行分流與控制.

我們的想像就像馬路上的車道一樣,有高速道,還有小車道,大車道,需要高速的syn ack icmp ssh等走高速道,需要大量傳輸的ftp-data,smtp等走大車道,不能讓它堵塞整條馬路,各行其道.

linux下的TC(traffic control)就有這樣的作用,只要控制得當,一定會有明顯的效果.tc 和iptables結合是最好的簡單運用的結合方法.

我 們設置過濾器以便用iptables對數據包進行分類,因為iptables更靈活,而且還可以為每個規則設置計數器,iptables用mangle鏈 來mark數據包,告訴了內核,數據包會有一個特定的FWMARK標記值(handle x fw) 表明它應該送給那個類(classid x:x),而prio是優先值,表明那些重要數據應該優先通過那個通道,首先選擇隊列(選擇htb),

一般系統默認的是fifo的先進先出隊列,就是說包是按照先來先處理的原則,如果有一個大的數據包在前面,那么后面的包只能等前面的發完后才能接着發了,這樣就算后面既使是一個小小的ack包,也要等待了,這樣上傳就影響了下載,就算你有很大的下載帶寬也無能為力.

HTB(Hierarchical token bucket,分層的令牌桶),就像CBQ一樣工作,但是並不靠計算閑置時間來整形,它是一個分類的令牌桶過濾器.,它只有很少的參數.

結構簡圖:             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

根據上面的例子,開始腳本:

關於參數的說明:

rate:是一個類保證得到的帶寬值,如果有不只一個類,請保證所有子類總和是小於或等於父類,

ceil: ceil是一個類最大能得到帶寬值.

prio: 是優先權的設置,數值越大,優先權越小,如果是分配剩余帶寬,就是數值小的會最優先取得剩余的空閑的帶寬權.

一般大數據的話,控制在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 3200K大概一半左右,以便能夠得到更多的關發連接.

DOWNLINK=1500

1 曾加一個根隊列,沒有進行分類的數據包都走這個1:24是缺省類:

tc qdisc add dev $DEV parent 1: htb default 24

1.1 增加一個根隊下面主干類1: 速率為$UPLINK k

tc cladd 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 qidsc 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 qidsc add dev $DEV parent 1:22 handle 122: sfq perturb 10

tc qidsc add dev $DEV parent 1:23 handle 123: sfq perturb 10

tc qidsc add dev $DEV parent 1:24 handle 124: sfq perturb 10

設置過濾器,handle是iptables作mark的值,讓被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

##################################################

##################################

下行的限制:

# 設置入隊的規則,是因為把一些經常會造成下載大文件的端口進行控制,不讓他們來得太快,導致堵塞,來得太快,就直接drop,就不會浪費和占用機器時間和力量去處理了.

1 把下行速率控制在大概1000-1500K(大約為帶寬的50%),因為這個速度已經夠用了,以便能夠得到更多的並發下載連接.

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

如果內部網數據流不是很瘋狂的話,就不用做下載的限制了,用#符號屏蔽上面兩行既可.

如果要對任何進來的數據進行限速的話,可以用下面這句.

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

################################

開始給數據包打標記

把出去的不同類數據包(為dport)給mark上標記1---6,讓它走不同的通道.

把進來的數據包(為sport)給mark上標記8,讓它受到下行的限制,以免速度太快而影響全局.

每條規則下跟着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-Througput -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放第二類,因為一般是小包,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 PRETOUTING -p tcp -m tcp --dport ftp-data -j MARK --set-mark 5

iptables -t mangle -A PREROUTING -p tcp -m tcp --dport -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 -j RETURN

##SMTP郵件,放在第4類,因為有時有人發送很大的郵件,為避免它堵塞,讓它跑第4道吧

iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 25 -j MARK --st-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 --dprot 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

###MICSOSOFT-SQL-SERVE:放在第2類,我這里認為較重要,一定保證速度和優先的

iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 1433 -j MARK --set-mark 3

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

##https:放在第3類

iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 443 -j MARK --set-mark 3

iptables -t mangle -A PREROUTING -p tcpm -m tcp --dport 443 -j RETURN

iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 443 -j MAKR --set-mark 8

iptables -t mangle -A PREROUTING -P tcp -m tcp --sport 443 -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 tcp -m tcp --sport 1720 -j MAKR --set-mark 8

iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 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 -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 packet (probably just ACKS)

iptables -t mangle -A OUTPUT -p tcp -m length --length :64 --set-mark 2

iptables -t mangle -A OUTPUT -p tcp -m length --length :64 -j RETURN

#################################################

## 向PRETOUTRIN中添加完mangle規則后,用這條規則結束prerouting表:也就是說前面沒有打過標記的數據包就交給1:24來處理實際 上是不必要的,因為1:24是缺省類,但仍然打上標記是為了保持整個設置 的協調一致,而且這樣,還能看到規則的數據包計數:

iptables -t mangle -A PREROUTING -i $DEV -j MARK --set-mark 6

###對某人限制:iptables -t mangle -I PREROUTING 1 -s 192.168.xx.xx -j MAKR --set-mark 6

###iptables -t mangle -I PREROUTING 2 -s 192.168.xx.xx -j RETURN

###################################################

u32的應用:

tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 ...... 這就是所謂的u32匹配,可以匹配數據包的任意部分.

根據源/目的地址: match ip src 0.0.0.0/0

match ip dst 1.2.3.0/24

單個IP地址可以用/32來表示

根據源/目的端口可以這樣表示: match ip sport 80 0xffff

match ip dport 80 0xffff

根據IP協議: match ip protocol (udp tcp icmp gre ipsec)

比如icmp協議是1 match ip protocol 1 0xff

舉例:

tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 match ip dst 4.3.2.1/32 flowid 10:1

tc filter add dev $DEV parent 1:0 protocol ip prio 1

u32 match ip src 4.3.2.1/32 match ip sport 80 0xffff flowid 10:1

#!/bin/bash
#腳本文件名: tc2
#########################################################################################
#用TC(Traffic Control)解決ADSL寬帶速度技術 Ver. 1.0 by KindGeorge 2004.12.27 #
#########################################################################################
#此腳本經過實驗通過,更多的信息請參閱http://lartc.org
#tc+iptables+HTB+SFQ
#
#一.什么是ADSL? ADSL(Asymmetric 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更靈活,而且你還可以為每個規則設
#置計數器. iptables用mangle鏈來mark數據包,告訴了內核,數據包會有一個特定的FWMARK標記值(hanlde x fw),
#表明它應該送給哪個類( classid x : x),而prio是優先值,表明哪些重要數據應該優先通過哪個通道.
#首先選擇隊列,cbq和htb是不錯的選擇,經過實驗,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.根據上面的例子,開始腳本
#通常adsl用pppoe連接,的得到的是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 是iptables作mark的值,讓被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
#三.結束語

 

 

 

轉自 :http://www.wy182000.com/2013/04/15/linux-tc-%E8%AF%A6%E8%A7%A3/

 

 

下一篇:Linux 流量控制實施指南

http://www.wy182000.com/2013/04/17/linux-%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6%E5%AE%9E%E6%96%BD%E6%8C%87%E5%8D%97/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM