目錄

前言
IntServ 與 DiffServ
Hardware Queue 與 Software Queue
Classification & Marking
  IP Precedence (IPP)
  Differentiated Services Code Point (DSCP)
  class-map 與 policy-map
Software Queuing
  Weighted Fair Queuing (WFQ)
  Class-based Weighted Fair Queueing (CBWFQ)
Congestion Avoidance
  Tail Drop
  Weighted Random Early Detection (WRED)
  Explicit Congestion Notification (ECN)
Hierarchical Policies

前言

服務品質 Quality of Service (QoS) 在網絡上的意義是透過不同的方法,包括控制 Bandwidth、Software Queue、Packet Delay 及 Packet Drop 等去維持網絡的傳輸質素。要在網路實行 QoS 一般分為 Integrated Services (IntServ) 和 Differentiated Services (DiffServ) 兩大方向,無論在考試或職場上,DiffServ 都比較常見,因此本文亦以 DiffServ 教學為主。

IntServ 與 DiffServ

IntServ 的 QoS 實施方法是預先在訊息即將通過的每一隻 Router 預留網絡資源 (主要是 Bandwidth),讓訊息封包通過時保證有足夠資源去提供服務。用道路來作比喻,有一輛消防車趕著去救火,如若遇到交通擠塞便不能提供服務了,IntServ 就好比在每一個路段都把其中一條行車線劃為緊急車輛通道,只有像消防車這類緊急車輛可以使用。缺點是就算沒有緊急車輛通過,所有道路使用者也不可使用這條預留路線。

quality of service

DiffServ 則不預先設置緊急通道,當道路暢通時,所有車輛可自由使用任何路線。當某路段發生壅塞 (Congestion) 時,該路段才會實施交通管制,包括把道路分為緊急線、快線和慢線等,然後把車輛分門別類,按其緊急性去使用不同的路線,例如緊急車輛使用緊急線,私人車用快線,公共交通工具使用慢線。甚至會在路線上選擇一些車輛炸掉 😨 (Packet Drop) 來舒緩 Congestion,通當是慢線車輛遭殃。DiffServ 巧妙的地方在於每段道路可設立自己的交通管制方法,路段間互不影響,稱為 Per-hop Behavior (PHB)。而且交通管制措施只會在發生 Congestion 時才會實行,不像 IntServ 需長期預留路線。DiffServ 缺點在於設定比較複雜。

quality of service

Hardware Queue 與 Software Queue

學習 QoS 設定前先了解一下 Router 的結構。在沒有設定 QoS 的情況下,當 Router 從一個 Interface (Ingress) 收到 Packet,會查看 Packet 的 Destination,再透過查找 Routing Table 等方法找出 Packet 應該放到那一個 Interface 送走 (Egress),詳情可閱讀本網頁關於 Routing Decision 的文章。然而 Packet 在送走前需要在 Egress Interface 的 Hardware Queue 排隊,Interface 會把它們按 First-in-first-out (FIFO) 的次序一個一個送走。

quality of service

Interface 會以其 Interface Speed 的速度把 Packet 送走,例如:Fast Ethernet 會用 100Mbps 的速度從 Hardware Queue 收取 Packet 送出去,然而 Hardware Queue 的長度是有限的,如果進入 Queue 排隊的 Packet 太多,Interface 處理不夠快,Hardware Queue 就會爆滿,後來的 Packet 無法進入 Queue 就會被丟棄,稱為 Tail Drop。

發生 Tail Drop 對 Traffic Flow 帶來什麼影響?不同種類的 Traffic 會有不同結果,如果是 TCP,當 Receiver 收到 Packet 後會回應 Sender,所以 Sender 可以感知每一個 Packet 是否被成功傳送。當 Packet Drop 發生,Sender 發現連續 3 個 Packet 都傳送失敗的時候,會自動降低傳輸速度及重送對方收不到的 Packet,降低傳輸速度可以舒緩網路的壓力。因此,對 TCP 來說,Packet Drop 並非壞事。但對於 UDP 來說 (例如:語音或視像數據),Sender 不會理會 Receiver 是否收到,只會不斷傳送,發生 Packet Drop 會讓 Receiver 失去一些數據,令語音和影像發生斷斷續續的情況。更加嚴重的是一些網絡控制協定,例如:OSPF,EIGRP 等的 Routing Protocol 如果發生 Packet Drop 甚至會讓網絡服務中斷。如套用剛才說的交通管制例子,Routing Protocol 應安排在緊急線,語音和視像是快線,一般 TCP Traffic 就是慢線。

