Openwrt配置QOS流量帶寬限制
QoS的底層是tc,其目的就是決定先發送哪些包。openwrt默認的規則是hfsc,設計了四個優先級:最高、高、普通、低 。
說到openwrt,就不能不提一下QoS。尤其是如果你需要用P2P軟件(目前對迅雷的支持還不大好),基本就不能不開QoS。QoS的全稱是Quality of Service,意即服務質量。是專門用於解決擁堵網絡上的信號質量一視同仁的問題。例如,我們有一根寬帶,兩人共用。一個人視頻聊天,一個人bt下載(我還不提迅雷個傻X呢)。玩bt的那個一開軟件,視頻聊天那個立刻沒法用了。bt和視頻聊天稍微好一點的是,視頻聊天消耗的帶寬是恆定的。你可以逐步限速,只要給視頻聊天留了足夠的帶寬,兩個就都能一起用了。但是,如果另一個人不是視頻聊天,而是網絡瀏覽怎么辦?網絡瀏覽,視頻聊天,p2p下載一起來怎么辦?實際上這是很多朋友家中常常碰到的情況。更不說有合租公寓里面你很難監控對方一定限速,軟件無法限速甚至惡意搶占帶寬(迅雷)。另一個更加技術的問題是,由於上傳帶寬不足,ACK包回應過慢,導致你的下載速度也不能達到峰值。玩p2p的常常會給上傳限速到真實帶寬差一點的位置,下載帶寬立刻上去,就是這個道理。
怎么辦?用QoS,解決你多年老便秘。QoS的底層是tc,其目的就是決定先發送哪些包。openwrt默認的規則是hfsc,設計了四個優先級。Priority最優先,處理22,53,icmp,以及小於128字節的syn,ack包中,不屬於bulk類別的。我們可以看到,DNS,syn/ack的優先響應,保證了你的上傳不會影響下載。其次是Express,處理5190和小於500字節的UDP包。這個我也不明白是為什么,好像是視頻什么的。然后是Normal,包括20,21,25,80,110,443,993,995這些常見端口。涵蓋http/https,ftp,郵件系統。最后是Bulk,包括其他包,尤其是ed和bt。
當你啟用QoS后,你的p2p軟件速度應當不會上升,反而會下降。下載速度不好說,有可能是上升,也有可能下降。因為原來p2p軟件搶占了所有帶寬,目前他們只能使用普通應用用剩下的帶寬,速度當然慢了。然而,當你使用瀏覽器,收發郵件的時候,速度應當和不使用p2p的時候一樣流暢。這才是使用QoS最大的意義。
方法很簡單,安裝QoS包,然后修改/etc/config/qos,注意修改你的帶寬。不修改的話,流量會被無意義的限制死。
另外,打開QoS后,千萬記得把你的p2p軟件改為不限速。否則不能達到最高性能。
root@ACU:~# cat /etc/config/qos # QoS configuration for OpenWrt # INTERFACES: config interface wan option classgroup "Default" option enabled 0 option upload 128 option download 1024 # RULES: config classify option target "Priority" option ports "22,53" option comment "ssh, dns" config classify option target "Normal" option proto "tcp" option ports "20,21,25,80,110,443,993,995" option comment "ftp, smtp, http(s), imap" config classify option target "Express" option ports "5190" option comment "AOL, iChat, ICQ" config default option target "Express" option proto "udp" option pktsize "-500" config reclassify option target "Priority" option proto "icmp" config default option target "Bulk" option portrange "1024-65535" # Don't change the stuff below unless you # really know what it means :) config classgroup "Default" option classes "Priority Express Normal Bulk" option default "Normal" config class "Priority" option packetsize 400 option avgrate 10 option priority 20 config class "Priority_down" option packetsize 1000 option avgrate 10 config class "Express" option packetsize 1000 option avgrate 50 option priority 10 config class "Normal" option packetsize 1500 option packetdelay 100 option avgrate 10 option priority 5 config class "Normal_down" option avgrate 20 config class "Bulk" option avgrate 1 option packetdelay 200 root@ACU:~#
tc qdisc del dev eth0 root tc qdisc add dev eth0 root fq_codel target 60ms interval 360ms noecn tc qdisc show dev eth0
IFB是tc過濾器的替代選擇,用於處理入口流量,方法是將其重定向到虛擬接口並將其視為出口流量。每個物理接口需要一個ifb接口,以將入口流量從eth0重定向到ifb0,將eth1重定向到ifb1等等上。
插入ifb模塊時,告訴它所需的虛擬接口數量。默認值為2:
modprobe ifb numifbs=1
現在,啟用所有ifb接口:
ip link set dev ifb0 up # repeat for ifb1, ifb2, ...
並將入口流量從物理接口重定向到相應的ifb接口。對於eth0-> ifb0:
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
再次,重復eth1-> ifb1,eth2-> ifb2,依此類推,直到覆蓋了所有想要塑形的接口。
現在,您可以應用所需的所有規則。eth0的出口規則在eth0中照常進行。讓我們限制帶寬,例如:
tc qdisc add dev eth0 root handle 1: htb default 10
tc class add dev eth0 parent 1: classid 1:1 htb rate 1mbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 1mbit
不用說,重復eth1,eth2,...
eth0的入口規則現在與ifb0的出口規則一樣(所有進入ifb0的東西都必須出來,只有eth0入口流量進入ifb0)。同樣,帶寬限制示例:
tc qdisc add dev ifb0 root handle 1: htb default 10
tc class add dev ifb0 parent 1: classid 1:1 htb rate 1mbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 1mbit
這種方法的優點是出口規則比入口過濾器靈活得多。過濾器僅允許您丟棄數據包,例如,不引入等待時間。通過將入口流量作為出口進行處理,您可以設置隊列規則,流量類別以及(如果需要)過濾器。您不僅可以訪問簡單的過濾器,還可以訪問整個tc樹。
看上去現在tc的還是htb加fq_codel的組合為主流。看一下介紹和源碼,還有別人的例子。
手冊:
====
http://man7.org/linux/man-pages/man8/tc.8.html
http://man7.org/linux/man-pages/man8/tc-ematch.8.html filter分類支持簡單的表達式,cmp/and/or/字節檢查/ipset/xtables等等的
http://man7.org/linux/man-pages/man8/tc-flow.8.html filter分類支持使用flow流表里面的src,dst,iif和NAT前后的nfct-src, nfct-dst,rxhash
來計算hash分類。比如默認fq_codel 是保證流的公平性的吧,但下面這個fq_codel使用NAT前的源ip地址來做fair-queue的隊列選擇。
tc qdisc add dev eth0 parent 1:1 handle 11: fq_codel
tc filter add dev eth0 parent 11: handle 11 protocol all flow hash keys nfct-src divisor 1024
https://man7.org/linux/man-pages/man8/tc-u32.8.html filter根據源ip目的ip,tcp,udp等協議字段以及包里面的任意內容的規則
https://man7.org/linux/man-pages/man8/tc-fw.8.html filter根據skb的mark值來設置規則
https://man7.org/linux/man-pages/man8/tc-flower.8.html filer匹配mac地址和各種流字段
http://man7.org/linux/man-pages/man8/tc-bpf.8.html filter也是支持bpf的自定義擴展的
http://man7.org/linux/man-pages/man8/tc-htb.8.html
http://man7.org/linux/man-pages/man8/tc-fq_codel.8.html
介紹:
=====
https://www.bufferbloat.net/projects/codel/wiki/Best_practices_for_benchmarking_Codel_and_FQ_Codel/
http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm
http://tldp.org/HOWTO/Traffic-Control-HOWTO/classful-qdiscs.html#qc-htb
https://www.linuxjournal.com/article/7562
https://www.cnblogs.com/acool/p/7779159.html
https://www.docum.org/docum.org/tests/htb/burst/
源碼:
=====
https://elixir.bootlin.com/linux/latest/source/net/sched/em_meta.c
https://elixir.bootlin.com/linux/latest/source/net/sched/sch_tbf.c
https://elixir.bootlin.com/linux/latest/source/net/sched/sch_htb.c
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/tc/sch_tbf.c
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/tc/q_htb.c
openwrt的例子:
==============
https://github.com/tohojo/sqm-scripts/blob/master/src/simple.qos
系統幫助
=======
man tc
man tc-htb
man tc-tbf
man tc-fc_codel
centos 7 中 基本表達式中支持的meta
/usr/sbin/tc filter add dev eth1 basic match 'meta(list)'
--------------------------------------------------------
ID Type Description
--------------------------------------------------------
Generic:
random INT Random value (32 bit)
loadavg_1 INT Load average in last minute
loadavg_5 INT Load average in last 5 minutes
loadavg_15 INT Load average in last 15 minutes
Interfaces:
dev INT,VAR Device the packet is on
Packet attributes:
priority INT Priority of packet
protocol INT Link layer protocol
pkt_type INT Packet type (uni|multi|broad|...)cast
pkt_len INT Length of packet
data_len INT Length of data in packet
mac_len INT Length of link layer header
Netfilter:
nf_mark INT Netfilter mark
fwmark INT Alias for nf_mark
Traffic Control:
tc_index INT TC Index
Routing:
rt_classid INT Routing ClassID (cls_route)
rt_iif INT Incoming interface index
vlan INT Vlan tag
Sockets:
sk_family INT Address family
sk_state INT State
sk_reuse INT Reuse Flag
sk_bind_if INT,VAR Bound interface
sk_refcnt INT Reference counter
sk_shutdown INT Shutdown mask
sk_proto INT Protocol
sk_type INT Type
sk_rcvbuf INT Receive buffer size
sk_rmem INT RMEM
sk_wmem INT WMEM
sk_omem INT OMEM
sk_wmem_queue INT WMEM queue
sk_snd_queue INT Send queue length
sk_rcv_queue INT Receive queue length
sk_err_queue INT Error queue length
sk_fwd_alloc INT Forward allocations
sk_sndbuf INT Send buffer size
--------------------------------------------------------
概念:
======
qdisc 是隊列,下面可以包含多個class,每個class就是分類了,可以多個樹形結構的級別,
filter是就是分類規則了,每個class可以設置不同的filter來分類決定包被分到那個子級別的class里面去。
可以先看一下 tc的man page里面THEORY OF OPERATION。小節的說明。 htb的話,根據http://man7.org/linux/man-pages/man8/tc-htb.8.html的說明,
一個包只有被分類的葉子節點了才會正在的被認為分類成功,如果在中間節點就沒有被filter分到葉子節點,最后還是會放到htb 創建時設置的default class id去。
實例
====
tc qdisc show dev eth1
tc -s qdisc show dev eth1
tc -s -d class show dev eth1
tc --g -s class show dev eth1
tc -s filter show dev eth1
tc qdisc del dev eth1 root
tc qdisc add dev eth1 root handle 1: htb default 13 r2q 10
tc class add dev eth1 parent 1: classid 1:1 htb quantum 125000 rate 1000mbit ceil 1000mbit burst 125000 cburst 125000
tc class add dev eth1 parent 1:1 classid 1:11 htb quantum 12500 rate 100mbit ceil 1000mbit burst 12500 cburst 12500 prio 1
tc class add dev eth1 parent 1:1 classid 1:12 htb rate 500mbit ceil 1000mbit burst 15000 cburst 125000 prio 2
tc class add dev eth1 parent 1:1 classid 1:13 htb rate 50mbit ceil 50mbit burst 3000 cburst 3000 prio 3
tc class add dev eth1 parent 1:13 classid 1:14 htb rate 20mbit ceil 20mbit burst 3000 cburst 3000 prio 1
tc class add dev eth1 parent 1:13 classid 1:15 htb rate 30mbit ceil 30mbit burst 3000 cburst 3000 prio 1
tc qdisc add dev eth1 parent 1:11 handle 110: fq_codel quantum 300 limit 1024 flows 2048 ecn
tc qdisc add dev eth1 parent 1:12 handle 120: fq_codel quantum 300 limit 1024 flows 1024 ecn
tc qdisc add dev eth1 parent 1:14 handle 140: fq_codel quantum 300 limit 1024 flows 1024 ecn
tc qdisc add dev eth1 parent 1:15 handle 150: fq_codel quantum 300 limit 1024 flows 1024 noecn
# tc filter add dev eth1 basic match 'meta(pkt_len gt 0)' flowid 1:13
# tc filter add dev eth1 protocol ip basic match 'meta(pkt_len gt 0)' flowid 1:13
# tc filter add dev eth1 basic match 'meta(dev eq 8)' flowid 1:13
# tc filter add dev eth1 basic match 'meta(rt_iif gt 0)' flowid 1:14
tc filter add dev eth1 basic match 'meta(fwmark gt 24)' flowid 1:15
tc filter add dev eth1 parent 1:13 handle 100 fw flowid 1:14
tc filter add dev eth1 parent 1:13 handle 101 fw flowid 1:15
tc filter add dev eth1 parent 1:13 priority 10 matchall classid 1:15
# 通常來說隊列是應用於出去的就流量的,也就是內核發網絡包到網卡之前的,但 ingres 這個qdisc可以
# 對接收上了的包應用tc隊列,可以把收上來的轉到一個ifb然后在那個ifb 設備上面限制接收方向的流量吧,
# 不過一般很少用這個吧。
# ingres qdisc的id 不能添加子qdisc
tc qdisc add dev eth1 handle ffff: ingress
modprobe ifb
ip link set dev ifb0 up
# 使用ifb0做輸入方向的重定向
tc filter add dev bond0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
# 使用ifb0做輸出方向的重定向
tc filter add dev bond0 parent 1: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0
htb的burst和burst
=================
tc 本身會自動計算burst和cburst,設置為
/* compute minimal allowed burst from rate; mtu is added here to make
sute that buffer is larger than mtu and to have some safeguard space */
if (!buffer)
buffer = rate64 / get_hz() + mtu;
if (!cbuffer)
cbuffer = ceil64 / get_hz() + mtu;
/ # cat /proc/net/psched
000003e8 00000040 000f4240 3b9aca00
但現在的系統tc從/proc/net/psched獲取的HZ都是很大的,跟網卡NAPI等接口有關?
所以基本算出來都是默認的mtu 1600byte,但HTB這些算法,現在的都是把包長度表示成
納秒的時間刻度的,所以轉換完再轉換回來好像數值有點不一樣,經常看到比MTU要小的。
本來HZ比較小的時候,這個burst和cburst是要設置的很大的比較十幾KB的,這樣才能發
完帶寬。但好像現在內核API變化了,這個跟系統時鍾周期沒關系了,
sqm-scripts叫里面burst和cburst都是用同一個值, 默認允許的突發時間是 t = 1ms (1000微秒),
用下面這個公式來計算的:
busrt(byte) = rate(kbit/s) * 1000(t=1ms) / 8000
來計算的,然后不能 小於 MTU + 200的樣子
quantum 用的也是busrt 一樣的數值。
說是quantum不能大於burst。burst說設置小了比較耗cpu。quantum是每一輪調度允許發送量?quantum設置小了,不同class之間的均衡性更好吧。
fq_codel的quantum 說是默認設置300,不能再小了,設置成300是可能有小包優先的作用? fq_codel的flows對應流(連接)數量,用於保證多流之間的公平性的
ecn / noecn
===
外網上行接口不開ecn,內網可以開ecn。 就是支持enc標記的tcp連接之類的,會用ecn標記一下包吧,不是直接丟棄,終端系統看到網絡包有這個標記就會知道發生擁堵了。
網上關於openwrt的tc限速描述有很多,目前主流用的是IMQ和ifb,其中IMQ的設置比較復雜,ifb的描述相當於簡單點,下面我簡單總結下ifb的使用,
TC的大概流程如下,具體每條命令的作用我就不做詳細介紹,大家可以百度
tc qdisc add dev eth0 ingress
tc filter add dev br-eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
tc qdisc add dev ifb0 root handle 1: htb default 1000
tc class add dev ifb0 parent 1: classid 1:1 htb rate 2000kbit ceil 2000kbit #限速2M
tc class add dev ifb0 parent 1:1 classid 1:1000 htb rate 1kbit ceil 8000kbit prio 3
tc qdisc add dev ifb0 parent 1:1000 handle 1000: sfq perturb 10
tc class add dev ifb0 parent 1:1 classid 1:8 htb rate 1000kbit ceil 2000kbit prio 1
tc qdisc add dev ifb0 parent 1:8 handle 8: sfq perturb 10
tc filter add dev ifb0 parent 1:0 prio 1 protocol ip handle 8 fw flowid 1:8
iptables -t mangle -A PREROUTING -p udp -j MARK --set-mark 8
iptables -t mangle -A PREROUTING -p udp -j RETURN
上述的使用的netfilter和tc相結合,通過fw,是的mark打入skb中,下面重點來了,
我發現在不同設備上,出現下面問題,百度了一下,居然老外也遇到過(be aware that if you use iptable to mark your packet and then filters them, you can't use ifb since all ingress trafic will be forwarded BEFORE any marking. so you will se your class stay at 0 and all forwarded to the default. IMQ seem the rigth solution for iptables users.)
為了解決這個問題,查了很多資料,終於get到了,在iptables中使用connmark這個參數進行mark的標記,從而使得skb頭里也能成功打上mark
使用netfilter的原因是因為涉及到ipset 地址集,以及域名。
tc也提供了另外一種方法,下面方法比較簡單了,也可以涉及到多地址,但可能比較繁瑣點(至少我認為沒有IPtables簡便)
#tc qdisc add dev imq0 root handle 1: htb default 20
#tc class add dev imq0 parent 1: classid 1:1 htb rate 2mbit burst 15k
#tc class add dev imq0 parent 1:1 classid 1:10 htb rate 1mbit
#tc class add dev imq0 parent 1:1 classid 1:20 htb rate 1mbit
#tc qdisc add dev imq0 parent 1:10 handle 10: pfifo
#tc qdisc add dev imq0 parent 1:20 handle 20: sfq
#tc filter add dev imq0 parent 10:0 protocol ip prio 1 u32 match ip dst 10.0.0.230/32 flowid 1:10
這里其實也可以對protol協議進行限制,以及端口范圍
協議”
tc filter add dev ifb0 parent 1: protocol ip prio 2 u32 match ip protocol 1 0xff flowid 1:8
1 0xff是icmp 協議,這里1 代表icmp,你可以在/etc/protocols查看每個協議具體是什么
關於端口范圍
tc filter add dev eth2 protocol ip parent 1: prio 2 u32 match ip sport 22 0xffff flowid 1:12
0xffB2-0xffff的數值,表示從起始端口開始后多少。
--------------
來源 https://www.right.com.cn/forum/thread-53500-1-1.html
要完成自定義QOS,需要先把tc,iptable, htb算法, opendpi , xt_recent 這些都搞清楚,起碼基本的命令都會用。否則就看看熱鬧好了。
命令很多人都懂,我就主要講下思路。tc的流量控制很准確,前提是要對tc,htb有足夠的了解。htb的分類主要以openwrt原版qos為基礎,上傳增加一個第五類。iptables的設置,也是以openwrt的原版為基礎,將l7-filter換成opendpi作七層識別,並作了一些小改動來符合我的需求。
上傳
1: root htb
|
1:1
/ / \
1:10 1:20 1:3
/ \ \
1:30 1:40 1:50
tc qdisc add dev eth1 root handle 1: htb default 40
tc class add dev eth1 parent 1: classid 1:1 htb rate 58kbps ceil 58kbps burst 5k cburst 5k
tc class add dev eth1 parent 1:1 classid 1:10 htb rate 10kbps ceil 58kbps prio 1
tc class add dev eth1 parent 1:1 classid 1:20 htb rate 15kbps ceil 58kbps prio 2
tc class add dev eth1 parent 1:1 classid 1:3 htb rate 15kbps ceil 45kbps
tc class add dev eth1 parent 1:3 classid 1:30 htb rate 10kbps ceil 45kbps prio 3 burst 2k cburst 2k
tc class add dev eth1 parent 1:3 classid 1:40 htb rate 5kbps ceil 45kbps prio 4
tc class add dev eth1 parent 1:3 classid 1:50 htb rate 5kbps ceil 45kbps prio 5
這是上傳500kbit帶寬的分類情況, 1:10是游戲, 1:20是dns, tcp syn,tcp ack ,ssh,QQ語音之類的, 1:30是網頁、virtual**、代理、rdp,1:40是BT,迅雷,PPS和其他未分類,包大小小於300的流量,1:50是BT,迅雷,PPS和未分類,包大小大於300的流量。
下載也作了tc和iptable的配置,不過相對來說沒那么重要,就不帖了。主要思路跟上傳差不多,沒用imq而是用了ifb模塊,也就是上傳和下載都在同一個interface(即出口)上整形。好像ifb是在iptable之前,具體有空測試一下,所以iptable對下行來說也不重要了,但對於七層識別還是有點用,所以也加上了,openwrt的原版QOS在iptable中是不對下行作mark的。
按這個速率設定來用的話,開下載的同時,游戲的延遲是可以保證的。當然最重要的是在iptable 上把流量用mark分好類,我的分類是按端口和七層識別同時用,比如22,80,53都可以按端口來設,雖然有些應用也會用這些端口,但一般沒多大影響。除非有特意改端口的,有影響了,那可以都用七層識別來做。opendpi在七層識別方面還是不錯的,openwrt的開發者在幾個月前已經開始計划用opendpi換掉l7-filter,不知道最近進展如何。不過我們可以自己編譯到openwrt里。
另外,很多QOS的設定都會推薦限制連接數,我沒有做方面的限制,至少在我這里沒有什么問題。測試3M下行,500k上行的時候迅雷開了3個種子,基本滿速,上行還有富余,游戲延遲沒問題,QQ語音同時連3個人流暢。 測試20M下行,1M上行的時候,迅雷開20個種子,下行不滿速,上行已經滿了,迅雷上傳顯示0,游戲延遲沒問題,QQ語音同時連3個人流暢。
因為我玩DOTA經常上浩方,所以自己分析了浩方的數據包特征,CS,WAR3都能匹配,最近去11平台玩DOTA,也分析了下,可以匹配了。opendpi對PPS支持很好,QQ需要修改匹配方法。迅雷和風行這種,只是部分能有些特征包,已經足夠了,可以配合recent來mark,要改recent模塊。
本來想貼幾個圖,想想沒什么意義。如果有人感興趣,可以聯系我,幫忙寫個腳本。
最后貼下iptable的統計信息。其中war3的匹配都在下行里,這里看不到,帖子長度的問題,就不貼了。
上行:
Chain Default (2 references)
pkts bytes target prot opt in out source destination
41447462 17211275535 CONNMARK all -- * * 0.0.0.0/0 0.0.0.0/0 CONNMARK restore
11384650 1499982652 Default_ct all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0
34 23446 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x1 length 400:65535 MARK and 0x0
24641 20134127 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x2 length 800:65535 MARK and 0x0
37746 5394916 MARK icmp -- * * 0.0.0.0/0 0.0.0.0/0 MARK set 0x1
2077725 101041304 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 length 0:128 mark match !0x4 tcp flags:0x3F/0x02 MARK set 0x2
1418481 59188992 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 length 0:128 mark match !0x4 tcp flags:0x3F/0x10 MARK set 0x2
6699462 697530975 MARK udp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 length 0:65535 MARK set 0x4
896620 621880446 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 length 0:65535 MARK set 0x4
2822843 3713061114 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x4 length 300:65535 MARK set 0x5
Chain Default_ct (1 references)
pkts bytes target prot opt in out source destination
379 18200 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 tcp multiport ports 22,53 MARK set 0x2
27432 1704319 MARK udp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 udp multiport ports 22,53 MARK set 0x2
144061 7137731 MARK tcp -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 tcp multiport ports 20,21,25,80,110,443,993,995,5190,3389,3390,5900,1080,1194 MARK set 0x3
364 23960 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol HF MARK set 0x1
1 45 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol COUNTERSTRIKE MARK set 0x1
0 0 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol WARCRAFT3 MARK set 0x1
966 51955 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol PT11 MARK set 0x1
174 31318 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol QQ MARK set 0x2
727 256830 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol HTTP MARK set 0x3
753 102156 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol PPStream MARK set 0x4
0 0 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol PPLive MARK set 0x4
683701 50272737 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol Bittorrent MARK set 0x4
4534 268934 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 protocol Thunder/Webthunder MARK set 0x8
103919 7200135 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x0 recent: UPDATE seconds: 60 name: DEFAULT side:source port MARK set 0x4
4534 268934 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 mark match 0x8 recent: SET name: DEFAULT side:source port MARK set 0x4
11384650 1499982652 CONNMARK all -- * * 0.0.0.0/0 0.0.0.0/0 CONNMARK save
################################ # 查看 ifb 接口 ip link show | grep ifb # 刪除 ifb 模塊 rmmod ifb # 插入 ifb 模塊 insmod ifb # 插入 ifb 模塊 並指定虛擬接口數量為2 modprobe ifb numifbs=2 # 啟用 ifb 接口 ifconfig ifb0 up ifconfig ifb1 up ################################ # 查看所有隊列規則 tc qdisc show # 查看eth0.2所有隊列規則 tc qdisc show dev eth0.2 # 刪除eth0.2的出隊規則 tc qdisc del dev eth0.2 root # 刪除eth0.2的入隊規則 tc qdisc del dev eth0.2 ingress # 刪除ifb0的入隊規則 tc qdisc del dev ifb0 root # 設置eth0.2發送隊列長度為32 ip link set dev eth0.2 txqueuelen 32 ################################
有PM要腳本的,貼一下完整的腳本 ,供大家研究,可能需要安裝一些模塊后才能用。 但准確的分類也很重要,這不是一個腳本能解決的。目前還在研究一些http協議的P2P流量,這個對看網頁有些影響。等東西成熟了,會做成安裝包放出來。 3M下行,500K上行帶寬。 insmod cls_u32 insmod em_u32 insmod act_connmark insmod act_mirred insmod sch_ingress insmod cls_fw insmod sch_htb insmod sch_sfq insmod sch_red 上行: ifconfig eth1 up txqueuelen 5 tc qdisc del dev eth1 root 2> /dev/null > /dev/null tc qdisc add dev eth1 root handle 1: htb default 40 tc class add dev eth1 parent 1: classid 1:1 htb rate 58kbps ceil 58kbps burst 5k cburst 5k tc class add dev eth1 parent 1:1 classid 1:10 htb rate 10kbps ceil 58kbps prio 1 tc class add dev eth1 parent 1:1 classid 1:20 htb rate 15kbps ceil 58kbps prio 2 tc class add dev eth1 parent 1:1 classid 1:3 htb rate 15kbps ceil 45kbps tc class add dev eth1 parent 1:3 classid 1:30 htb rate 10kbps ceil 45kbps prio 3 burst 2k cburst 2k tc class add dev eth1 parent 1:3 classid 1:40 htb rate 5kbps ceil 45kbps prio 4 tc class add dev eth1 parent 1:3 classid 1:50 htb rate 5kbps ceil 45kbps prio 5 tc qdisc add dev eth1 parent 1:10 handle 100: sfq perturb 2 limit 36000 tc qdisc add dev eth1 parent 1:20 handle 200: sfq perturb 2 limit 36000 tc qdisc add dev eth1 parent 1:30 handle 300: red min 3116 max 9348 burst 3 avpkt 1500 limit 37392 probability 0.12 ecn tc qdisc add dev eth1 parent 1:40 handle 400: red min 3116 max 9348 burst 3 avpkt 1500 limit 37392 probability 0.12 ecn tc qdisc add dev eth1 parent 1:50 handle 500: red min 3116 max 9348 burst 3 avpkt 1500 limit 37392 probability 0.12 ecn tc filter add dev eth1 parent 1: prio 1 protocol ip handle 1 fw flowid 1:10 tc filter add dev eth1 parent 1: prio 2 protocol ip handle 2 fw flowid 1:20 tc filter add dev eth1 parent 1: prio 3 protocol ip handle 3 fw flowid 1:30 tc filter add dev eth1 parent 1: prio 4 protocol ip handle 4 fw flowid 1:40 tc filter add dev eth1 parent 1: prio 5 protocol ip handle 5 fw flowid 1:50 下行 ifconfig ifb0 up txqueuelen 5 tc qdisc del dev ifb0 root 2> /dev/null > /dev/null tc qdisc add dev ifb0 root handle 1: htb default 40 tc class add dev ifb0 parent 1: classid 1:1 htb rate 360kbps ceil 360kbps burst 50k cburst 50k tc qdisc del dev eth1 ingress tc qdisc add dev eth1 ingress tc filter add dev eth1 parent ffff: protocol ip prio 1 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb0 tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 20kbps ceil 360kbps prio 1 tc class add dev ifb0 parent 1:1 classid 1:20 htb rate 50kbps ceil 360kbps prio 2 tc class add dev ifb0 parent 1:1 classid 1:3 htb rate 200kbps ceil 320kbps tc class add dev ifb0 parent 1:3 classid 1:30 htb rate 100kbps ceil 320kbps prio 3 burst 50k cburst 50k tc class add dev ifb0 parent 1:3 classid 1:40 htb rate 20kbps ceil 320kbps prio 4 tc qdisc add dev ifb0 parent 1:10 handle 100: sfq perturb 2 limit 223716 tc qdisc add dev ifb0 parent 1:20 handle 200: sfq perturb 2 limit 223716 tc qdisc add dev ifb0 parent 1:30 handle 300: red min 18643 max 55929 burst 20 avpkt 1500 limit 223716 probability 0.12 ecn tc qdisc add dev ifb0 parent 1:40 handle 400: red min 18643 max 55929 burst 20 avpkt 1500 limit 223716 probability 0.12 ecn tc filter add dev ifb0 parent 1: prio 1 protocol ip handle 1 fw flowid 1:10 tc filter add dev ifb0 parent 1: prio 2 protocol ip handle 2 fw flowid 1:20 tc filter add dev ifb0 parent 1: prio 3 protocol ip handle 3 fw flowid 1:30 tc filter add dev ifb0 parent 1: prio 4 protocol ip handle 4 fw flowid 1:40 iptables : + iptables -t mangle -F + iptables -t mangle -X + insmod ipt_multiport + insmod ipt_CONNMARK + insmod xt_opendpi + insmod ipt_length + iptables -t mangle -N Default + iptables -t mangle -N Default_ct + iptables -t mangle -A Default_ct -m mark --mark 0 -m tcp -p tcp -m multiport --ports 22,53 -j MARK --set-mark 2 + iptables -t mangle -A Default_ct -m mark --mark 0 -p udp -m udp -m multiport --ports 22,53 -j MARK --set-mark 2 + iptables -t mangle -A Default_ct -m mark --mark 0 -p tcp -m tcp -m multiport --ports 20,21,25,80,110,443,993,995,5190,3389,3390,5900,1080,1194 -j MARK --set-mark 3 + iptables -t mangle -A Default_ct -m mark --mark 0 -m opendpi --hf -j MARK --set-mark 1 + iptables -t mangle -A Default_ct -m mark --mark 0 -m opendpi --qq -j MARK --set-mark 2 + iptables -t mangle -A Default_ct -m mark --mark 0 -m opendpi --http -j MARK --set-mark 3 + iptables -t mangle -A Default_ct -m mark --mark 0 -m opendpi --ppstream -j MARK --set-mark 4 + iptables -t mangle -A Default_ct -m mark --mark 0 -m opendpi --pplive -j MARK --set-mark 4 + iptables -t mangle -A Default_ct -m mark --mark 0 -m opendpi --bittorrent -j MARK --set-mark 4 + iptables -t mangle -A Default_ct -m mark --mark 0 -m opendpi --thunder -j MARK --set-mark 4 + iptables -t mangle -A Default_ct -j CONNMARK --save-mark + iptables -t mangle -A Default -j CONNMARK --restore-mark + iptables -t mangle -A Default -m mark --mark 0 -j Default_ct + iptables -t mangle -A Default -m mark --mark 1 -m length --length 400: -j MARK --set-mark 0 + iptables -t mangle -A Default -m mark --mark 2 -m length --length 800: -j MARK --set-mark 0 + iptables -t mangle -A Default -p icmp -j MARK --set-mark 1 + iptables -t mangle -A Default -p tcp -m length --length :128 -m mark ! --mark 4 -m tcp --tcp-flags ALL SYN -j MARK --set-mark 2 + iptables -t mangle -A Default -p tcp -m length --length :128 -m mark ! --mark 4 -m tcp --tcp-flags ALL ACK -j MARK --set-mark 2 + iptables -t mangle -A Default -m mark --mark 0 -p udp -m length --length 0: -j MARK --set-mark 4 + iptables -t mangle -A Default -m mark --mark 0 -p tcp -m length --length 0: -j MARK --set-mark 4 + iptables -t mangle -A OUTPUT -o eth1 -j Default + iptables -t mangle -A FORWARD -o eth1 -j Default + iptables -t mangle -D Default_ct 10 + iptables -t mangle -I Default_ct 10 -m mark --mark 0x0 -m opendpi --thunder -j MARK --set-xmark 0x8/0xffffffff + iptables -t mangle -I Default_ct 11 -m mark --mark 0x0 -m recent --update --seconds 60 --name DEFAULT --rsource --rport -j MARK --set-xmark 0x4/0xffffffff + iptables -t mangle -I Default_ct 12 -m mark --mark 0x8 -m recent --set --name DEFAULT --rsource --rport -j MARK --set-xmark 0x4/0xffffffff + iptables -t mangle -N Default_dn + iptables -t mangle -N Default_ct_dn + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m tcp -p tcp -m multiport --ports 22,53 -j MARK --set-mark 2 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -p udp -m udp -m multiport --ports 22,53 -j MARK --set-mark 2 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -p tcp -m tcp -m multiport --ports 20,21,25,80,110,443,993,995,5190,3389,3390,5900,1080,1194 -j MARK --set-mark 3 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m opendpi --hf -j MARK --set-mark 1 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m opendpi --qq -j MARK --set-mark 2 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m opendpi --http -j MARK --set-mark 3 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m opendpi --ppstream -j MARK --set-mark 4 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m opendpi --pplive -j MARK --set-mark 4 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m opendpi --bittorrent -j MARK --set-mark 4 + iptables -t mangle -A Default_ct_dn -m mark --mark 0 -m opendpi --thunder -j MARK --set-mark 4 + iptables -t mangle -A Default_ct_dn -j CONNMARK --save-mark + iptables -t mangle -A Default_dn -j CONNMARK --restore-mark + iptables -t mangle -A Default_dn -m mark --mark 0 -j Default_ct_dn + iptables -t mangle -A Default_dn -m mark --mark 1 -m length --length 400: -j MARK --set-mark 0 + iptables -t mangle -A Default_dn -m mark --mark 2 -m length --length 800: -j MARK --set-mark 0 + iptables -t mangle -A Default_dn -p icmp -j MARK --set-mark 1 + iptables -t mangle -A Default_dn -p tcp -m length --length :128 -m mark ! --mark 4 -m tcp --tcp-flags ALL SYN -j MARK --set-mark 2 + iptables -t mangle -A Default_dn -p tcp -m length --length :128 -m mark ! --mark 4 -m tcp --tcp-flags ALL ACK -j MARK --set-mark 2 + iptables -t mangle -A Default_dn -m mark --mark 0 -p udp -m length --length 0: -j MARK --set-mark 4 + iptables -t mangle -A Default_dn -m mark --mark 0 -p tcp -m length --length 0: -j MARK --set-mark 4 + iptables -t mangle -A INPUT -i eth1 -j Default_dn + iptables -t mangle -A FORWARD -i eth1 -j Default_dn + iptables -t mangle -I Default_ct_dn 11 -m mark --mark 0x0 -m recent --update --seconds 60 --name DEFAULT --rdest --rport -j MARK --set-xmark 0x4/0xffffffff root@OpenWrt:~#
------------------------
來源 https://www.haiyun.me/archives/openwrt-tc-qos.html
Openwrt配置QOS流量帶寬限制 #加載模塊: insmod xt_IPID insmod cls_u32 insmod cls_fw insmod sch_htb insmod sch_sfq insmod sch_prio #啟用IMQ虛擬網卡 ip link set imq0 up ip link set imq1 up #刪除舊隊列 tc qdisc del dev imq0 root tc qdisc del dev imq1 root #上傳設置 #增加根隊列,未標記數據默認走26 tc qdisc add dev imq0 root handle 1: htb default 26 #增加總流量規則 tc class add dev imq0 parent 1: classid 1:1 htb rate 350kbit #增加子類 tc class add dev imq0 parent 1:1 classid 1:20 htb rate 80kbit ceil 250kbit prio 0 tc class add dev imq0 parent 1:1 classid 1:21 htb rate 80kbit ceil 250kbit prio 1 tc class add dev imq0 parent 1:1 classid 1:22 htb rate 80kbit ceil 250kbit prio 2 tc class add dev imq0 parent 1:1 classid 1:23 htb rate 80kbit ceil 250kbit prio 3 tc class add dev imq0 parent 1:1 classid 1:24 htb rate 80kbit ceil 250kbit prio 4 tc class add dev imq0 parent 1:1 classid 1:25 htb rate 50kbit ceil 250kbit prio 5 tc class add dev imq0 parent 1:1 classid 1:26 htb rate 50kbit ceil 150kbit prio 6 tc class add dev imq0 parent 1:1 classid 1:27 htb rate 50kbit ceil 100kbit prio 7 #為子類添加SFQ公平隊列,每10秒重置 tc qdisc add dev imq0 parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev imq0 parent 1:21 handle 21: sfq perturb 10 tc qdisc add dev imq0 parent 1:22 handle 22: sfq perturb 10 tc qdisc add dev imq0 parent 1:23 handle 23: sfq perturb 10 tc qdisc add dev imq0 parent 1:24 handle 24: sfq perturb 10 tc qdisc add dev imq0 parent 1:25 handle 25: sfq perturb 10 tc qdisc add dev imq0 parent 1:26 handle 26: sfq perturb 10 tc qdisc add dev imq0 parent 1:27 handle 27: sfq perturb 10 #添加過濾規則配合Iptables Mark標記 #tc filter add dev imq0 parent 1:0 protocol ip u32 match ip sport 22 0xffff flowid 1:10 #使用U32標記數據,下面使用Iptables mark,容易。 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:22 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 23 fw flowid 1:23 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 24 fw flowid 1:24 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 25 fw flowid 1:25 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 26 fw flowid 1:26 tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 27 fw flowid 1:27 #上傳數據轉入特定鏈 iptables -t mangle -N MYSHAPER-OUT iptables -t mangle -A POSTROUTING -o pppoe-wan -j MYSHAPER-OUT iptables -t mangle -A MYSHAPER-OUT -j IMQ --todev 0 #為特定數據打上標記配合之前過濾規則 #iptables -t mangle -I MYSHAPER-OUT -s 192.168.1.16 -j MARK --set-mark 27 #限制特定IP上傳速度 #iptables -t mangle -I MYSHAPER-OUT -s 192.168.1.16 -j RETURN iptables -t mangle -A MYSHAPER-OUT -p tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 20 #提高HTTP連接速度 iptables -t mangle -A MYSHAPER-OUT -p tcp --tcp-flags SYN,RST,ACK SYN -j RETURN iptables -t mangle -A MYSHAPER-OUT -p udp --dport 53 -j MARK --set-mark 20 #DNS查詢 iptables -t mangle -A MYSHAPER-OUT -p udp --dport 53 -j RETURN iptables -t mangle -A MYSHAPER-OUT -p icmp -j MARK --set-mark 21 #ICMP數據 iptables -t mangle -A MYSHAPER-OUT -p icmp -j RETURN iptables -t mangle -A MYSHAPER-OUT -p tcp -m length --length :64 -j MARK --set-mark 21 #小數據包 iptables -t mangle -A MYSHAPER-OUT -p tcp -m length --length :64 -j RETURN iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 22 -j MARK --set-mark 22 #SSH連接 iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 22 -j RETURN iptables -t mangle -A MYSHAPER-OUT -p udp --dport 1194 -j MARK --set-mark 22 #VPN連接 iptables -t mangle -A MYSHAPER-OUT -p udp --dport 1194 -j RETURN iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 80 -j MARK --set-mark 23 #HTTP連接 iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 80 -j RETURN iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 443 -j MARK --set-mark 24 #HTTPS連接 iptables -t mangle -A MYSHAPER-OUT -p tcp --dport 443 -j RETURN #上傳設置完成 #下載設置 #增加根隊列,未標記數據默認走24 tc qdisc add dev imq1 handle 1: root htb default 24 tc class add dev imq1 parent 1: classid 1:1 htb rate 3500kbit #添加子類 tc class add dev imq1 parent 1:1 classid 1:20 htb rate 1000kbit ceil 1500kbit prio 0 tc class add dev imq1 parent 1:1 classid 1:21 htb rate 1500kbit ceil 2500kbit prio 1 tc class add dev imq1 parent 1:1 classid 1:22 htb rate 2000kbit ceil 3500kbit prio 2 tc class add dev imq1 parent 1:1 classid 1:23 htb rate 1000kbit ceil 1500kbit prio 3 tc class add dev imq1 parent 1:1 classid 1:24 htb rate 1000kbit ceil 1500kbit prio 4 #為子類添加SFQ公平隊列 tc qdisc add dev imq1 parent 1:20 handle 20: sfq perturb 10 tc qdisc add dev imq1 parent 1:21 handle 21: sfq perturb 10 tc qdisc add dev imq1 parent 1:22 handle 22: sfq perturb 10 tc qdisc add dev imq1 parent 1:23 handle 23: sfq perturb 10 tc qdisc add dev imq1 parent 1:24 handle 24: sfq perturb 10 #過濾規則 tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20 tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21 tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:22 tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 23 fw flowid 1:23 tc filter add dev imq1 parent 1:0 prio 0 protocol ip handle 24 fw flowid 1:24 #下載數據轉入特定鏈 iptables -t mangle -N MYSHAPER-IN iptables -t mangle -A PREROUTING -i pppoe-wan -j MYSHAPER-IN iptables -t mangle -A MYSHAPER-IN -j IMQ --todev 1 #分類標記數據 #iptables -t mangle -A MYSHAPER-IN -d 192.168.1.16 -j MARK --set-mark 23 #限制特定IP下載速度 #iptables -t mangle -A MYSHAPER-IN -d 192.168.1.16 -j RETURN iptables -t mangle -A MYSHAPER-IN -p tcp -m length --length :64 -j MARK --set-mark 20 #小數據優先 iptables -t mangle -A MYSHAPER-IN -p tcp -m length --length :64 -j RETURN iptables -t mangle -A MYSHAPER-IN -p icmp -j MARK --set-mark 20 #ICMP數據 iptables -t mangle -A MYSHAPER-IN -p icmp -j RETURN iptables -t mangle -A MYSHAPER-IN -p tcp --sport 22 -j MARK --set-mark 21 #SSH連接 iptables -t mangle -A MYSHAPER-IN -p tcp --sport 22 -j RETURN iptables -t mangle -A MYSHAPER-IN -p udp --sport 1194 -j MARK --set-mark 21 #VPN連接 iptables -t mangle -A MYSHAPER-IN -p udp --sport 1194 -j RETURN iptables -t mangle -A MYSHAPER-IN -p tcp --sport 443 -j MARK --set-mark 22 #HTTPS連接 iptables -t mangle -A MYSHAPER-IN -p tcp --sport 443 -j RETURN iptables -t mangle -A MYSHAPER-IN -p tcp --sport 80 -j MARK --set-mark 22 #HTTP連接 iptables -t mangle -A MYSHAPER-IN -p tcp --sport 80 -j RETURN iptables -t mangle -A MYSHAPER-IN -p tcp --sport 0:1024 -j MARK --set-mark 23 #系統服務端口連接 iptables -t mangle -A MYSHAPER-IN -p tcp --sport 0:1024 -j RETURN
=============== End