做网络运维这些年,我越来越觉得MQC(模块化QoS命令行)是被低估的一套工具。很多人一提QoS就想到限速,一提过滤就想到ACL,但实际上把MQC吃透之后,流量过滤、优先级标记、限速、重定向这些需求都可以用同一套"分类-行为-策略"框架统一解决,配置逻辑非常清爽。这篇是MQC系列的第二篇,重点是基本配置和流量过滤,从原理讲到命令,再到我在现网上排错时真实踩过的几个坑,尽量一次讲透。适合正在学数通基础、准备设备认证,或者需要在组网里做精细化流量控制的同行参考。
先说一个很多人没想明白的点:MQC不是某个具体功能,而是一种配置组织方式。它把复杂策略拆成三个独立部件——流分类、流行为、流策略,然后再把策略绑定到接口上。好处是,你可以在多个接口复用同一套策略,也能在不改动ACL的情况下单独调整某类流量的动作。下面我按自己实际配置的顺序,把整个过程展开。
1. 先把MQC三要素拆开:分类、行为、策略到底在配置什么
1.1 三要素的职责边界
MQC的整套逻辑可以压缩成三段式:先定义"哪些流量",再定义"拿这些流量怎么办",最后把两者组合起来并绑定到接口。对应到命令上就是三类配置块:
traffic classifier:流分类,负责描述报文的匹配条件,例如源地址、目的地址、端口号、DSCP值、VLAN、甚至上下行接口。traffic behavior:流行为,负责定义动作。最常见的是permit、deny,也就是流量过滤里的放行和丢弃;后续还可以叠加限速、重标记、重定向。traffic policy:流策略,把分类器和行为绑定在一起,并给每个分支设置优先级,最后整体应用到接口的入方向或出方向。
类比一下生活场景:分类器像门禁的识别规则,行为像保安的执行动作,策略像整套门禁方案,接口绑定则是把这套方案装到某一扇门上。这样拆开之后,新增一种流量的过滤规则时,完全不需要动其他部分。
1.2 和传统ACL接口政策的差异
早期配置流量过滤,通常是直接在接口下写ACL,或者把ACL套到接口的traffic-filter上。这种方式在小规模场景里够用,但问题很明显:多个接口要做相同过滤时,配置冗余;想调整某一类流量的动作时,只能删掉整个ACL重新写;ACL和动作绑定得太死,没法灵活组合。
MQC则把匹配条件和动作彻底解耦。同一套ACL可以被不同流分类引用,同一个流行为也可以被多个流策略复用。举个我在某园区网络里的例子:出口路由器上既要过滤内网访问某个高风险端口段的流量,又要对视频流量做DSCP重标记,还要限制P2P下载带宽。若用传统方式,三个需求就要在接口上写三套ACL策略,互相穿插,排错时根本分不清哪条规则管哪部分。用MQC拆开后,每个需求各自独立,策略之间互不干扰。
需要留意的是,MQC的本质是"基于类的策略框架",它本身不产生新的QoS能力,而是把ACL、队列、限速等底层机制组织得更清晰。理解了这一点,后面配置时你对每条命令的意图就会很明确。
1.3 和策略路由有什么关系
标题里的"策略路由"和MQC并不矛盾。策略路由的核心是"根据策略决定报文下一跳",而MQC是承载这个策略的框架之一。实际配置中,流行为可以包含redirect ip-nexthop这类动作,把匹配到的流量引到其他路径。也就是说,MQC既可以做流量过滤(deny/permit),也可以变相实现策略路由,这取决于你给行为块定义什么动作。本篇以过滤为主线,最后我会专门讲一下如何扩展成重定向和限速。
2. 一个我能复现的过滤场景:拓扑、地址和过滤目标怎么定
2.1 先说清楚过滤什么
动手配置前,最重要的事情不是敲命令,而是把过滤目标写下来。我给自己设计了一个可复现的实验场景:一台充当网关的路由器连接了两个网段,一侧是办公终端所在的VLAN 10,地址段为192.168.10.0/24;另一侧是服务器所在VLAN 20,地址段为192.168.20.0/24。业务需求有两条:
- 办公网段只允许访问服务器的
TCP 80/443端口,其他访问一律丢弃。 - 办公网段内部允许互相访问,但禁止访问服务器网段里一个测试用的高危端口段
TCP 20000-20100。
这个场景非常典型:既要基于五元组做细粒度匹配,又要对不同目的地址执行不同动作。用MQC实现时,我会把它拆成两个流分类、两个流行为、一个流策略。
2.2 接口和地址规划
实验拓扑很简单,可以用模拟器,也可以用两台物理设备串联。我这里以一台三层设备为例,接口规划如下:
| 接口 | 用途 | 地址 |
|---|---|---|
| GE0/0/1 | 接入办公网段 | 192.168.10.254/24 |
| GE0/0/2 | 接入服务器网段 | 192.168.20.254/24 |
设备上先确保两个接口物理状态正常,直连地址能互相ping通,路由表里有对应直连路由。我习惯在配置策略前先做一轮基础连通性测试,避免后面策略不生效时,还要分心排查基础故障。
2.3 配置思路的提前规划
明确了需求之后,我通常画一个简单的匹配决策表,把每条流量对应到具体分类器和行为:
| 流量特征 | 分类器名称 | 行为名称 | 动作 |
|---|---|---|---|
| 目的TCP 80/443 | classifier_web | behavior_allow | permit |
| 目的TCP 20000-20100 | classifier_test_port | behavior_deny | deny |
| 其他所有流量 | 不匹配任何分类器 | 默认放行 | permit |
这里有个细节:MQC流策略默认对未匹配流量执行放行,所以只要把需要丢弃的流量单独区分出来即可。如果你的需求是"默认拒绝一切、只放行白名单",就需要额外加一个匹配所有报文的分类器,行为设为deny,并把它放在策略的最低优先级。
这个规划阶段看似麻烦,却是我每次少走弯路的关键。到了命令行下面,思路已经定了,配置只是把表格翻译成命令而已。
3. MQC流量过滤配置全流程:从ACL匹配到接口绑定
3.1 用ACL定义流分类的匹配条件
MQC的流分类支持多种匹配方式,比如if-match acl、if-match dscp、if-match vlan-id、if-match ip next-hop等。流量过滤场景下最常用的是匹配ACL,因为ACL能表达五元组级别的精细条件。
acl number 3001 rule 5 permit tcp destination-port eq 80 rule 10 permit tcp destination-port eq 443 acl number 3002 rule 5 permit tcp destination-port range 20000 20100注意ACL编号的含义:2000-2999是基本ACL,只能匹配源地址等简单字段;3000-3999是高级ACL,可以匹配协议、源目地址、端口号等。我的两个过滤条件都需要匹配目的端口,所以都用高级ACL。
定义完ACL后,在系统视图下创建流分类并挂接ACL:
traffic classifier classifier_web operator or if-match acl 3001 traffic classifier classifier_test_port operator or if-match acl 3002这里有一个经常被忽略的点:operator or表示分类器内多个匹配条件之间是"或"关系,只要命中任意一条就算匹配;如果写成operator and,则所有条件必须同时满足。我这两个分类器里都只引用一个ACL,所以or/and效果一样,但后续如果你要叠加多个匹配条件,一定要提前想清楚逻辑关系。
3.2 定义流行为:过滤就是permit和deny
流行为块里的permit和deny,对应到流量过滤就是"放行"和"丢弃"。
traffic behavior behavior_allow permit traffic behavior behavior_deny deny不少新手看到permit会下意识以为这是ACL里的permit,把两边混淆。实际上这两层是独立生效的:ACL里的permit只是让报文"被这个分类器选中",真正决定报文最终是通过还是丢弃的,是流行为里的动作。ACL如果写deny,那么这条流压根不会进入分类器,后续的permit/deny动作都不会执行,这会导致策略表现"莫名其妙地不匹配"。我在第4节会专门展开这个坑。
3.3 组策略并在接口上生效
有了分类器和行为,接下来用流策略把它们串起来:
traffic policy policy_filter classifier classifier_web behavior behavior_allow precedence 10 classifier classifier_test_port behavior behavior_deny precedence 20precedence是策略内部的匹配优先级,数字越小越先匹配。报文进入策略后,先和优先级最高的分类器比对,匹配就执行对应行为,不再往下匹配。我上面之所以把classifier_web设为10、classifier_test_port设为20,主要考虑到web放行是正常业务流量,应优先处理。
然后绑定到接口:
interface GigabitEthernet0/0/1 traffic-policy policy_filter inbound在GE0/0/1的入方向应用,意味着从办公网段进入设备的所有报文都要经过该策略过滤。方向选择非常关键:办公终端访问服务器,流量从办公网段进入设备,所以在GE0/0/1的inbound方向应用;如果需求是限制从服务器方向进入办公网段的流量,则应该绑定到GE0/0/2的inbound或GE0/0/1的outbound。方向搞反是MQC配置失败最常见的原因之一。
3.4 验证配置和实际效果
配置完成后,先查看策略是否成功挂载:
display traffic policy applied record确认接口、方向、策略名都正确。然后测试办公终端访问服务器的80端口和20000端口,同时用设备侧统计观察命中次数:
display traffic policy statistics interface GigabitEthernet0/0/1 inbound理想结果是:访问80/443命中behavior_allow分支,访问20000端口命中behavior_deny分支,丢弃计数增长。到这一步,最基础的MQC流量过滤已经跑通了。实际网络环境里,可能还会碰到策略不生效、误伤正常流量、设备CPU占用上升等问题,下面重点讲排查思路。
4. 策略不生效的排错链路:我实际遇到的三类问题
4.1 坑一:ACL的permit/deny和多层动作叠加搞混
有次现场反馈说,办公网段的终端访问服务器端口全部不通,但配置明明是按白名单放行的。我登进设备一看,ACL 3001里写的是:
acl number 3001 rule 5 deny tcp destination-port eq 80 rule 10 permit tcp destination-port eq 443第一眼很难发现问题,因为这组ACL挂在classifier_web下面,而流行为是permit。按很多人的直觉,ACL deny了80端口,那80端口就被拒了,这没错;但问题在于ACL deny掉的流量,根本不会进入分类器,所以流行为里的permit对这条ACL规则完全不起作用。最终表现就是所有目的端口为80的报文在分类器这一层就被"排除"了,看上去像被过滤,实际上是被ACL拒绝,而不是被流行为处理。
ACL在MQC里的角色是"选择器",它负责决定"哪些报文进入分类器",而不是直接决定报文生死。正确的做法是:ACL规则全部写成permit,只描述匹配特征;真正的放行或丢弃交给流行为。用deny写ACL只会让报文失去后续处理机会。
4.2 坑二:接口方向选错导致策略静默失效
另一个常见问题是策略绑定到了错误方向。某次客户在出口路由器上做了入方向的流量过滤,要求过滤内网访问外网某端口的流量,配置完成后测试发现完全不生效。我检查发现,策略被绑定在了出接口的outbound方向,而内网流量到达出接口时已经被路由处理完了,出方向策略实际上针对的是即将从该接口发出的报文,和"内网访问外网"的流量方向相反。
判断方向时,我习惯先画一条流量路径:源终端 -> 源接口入方向 -> 设备转发 -> 目的接口出方向 -> 目的终端。要过滤的是哪一段路径上的流量,就绑定到对应接口的对应方向。对于网关设备,过滤进入的流量一般用入接口的inbound,过滤发往某个方向的流量则用出接口的outbound。
4.3 坑三:策略内优先级顺序导致误匹配
优先级问题往往在复杂策略里出现。假设策略里有两条分类器:
classifier_a:匹配目的端口8080,动作是denyclassifier_b:匹配目的地址192.168.20.0/24,动作是deny
如果classifier_b的优先级是5,classifier_a的优先级是10,那么访问服务器8080端口的报文会先匹配classifier_b并被deny,而classifier_a的逻辑根本不会执行到。从结果看,访问8080端口确实不通,但你无法判断是a规则生效还是b规则生效,排错信息就会很混乱。更危险的是,如果某条宽泛匹配的分类器优先级过高,它可能"吃掉"后面所有更精细化分类器的流量,导致后者的deny/permit完全不生效。
我现在的习惯是:越具体的匹配条件优先级越高,precedence数字越小;宽泛条件放在后面兜底。每次修改策略后,用统计命令确认每个分支的命中计数是否符合预期,而不是只看通不通。
4.4 排错工具的使用顺序
遇到"策略不生效",我建议按以下顺序排查,不要一上来就怀疑设备有bug:
- 确认策略已正确应用:
display traffic policy applied record,重点看接口名、方向、策略名。 - 确认流量确实经过了该接口方向:用
display interface看接口流量计数是否增长。 - 确认分类器命中情况:
display traffic policy statistics,看哪个classifier匹配次数是0。 - 若所有分类器匹配次数都是0,多半是ACL条件写错了,或者ACL里用了deny导致报文进不了分类器。
- 若匹配次数在增长但业务还是不通,重点看流行为动作,以及后续是否有其他策略或路由策略覆盖了结果。
这套链路我每次都能定位到问题根因,基本没有落空过。
5. 从过滤到QoS全家桶:限速、重标记和策略路由联动
5.1 用MQC做限速
流量过滤只是MQC的入门动作。在同一个框架下,把流行为改成限速也很简单:
traffic behavior behavior_limit car cir 8000 pir 10000cir是承诺信息速率,单位通常为kbps,pir是峰值信息速率。理解上可以类比水管:CIR是保证流量,PIR是允许突发的水量上限。把行为绑定到指定流量后,就能实现"只对某类流量限速,其余流量不限制"的精细化QoS。相比在接口上做整体限速,MQC的优势在于可以区分用户、业务和目的网段。
5.2 用MQC重标记报文优先级
另一个常用动作是重标记DSCP或802.1p优先级:
traffic behavior behavior_remark remark dscp ef匹配到的流量被标记为EF后,下游设备就可以依据这个标记做队列调度,实现端到端的差分服务。这个场景非常实用:内网视频会议流量从终端发出时优先级较低,穿过中间设备时可能被普通流量挤占;在入口设备上用MQC识别视频流并重标记,后面的转发设备就能识别并优先处理。
5.3 扩展成策略路由:redirect到其他下一跳
回到标题里的"策略路由"。在MQC流行为中,可以直接指定报文的下一跳或出接口:
traffic behavior behavior_redirect redirect ip-nexthop 10.1.1.2 traffic policy policy_pbr classifier classifier_special behavior behavior_redirect precedence 5这样匹配到的流量会被强制引导到10.1.1.2,而不是根据路由表正常转发。这时候MQC实际上承担了策略路由的工作,且策略的匹配条件比传统PBR更丰富,能叠加ACL、DSCP、VLAN等维度。我通常建议把MQC重定向当作策略路由的一种灵活实现方式,特别是在分类器条件较多的组网里,比单纯写PBR策略更易维护。
5.4 配置规模与性能边界
MQC虽好,但不是没有代价。每增加一个策略分支,设备在转发面上就需要多维护一条匹配规则;分类器越多,匹配耗时越长。在低端盒式设备上,我曾经把流策略扩展到几十条分类器,结果发现接口转发性能明显下降,ping时延抖动。后来我把匹配项合并,能用一条ACL描述的就不拆成多个分类器,同时把策略应用下沉到接入层设备,分散匹配压力,问题才解决。
另外,不同厂商对MQC的层次和调度算法有差异,迁移配置时要先核对语法和特性支持情况,不要想当然照搬。
6. 一些关于MQC配置顺序与维护的小习惯
6.1 配置前先备份,修改前先看统计
我在现网上凡是涉及MQC变更,都坚持先备份配置文件,并对现有策略做一次display traffic policy statistics快照。这样做的好处是,改完后可以通过计数对比,快速判断新策略是否真的生效,以及是否误伤其他流量。
6.2 命名规范和注释意识
MQC配置多了以后,最难维护的不是命令,而是"当时为什么这么写"。给分类器、行为、策略起名时,我会加入业务语义,比如classifier_video_conf、behavior_limit_p2p,而不是classifier1、behavior1。同时我会在配置关键节点用备注说明流量来源、业务归属和联系人。别觉得这是形式主义,半年后回头看配置时,清晰命名能省下大量沟通成本。
6.3 小步变更,逐步验证
一次性把过滤、限速、重标记、重定向全部加进同一个策略,出问题后很难隔离。我的做法是一条业务需求对应一个分支,配置完立即用测试流量验证,确认无误后再加下一个分支。正验证,负验证都要做:既测试"应该放行的流量",也测试"应该丢弃的流量",两边都符合预期,才算真的配置正确。
我自己在多次MQC调试后最大的体会是:这套框架的价值不在于单个功能有多强,而在于它让你把"匹配"和"动作"分开思考,逼迫你在配置前就把流量模型理清楚。只要前期规划到位,后面无论过滤、限速还是策略路由,都只是往行为块里加动作而已。希望这篇记录对正在折腾MQC的你有实际帮助。