那麽,可以把 Hardware Queue 長度加長讓 Tail Drop 不發生嗎?先說 Egress Interface 的 Hardware Queue,容量是可以調校的,但 Egress Hardware Queue 加長後會讓重要和不重要的 Packet 一同塞在 Queue 排隊,導致所有 Traffic 都出現 Delay 的情況,有些 Protocol 也可能會因為等太久而出現 Timeout 造成中斷。因此,解決方法應為:當 Tail Drop 發生時,立刻檢查 Packet 的重要性,重要的 Packet 優先放入 Egress Hardware Queue,不重要的遲些才放入,甚至直接 Drop 掉不放入,保留 Egress Hardware Queue 的空間給有需要的 Packet,這稱為 Software Queuing (或 Scheduling)。透過 Software Queuing,Router 可以根據 Packet 預先被設定的重要性來安排進入 Hardware Queue 的優先次序,這就能確保服務質素。

雖然 Ingress Interface 的 Hardware Queue 也可調校,但不建議。Ingress Hardware Queue 爆滿代表 Router 不夠快速地把進來的 Packet 處理掉,導致 Packet 在 Ingress Queue 累積,如發生此問題應了解 Router 資源狀況是否出了問題。

quality of service

使用 hold-queue 指令可修改 queue 長度,如要修改 Egress Hardware Queue 長度,設定如下:

R2(config)#int ethernet 1/0
R2(config-if)#hold-queue 1000 out

Classification & Marking

所以首先要解決的問題就是如何及何時把所謂「重要性」寫進 Packet 之中?話說每個 IP Packet 的 Header 裡面都有一個 8 Bits 的 Type of Service (ToS) 標記,用來記錄該 Packet 的重要性。當 Packet 進來網路時可先進行分類 (Classification),然後把代表 Packet「重要性」的 IPP 或 DSCP 值寫在 Packet 的 ToS 裡面,這個動作稱為 Marking,情況就好像把 Packet 按著不同的「重要性」填上顏色。這樣子,無論 Packet 在網路裡走到哪隻 Router,只要 Router 看看 ToS 就能知道應該為 Packet 提供什麼質素的服務了,這也是 DiffServ 的精神所在。接下來先解說一下 IPP 和 DSCP。

quality of service

IP Precedence (IPP)

文章初段所說的緊急線、快線和慢線只是一個例子,真正的分類豈止三個類別。最初提出的分類方法 IP Precedence (IPP) 就把 Packet 分成 8 個類別,IPP 值越高代表越重要。雖然 ToS 有 8 Bits,但 IPP 只應用到 ToS 的首 3 Bits,如下表:

IPP 名稱IPP 二進數IPP 十進數RFC 建議分類例子
Routine 000 0 Best Effort Data FTP, File Transfer
Priority 001 1 Medium Priority Data 企業內中度重要性 Application
Immediate 010 2 High Priority Data 企業內高度重要性 Application
Flash 011 3 Call Control/Signaling RTSP
Flash Override 100 4 Video RTP
Critical 101 5 VoIP RTP
Internetwork Control 110 6 Internetworking/Routing OSPF, EIGRP
Network Control 111 7 Reserved Reserved

Differentiated Services Code Point (DSCP)

