Linux下使用tc(Traffic Control) 流量控制命令模擬網絡延遲和丟包


 Linux下使用tc(Traffic Control) 流量控制命令模擬網絡延遲和丟包

qdisc is short for 'queueing discipline'  

TC案例

如何使用tc模擬網絡延遲和丟包

修改網絡延時:  sudo tc qdisc add dev eth0 root netem delay 1000ms

查看流量管理:tc qdisc show

刪除策略:sudo tc qdisc del dev eth0 root netem delay 1000ms

驗證效果:ping 192.168.102.124 -c 20

 

修改丟包率:sudo tc qdisc add dev eth0 root netem loss 10%

刪除策略:sudo tc qdisc del dev eth0 root netem loss 10%

 

--------------------------------------------------------------------------------------------------------------------------------------------

配置網絡超時

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@dev-xx-xx ~] # tc qdisc del dev eth0 root netem delay 100ms
RTNETLINK answers: Invalid argument
[root@dev-xx-xx ~] # tc qdisc show
qdisc mq 0: dev eth0 root
qdisc pfifo_fast 0: dev eth0 parent :1 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev eth0 parent :2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev eth0 parent :3 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev eth0 parent :4 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
[root@dev-xx-xx ~] # tc qdisc add dev eth0 root netem delay 100ms
[root@dev-xx-xx ~] # ping 192.168.102.124
PING 192.168.102.124 (192.168.102.124) 56(84) bytes of data.
64 bytes from 192.168.102.124: icmp_seq=1 ttl=64  time =0.074 ms
64 bytes from 192.168.102.124: icmp_seq=2 ttl=64  time =0.066 ms
64 bytes from 192.168.102.124: icmp_seq=3 ttl=64  time =0.080 ms
64 bytes from 192.168.102.124: icmp_seq=4 ttl=64  time =0.043 ms
64 bytes from 192.168.102.124: icmp_seq=5 ttl=64  time =0.084 ms
64 bytes from 192.168.102.124: icmp_seq=6 ttl=64  time =0.094 ms
^C
--- 192.168.102.124  ping  statistics ---
12 packets transmitted, 12 received, 0% packet loss,  time  11131ms
rtt min /avg/max/mdev  = 0.043 /0 .081 /0 .107 /0 .018 ms
[root@dev-xx-xx ~] # tc qdisc del dev eth0 root netem delay 100ms
[root@dev-xx-xx ~] # tc qdisc del dev eth0 root netem delay 100ms
RTNETLINK answers: Invalid argument

  

 

配置網絡丟包率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
[root@dev-xx-xx ~] # tc qdisc del dev eth0 root netem loss 10%
RTNETLINK answers: Invalid argument
[root@dev-xx-xx ~] # tc qdisc add dev eth0 root netem loss 10%
[root@dev-xx-xx ~] # tc qdisc show
qdisc netem 8005: dev eth0 root refcnt 5 limit 1000 loss 10%
[root@dev-xx-xx ~] # ping 192.168.102.124 -n 20
PING 20 (0.0.0.20) 56(124) bytes of data.
^C
--- 20  ping  statistics ---
21 packets transmitted, 0 received, 100% packet loss,  time  20650ms
 
[root@dev-xx-xx ~] # ping 192.168.102.124 -c 20
PING 192.168.102.124 (192.168.102.124) 56(84) bytes of data.
64 bytes from 192.168.102.124: icmp_seq=1 ttl=64  time =0.101 ms
64 bytes from 192.168.102.124: icmp_seq=2 ttl=64  time =0.062 ms
64 bytes from 192.168.102.124: icmp_seq=3 ttl=64  time =0.098 ms
64 bytes from 192.168.102.124: icmp_seq=4 ttl=64  time =0.098 ms
64 bytes from 192.168.102.124: icmp_seq=5 ttl=64  time =0.062 ms
64 bytes from 192.168.102.124: icmp_seq=6 ttl=64  time =0.088 ms
64 bytes from 192.168.102.124: icmp_seq=7 ttl=64  time =0.045 ms
64 bytes from 192.168.102.124: icmp_seq=8 ttl=64  time =0.070 ms
64 bytes from 192.168.102.124: icmp_seq=9 ttl=64  time =0.062 ms
64 bytes from 192.168.102.124: icmp_seq=10 ttl=64  time =0.066 ms
64 bytes from 192.168.102.124: icmp_seq=11 ttl=64  time =0.088 ms
64 bytes from 192.168.102.124: icmp_seq=12 ttl=64  time =0.070 ms
64 bytes from 192.168.102.124: icmp_seq=13 ttl=64  time =0.089 ms
64 bytes from 192.168.102.124: icmp_seq=14 ttl=64  time =0.087 ms
64 bytes from 192.168.102.124: icmp_seq=15 ttl=64  time =0.054 ms
64 bytes from 192.168.102.124: icmp_seq=16 ttl=64  time =0.085 ms
64 bytes from 192.168.102.124: icmp_seq=17 ttl=64  time =0.064 ms
64 bytes from 192.168.102.124: icmp_seq=18 ttl=64  time =0.124 ms
64 bytes from 192.168.102.124: icmp_seq=19 ttl=64  time =0.063 ms
64 bytes from 192.168.102.124: icmp_seq=20 ttl=64  time =0.108 ms
 
