目录

前言
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 送走 (Outgress),详情可阅读本网页关於 Routing Decision 的文章。然而 Packet 在送走前需要在 Outgress 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 不发生吗?先说 Outgress Interface 的 Hardware Queue,容量是可以调校的,但 Outgress Hardware Queue 加长後会让重要和不重要的 Packet 一同塞在 Queue 排队,导致所有 Traffic 都出现 Delay 的情况,有些 Protocol 也可能会因为等太久而出现 Timeout 造成中断。因此,解决方法应为:当 Tail Drop 发生时,立刻检查 Packet 的重要性,重要的 Packet 优先放入 Outgress Hardware Queue,不重要的迟些才放入,甚至直接 Drop 掉不放入,保留 Outgress 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 长度,如要修改 Outgress 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 的文章。