而另一個分類方法 DSCP 則用到 ToS 的首 6 Bits,首 3 Bits 依舊用來判斷重要性,但需留意的是,在 DSCP 的立場上 Assured Forwarding (AFxx) 之間不存在重要性差異,即是說:所有 4 個 AF 的重要性相同。然而如果 Packet 經過一些只支援 IPP (只檢測 ToS 首 3 Bits) 卻不支援 DSCP 的 Software Queuing 系統,分別就出來了,所以習慣上仍會視 AF4x 比 AF1x 重要。而第 4 和 5 Bits 則代表 Packet 的 Drop Preferences,當 Congestion 發生時,Drop Preferences 越大的 Packet 較傾向被 Drop 掉,因此可以理解為在同一個 AF 裡,例如 AF1x,AF12 比 AF11 差,因 AF12 較易被 Drop,而 AF13 比 AF12 更差。至於第 6 Bit 暫時沒有被使用,必然填上 0。由於 6 Bits 共產生 64 個值 (2^6=64),DSCP 也可用一個十進制數字代表,針對 AF,有一條公式可以很快地計算出 DSCP 10 進位值:AFxy=(8*x)+(2*y)。

一個較特別的 DSCP 稱為 Expedited Forwarding (EF),業界一般會把 Voice Traffic 這類即時性及不可延遲的 Traffic 放進 EF,文章稍後會提到針對 EF Traffic 的特別處理。

分類名稱次分類DSCP 16 進制DSCP 10 進制Cisco 建議應用例子
Bit 1-3Bit 4-5Bit 6
DF   000 00 0 0 Best Effort Internet Browsing
CS1   001 00 0 8 Scavenger iTunes, BitTorrent
AF1 AF11 001 01 0 10 Bulk Data   E-mail, FTP  
AF12 001  10 0 12
AF13 001  11 0 14
CS2   010 00 0 16 Admin System SNMP, SSH
AF2 AF21 010 01 0 18 Transaction Data   Enterprise Application  
AF22 010 10 0 20
AF23 010  11 0 22
CS3   011 00 0 24 Signaling SIP, H323
AF3 AF31 011 01 0 26 Multimedia Streaming  
AF32 011 10 0 28
AF33 011  11 0 30
CS4   100 00 0 32 Real-time Interactive  
AF4 AF41 100 01 0 34 Multimedia Conferencing    
AF42 100  10 0 36
AF43 100  11 0 38
CS5   101 00 0 40 Broadcast Video  
EF   101 11 0 46 VoIP Telephony G711, G729
CS6   110 00 0 48 Network Control OSPF, HSRP, IKE
CS7   111 00 0 56 Reserved Reserved

class-map 與 policy-map

知道 IPP 和 DSCP 的理論後,下一步是如何幫 Packet 設定 IPP 或 DSCP。

先說 Classification,可用 class-map 指令訂明 Class 的名稱,然後用 match 把條件輸入。可以 match 的選擇太多,未能一一列舉,不過最常用的應該是 match access-group 和 match protocol。另外,如果 Packet 本身已經在其他 Router 被寫下了 IPP 或 DSCP,則可用 match ip precedence 或 match ip dscp。留意 match-all 為 AND case,必需全條件附合;match-any 為 OR case,只需附合其中一個條件便可。請看以下例子:

class-map match-all CLASS-EF
 match access-group name TRAFFIC-VOICE
class-map match-any CLASS-AF11
 match protocol snmp
 match protocol ssh
class-map match-all CLASS-AF43
 match ip dscp af43
ip access-list extended TRAFFIC-VOICE
 permit ip 192.168.100.0 0.0.0.255 any

然後就是 Marking 了,用 policy-map 把剛才所建的 Class 設定 IPP 或 DSCP 值。class-default 是一個預設的 Class,所有沒有被分類的 Traffic 都會跌入 class-default,理論上可以為 class-default 定 DSCP 值,但很少會這樣做。如 Packet 本身已被 Marking,再做一次 Marking (Re-marking) 會覆蓋原設定。

policy-map POLICY-INCOMING
 class CLASS-EF
  set dscp ef
 class CLASS-AF11
  set dscp af11
 class CLASS-AF43
  set dscp af43
 class class-default
  set dscp default

最後緊記把 policy-map 放進 Interface 便大功告成,Classification 與 Marking 一般用在 Router 的 Ingress Interface (input)。

R2(config-if)#service-policy input POLICY-INCOMING

Software Queuing