--- 192.168.102.124  ping  statistics ---
20 packets transmitted, 20 received, 0% packet loss,  time  19000ms
rtt min /avg/max/mdev  = 0.045 /0 .079 /0 .124 /0 .020 ms
[root@dev-xx-xx ~] # tc qdisc del dev eth0 root netem loss 10%
[root@dev-xx-xx ~] # ping 192.168.102.124 -c 20
PING 192.168.102.124 (192.168.102.124) 56(84) bytes of data.
64 bytes from 192.168.102.124: icmp_seq=1 ttl=64  time =0.041 ms
64 bytes from 192.168.102.124: icmp_seq=2 ttl=64  time =0.132 ms
64 bytes from 192.168.102.124: icmp_seq=3 ttl=64  time =0.344 ms
64 bytes from 192.168.102.124: icmp_seq=4 ttl=64  time =0.404 ms
64 bytes from 192.168.102.124: icmp_seq=5 ttl=64  time =0.086 ms
64 bytes from 192.168.102.124: icmp_seq=6 ttl=64  time =0.088 ms
64 bytes from 192.168.102.124: icmp_seq=7 ttl=64  time =0.063 ms
64 bytes from 192.168.102.124: icmp_seq=8 ttl=64  time =0.109 ms
64 bytes from 192.168.102.124: icmp_seq=9 ttl=64  time =0.064 ms
64 bytes from 192.168.102.124: icmp_seq=10 ttl=64  time =0.092 ms
64 bytes from 192.168.102.124: icmp_seq=11 ttl=64  time =0.044 ms
64 bytes from 192.168.102.124: icmp_seq=12 ttl=64  time =0.066 ms
64 bytes from 192.168.102.124: icmp_seq=13 ttl=64  time =0.094 ms
64 bytes from 192.168.102.124: icmp_seq=14 ttl=64  time =0.097 ms
64 bytes from 192.168.102.124: icmp_seq=15 ttl=64  time =0.108 ms
64 bytes from 192.168.102.124: icmp_seq=16 ttl=64  time =0.043 ms
64 bytes from 192.168.102.124: icmp_seq=17 ttl=64  time =0.093 ms
64 bytes from 192.168.102.124: icmp_seq=18 ttl=64  time =0.056 ms
64 bytes from 192.168.102.124: icmp_seq=19 ttl=64  time =0.093 ms
64 bytes from 192.168.102.124: icmp_seq=20 ttl=64  time =0.039 ms
 
--- 192.168.102.124  ping  statistics ---
20 packets transmitted, 20 received, 0% packet loss,  time  18999ms
rtt min /avg/max/mdev  = 0.039 /0 .107 /0 .404 /0 .093 ms
[root@dev-xx-xx ~] #

 

TC常用命令


1)模擬延遲傳輸:

# tc qdisc add dev eth0 root netem delay 100ms

該命令將 eth0 網卡的傳輸設置為延遲 100 毫秒發送,更真實的情況下,延遲值不會這么精確,會有一定的波動,后面用下面的情況來模擬出帶有波動性的延遲值


2)模擬延遲波動:
# tc qdisc add dev eth0 root netem delay 100ms 10ms

該命令將 eth0 網卡的傳輸設置為延遲 100ms ± 10ms (90 ~ 110 ms 之間的任意值)發送。 還可以更進一步加強這種波動的隨機性


3)延遲波動隨機性:

該命令將 eth0 網卡的傳輸設置為 100ms ,同時,大約有 30% 的包會延遲 ± 10ms 發送。
# tc qdisc add dev eth0 root netem delay 100ms 10ms 30%


4)模擬網絡丟包:
# tc qdisc add dev eth0 root netem loss 1%

該命令將 eth0 網卡的傳輸設置為隨機丟掉 1% 的數據包


5)網絡丟包成功率:
# tc qdisc add dev eth0 root netem loss 1% 30%

該命令將 eth0 網卡的傳輸設置為隨機丟掉 1% 的數據包,成功率為 30%


6)刪除相關配置(將之前命令中的 add 改為 del 即可刪除配置):
# tc qdisc del dev eth0 root netem delay 100ms


7)模擬包重復:
# tc qdisc add dev eth0 root netem duplicate 1%

該命令將 eth0 網卡的傳輸設置為隨機產生 1% 的重復數據包