故事來到最精彩的情節,現在集中觀看 Software Queue 和 Hardware Queue 的部份。當網絡暢通時,Packet 抵達 Software Queue 就立刻被送到 Hardware Queue 排隊等待被送出,Software Queue 並不會發生作用。但如果 Traffic 量太多,處理得不夠快,Hardware Queue 便會爆滿,Packet 被積存於 Software Queue 等待,此時 Software Queue 便要考慮 Packet 要排在那條隊列和每次安排那條隊列的 Packet 進入 Hardware Queue。現時考試最需要了解的只有 Weighted Fair Queuing (WFQ) 和 Class-based Weighted Fair Queuing (CBWFQ)。

Weighted Fair Queuing (WFQ)

Weighted Fair Queuing (WFQ) 會給每條 Traffic Flow 建立一條 Software Queue,根據 IPP 計算出每條 Flow 的 Weight。Scheduler 從 Software Queue 拿出 Packet 放進 Hardware Queue 的次數是按照 Weight 的反比,即是說 Weight 越大,則 Scheduler 從這條 Queue 取出 Packet 的次數越少;相反如果 Weight 越小,Scheduler 服務這條 Queue 的次數越多。

在 Hardware Queue 沒有爆滿時,WFQ Software Queue 並不會建立。

quality of service

Packet 太多,Interface 處理速度不夠快,Hardware Queue 爆滿,WFQ Software Queue 按照 Traffic Flow 的數量被產生,理論上每條 Queue 只服務一條 Traffic Flow,除非 Traffic Flow 數量比 Max Queue (預設 64 條) 多,不同的 Flow 便會被安排在同一條 Queue。

quality of service

Scheduler 按 Weight 的反比例向每條 Software Queue 設定服務量 (按 Bit 計算),拿出適當數量的 Packet 放進 Hardware Queue。因此,Weight 越低的 Traffic Flow 能獲得更多的 Bandwidth。

quality of service

Cisco Router 對 Weight 的計算方法如下:32384/(IPP+1),舉例:IPP 3 的 Weight 為 32384/(3+1)=8096,IPP 越高則 Weight 越小,能得到較佳的服務質量。但到底不同的 Weight 所得到的 Bandwidth 實際上是多少呢?筆者無法在網絡上找到文獻記載,如果你知道的話請告訴我。

Class-based Weighted Fair Queueing (CBWFQ)

比起 WFQ 自動建立 Software Queue,CBWFQ 容許我們預先建立不同的 Queue 並設定其 Bandwidth。建立 Queue 的方法仍然是用 class-map 指令,跟之前在 marking 章節中相同,不在此重覆。然後便可在 policy-map 設定其 Bandwidth (以 Kbps 為單位):

policy-map POLICY-OUT
 class CLASS-EF
  bandwidth 100
 class CLASS-AF11
  bandwidth 200
 class CLASS-AF43
  bandwidth 300
 class class-default
  bandwidth 400

按照這設定,當 Congestion 發生時,Scheduler 會梅花間竹地從每條 Queue 拿走 Packet。Scheduler 每秒在 CLASS-EF 拿走大約 100K 到 Hardware Queue,每秒在 CLASS-AF11 拿走大約 200K 到 Hardware Queue,如此類推。class-default 包含所有未分類 Traffic,有趣的是 CBWFQ 會為 class-default 執行 WFQ,即 CBWFQ 這個 Software Queue 裡面包含了一個 WFQ 的 Software Queue,如下圖:

quality of service

另一個可以使用的 Keyword 是 priority,即 Low Latency Queue (LLQ)。LLQ 優勝之處是每次 Hardware Queue 有空間,Scheduler 必然會先從 LLQ 拿取 Packet,然後才梅花間竹地從其他 Queue 取 Packet,適合 Live Streaming 的 Traffic Flow,例如 VoIP Traffic。每條 Policy 只容許一條 LLQ,習慣上會為 DSCP EF 設定 LLQ。

policy-map POLICY-OUT
 class CLASS-EF
  priority 300
 class CLASS-AF11
  bandwidth 200
 class CLASS-AF43
  bandwidth 100

quality of service

除了直接設定 Bandwidth,我們也可以用 percent 去讓 policy 自動計算 Bandwidth,當然總和必需等於或少於 100%。