8)模擬包損壞:
# tc qdisc add dev eth0 root netem corrupt 0.2%

該命令將 eth0 網卡的傳輸設置為隨機產生 0.2% 的損壞的數據包 。 (內核版本需在 2.6.16 以上)

 

9)模擬包亂序:
# tc qdisc change dev eth0 root netem delay 10ms reorder 25% 50%

該命令將 eth0 網卡的傳輸設置為:有 25% 的數據包(50%相關)會被立即發送,其他的延遲10 秒。

新版本中,如下命令也會在一定程度上打亂發包的次序:# tc qdisc add dev eth0 root netem delay 100ms 10ms

 

10)查看網卡配置:
# tc qdisc show dev eth0

該命令將 查看並顯示 eth0 網卡的相關傳輸配置


11)查看丟包率:
# tc -s qdisc show dev eth0

 

TC安裝

 TC是linux自帶的模塊,一般不需要安裝,TC要求內核2.4.18以上。注意:64位機器上,或需先執行下面命令,做個軟鏈接:ln -s /usr/lib64/tc /usr/lib/tc

 

TC原理介紹

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

 

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

 

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

 

inux流量控制的基本原理如下圖所示:

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

 

TC規則

一、流量控制方式

流量控制包括一下幾種方式:SHAPING、SCHEDULING、POLICING、DROPPING;

 

SHAPING(限制)

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

 

SCHEDULING(調度)

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

 

POLICING(策略)

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

 

DROPPING(丟棄)

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

 

二、流量控制處理對象

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

 

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

 

qddis(排隊規則)分為 CLASSLESS QDISC和 CLASSFUL QDISC;

 

CLASSLESS QDISC (無類別QDISC)包括:

 

[ p | b ]fifo,使用最簡單的qdisc(排隊規則),純粹的先進先出。只有一個參數:limit ,用來設置隊列的長度,pfifo是以數據包的個數為單位;bfifo是以字節數為單位。

 

pfifo_fast,在編譯內核時,如果打開了高級路由器(Advanced Router)編譯選項,pfifo_fast 就是系統的標准qdisc(排隊規則)。它的隊列包括三個波段(band)。在每個波段里面,使用先進先出規則。而三個波段(band)的優先級也不相同,band 0 的優先級最高,band 2的最低。如果band 0里面有數據包,系統就不會處理band 1 里面的數據包,band 1 和 band 2 之間也是一樣的。數據包是按照服務類型(Type Of Service,TOS )被分配到三個波段(band)里面的。

 

red,red是Random Early Detection(隨機早期探測)的簡寫。如果使用這種qdsic,當帶寬的占用接近與規定的帶寬時,系統會隨機的丟棄一些數據包。他非常適合高帶寬的應用。

 

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

 

tbf,tbf是 Token Bucket Filter 的簡寫,適用於把流速降低到某個值。

 

CLASSLESS QDISC (無類別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)包括:

 

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)。

 

TC操作原理

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

 

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

 

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

 

TC命名規則

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

 

qdisc,一個qdisc會被分配一個主序列號,叫做句柄(handle),然后把從序列號作為類的命名空間。句柄才有像1:0 一樣的表達方式。習慣上,需要為有子類的qdisc顯式的分配一個句柄。

 

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

 

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

 

TC單位

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, 只適用於qdisc,替代一個現有的節點。

 

名稱:

linux TC(8) : tc - 顯示/操作流量控制設置

 

命令的格式:

tc qdisc [ add | change | replace | link | delete ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ] tc class [ add | change | replace | delete ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ] tc filter [ add | change | replace | delete ] dev DEV [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id tc [ FORMAT ] qdisc show [ dev DEV ] tc [ FORMAT ] class show dev DEV tc filter show dev DEV tc [ -force ] [ -OK ] -b[atch] [ filename ] 
FORMAT := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -i[ec] }

 

描述:

Tc用於在Linux內核中配置流量控制。交通管制包括以下內容:

 

SHAPING(成型)

交通成形時,其傳輸速度受到控制。整形可能不僅僅是降低可用帶寬 - 它還可以用來消除流量突發,實現更好的網絡行為。在出口處形成整形。

 

SCHEDULING(調度)

通過調度數據包的傳輸,可以改善需要它的流量的交互性,同時保證帶寬進行批量傳輸。重新排序也被稱為優先排序,只發生在出口。

 

POLICING(治安)

鑒於與交通的傳輸形成交易,警務涉及到的交通。警察因此在入口處發生。

 

DROPPING

超過設定帶寬的流量也可以隨時在入口和出口丟棄。

 

流量處理由三種對象來控制:qdiscs,classes和filters。

 

https://www.cnblogs.com/yulia/p/10346339.html

https://tonydeng.github.io/sdn-handbook/linux/tc.html


免責聲明!

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



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