policy-map POLICY-OUT
 class CLASS-EF
  priority percent 30
 class CLASS-AF11
  bandwidth percent 20
 class CLASS-AF43
  bandwidth percent 10
 class class-default
  bandwidth percent 10

percent remaining 則代表把總 Bandwidth 先扣除了 priority 所佔用了的 Bandwidth 後,用餘額去計算百份比。

policy-map POLICY-OUT
 class CLASS-EF
  priority 100
 class CLASS-AF11
  bandwidth remaining percent 40
 class CLASS-AF43
  bandwidth remaining percent 30
 class class-default
  bandwidth remaining percent 20

假設 Interface 的 Bandwidth 是 1000K,以上設定的 Bandwidth 分配結果如下:

quality of service

Congestion Avoidance

話說每條 Software Queue 都有一個叫作 Queue Limit 的限制,表示最多可容納的 Packet 數量,預設為 64。當 Software Queue 爆滿,某些 Packet 便要有所犧牲,騰出空間給新來的 Packet,這就是 Congestion Avoidance。

Tail Drop

把新來的 Packet Drop 掉就是 Tail Drop。使用 Tail Drop 會出現幾個問題:(1) Tail Drop 不查看 ToS,這會把重要的 Packet Drop 掉;(2) Drop 掉一條 TCP Flow 的連續多個 Packet,TCP Flow 會因為 Timeout 而斷掉;(3) 被同一時間 Tail Drop 的多條 TCP Flow 可能會同一時間斷掉並在同一時間重新傳送,造成惡性循環,這稱為 Global Synchronization。Software Queue 預設使用 Tail Drop,不需作任何設定。

quality of service

Weighted Random Early Detection (WRED)

較理想的方法是 Weighted Random Early Detection (WRED),WRED 可按 Packet 的 IPP 或 DSCP 設定不同的 Drop Policy。設定的參數有 3 個:

Minimum Threshold

代表當 Queue 長度達到多少便開始執行 Drop。

Probability Denominator

要 Drop 多少個 Packet 呢?如把 Probability Denominator 設定為 10,意思是把 Queue 中每 10 個 Packet 隨機選 1 個 Drop 掉。如此類推。

Maximum Threshold

到 Queue 過了 Maximum Threshold,就強制發生 Tail Drop 了。

quality of service

如要使用 WRED,只需在 Policy-map 的 Class 中加入 random-detect 指令,預設使用 IPP。唯 LLQ 不可設定 WRED。

policy-map POLICY-OUT
 class CLASS-EF
  priority 100
 class CLASS-AF11
  bandwidth remaining percent 40
  random-detect
 class CLASS-AF43
  bandwidth remaining percent 30
  random-detect
 class class-default
  bandwidth remaining percent 20
  random-detect

show policy-map interface 可以看到自動產生的 Probability Denominator 設定。可見 IPP 越高,Minimum Threshold 越大,越難發生 Drop。

<--Output Omitted-->
  Class-map: CLASS-AF11 (match-any)  
      0 packets, 0 bytes
      30 second offered rate 0000 bps, drop rate 0000 bps
      Match: ip dscp af23 (22)
        0 packets, 0 bytes
        30 second rate 0 bps
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/0/0
      (pkts output/bytes output) 0/0
      bandwidth remaining 30%
        Exp-weight-constant: 9 (1/512)
        Mean queue depth: 0 packets
        class     Transmitted       Random drop    Tail drop        Minimum      Maximum   Mark
                  pkts/bytes        pkts/bytes     pkts/bytes       thresh       thresh    prob
        
        0             0/0             0/0            0/0               20          40  1/10
        1             0/0             0/0            0/0               22          40  1/10
        2             0/0             0/0            0/0               24          40  1/10
        3             0/0             0/0            0/0               26          40  1/10
        4             0/0             0/0            0/0               28          40  1/10
        5             0/0             0/0            0/0               30          40  1/10
        6             0/0             0/0            0/0               32          40  1/10
        7             0/0             0/0            0/0               34          40  1/10
<--Output Omitted-->

如要修改,可用 random-detect precedence <IPP> <min> <max> <prob>

R2(config-pmap-c)#random-detect precedence 5 25 30 20
<--Output Omitted-->
Class-map: CLASS-AF11 (match-any)  
      0 packets, 0 bytes
      30 second offered rate 0000 bps, drop rate 0000 bps
      Match: ip dscp af23 (22)
        0 packets, 0 bytes
        30 second rate 0 bps
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/0/0
      (pkts output/bytes output) 0/0
      bandwidth remaining 30%
        Exp-weight-constant: 9 (1/512)
        Mean queue depth: 0 packets
        class     Transmitted       Random drop    Tail drop        Minimum      Maximum   Mark
                  pkts/bytes        pkts/bytes     pkts/bytes       thresh       thresh    prob
        
        0             0/0             0/0            0/0               20          40  1/10
        1             0/0             0/0            0/0               22          40  1/10
        2             0/0             0/0            0/0               24          40  1/10
        3             0/0             0/0            0/0               26          40  1/10
        4             0/0             0/0            0/0               28          40  1/10
        5             0/0             0/0            0/0               25          30  1/20
        6             0/0             0/0            0/0               32          40  1/10
        7             0/0             0/0            0/0               34          40  1/10
<--Output Omitted-->

如想 WRED 用 DSCP 作判斷,則在 random-detect 後加上 dscp-based 便可。

policy-map POLICY-OUT
 class CLASS-EF
  priority 100
 class CLASS-AF11
  bandwidth remaining percent 40
  random-detect dscp-based
 class CLASS-AF43
  bandwidth remaining percent 30
  random-detect dscp-based
 class class-default
  bandwidth remaining percent 20
  random-detect dscp-based

修改 Probability Denominator 指令相若。

R2(config-pmap-c)#random-detect dscp af11 25 30 20

Explicit Congestion Notification (ECN)

雖然 Drop Packet 已經可以讓 TCP Flow 被動地減速,但除了 Drop Packet 之外,還有一個方法可讓 TCP 主動減速,就是 Explicit Congestion Notification (ECN)。Software Queue 可在 Queue 即將被填滿之前告訴 TCP Flow 的 Receiver Congestion 即將發生,Receiver 在收到此訊號後可在發 TCP ACK 時告知 Sender 減速 (透過調校 Windows Size),前題是 TCP Flow 的兩端 Host 都支緩 ECN。在介紹 Marking 的章節時說過 ToS 一共有 8 Bits,DSCP 只用了首 6 Bits,最後兩 Bits 就是用作 ECN,分別是 ECN Capable Transport (ECT) 和 Congestion Experienced (CE)。如 Sender 支持 ECN 則會把 ECT 設成 1,Queue 超過 Minimum Threshold 時,如 Software Queue 發現 ECT 是 1,則不 Drop Packet,反而會把 CE 設成 1 並傳給 Receiver,藉此告知 Receiver 即將發生 Congestion。Receiver 收到 CE=1 後便會告訴 Sender 需要把傳送速度降低。如 Host 不支緩 ECN (ECT=0),Software Queue 則依 WRED 設定 Drop Packet。要設定 ECN 只需在 policy-map 的 class 裡加入 random-detect ecn。

policy-map POLICY-OUT
 class CLASS-EF
  priority 100
 class CLASS-AF11
  bandwidth remaining percent 40
  random-detect dscp-based
  random-detect ecn
 class CLASS-AF43
  bandwidth remaining percent 30
  random-detect dscp-based
  random-detect ecn
 class class-default
  bandwidth remaining percent 20
  random-detect dscp-based
  random-detect ecn

Hierarchical Policies

IOS 的 Policy 支援最多三層架構 (Hierarchical),又稱為 Nested Policy,通常配合 Traffic Management 一起使用,以下是一個兩層架構的例子,把 Inbound Traffic 先 Police 至 10Mb,然後再執行 Classification 與 Marking。

policy-map TRAFFIC-POLICING
 class class-default
  police rate 10000000 
   service-policy POLICY-INCOMING

關於 Policing 的設定請參考介紹 Traffic Management 的文章。