资讯动态

华为前缀列表深度解析:原理、配置与BGP/OSPF路由过滤实战

发布时间:2026/10/17 11:22:17 来源:尧图企业网站定制
1. 前缀列表到底解决了什么问题第一次接触前缀列表是在一个园区网改造项目里当时需要在一台核心设备上做路由过滤要求很明确只允许特定的几条业务网段通过其余全部拒绝。我一开始用的是基础ACL写完发现根本没法精确匹配掩码长度——比如我想只放行 10.1.0.0/16但ACL的规则会把 10.1.1.0/24 这种更具体的子网也一并放过去。这个问题困扰了我好一阵直到翻文档才意识到前缀列表ip ip-prefix才是干这个事的正确工具。前缀列表本质上是一个路由匹配工具它和ACL最大的区别在于ACL匹配的是数据包的源目地址而前缀列表匹配的是路由条目本身而且能同时匹配网络地址和掩码长度。这个能力在路由策略场景里非常关键。你可以把它理解成一个带掩码校验的筛子——不光看网段对不对还要看掩码长度是否符合预期。它主要用在几个地方路由引入时的过滤、BGP邻居的路由收发策略、OSPF/IS-IS区域间的路由过滤等。适合谁学我觉得只要你在做网络运维、路由交换配置或者准备考华为认证HCIP/HCIE方向前缀列表都是绕不过去的基本功。它不像某些高级特性那样只在特定场景才用得上而是日常配置里高频出现的工具。这篇文章我会从原理讲到实验把匹配规则、配置命令、常见坑点都拆开说清楚。所有实验基于华为VRP系统用eNSP模拟器就能完整复现。我尽量把每个参数为什么这么设、不这么设会出什么问题都讲透让你看完能直接上手配。2. 前缀列表的核心原理拆解2.1 和ACL的本质区别在哪很多人刚学的时候会把前缀列表和ACL混为一谈觉得都是过滤工具随便用哪个都行。实际上两者的匹配维度完全不同。ACL匹配的是地址范围比如 10.1.1.0 0.0.0.255 匹配的是 10.1.1.0/24 这个网段里的所有地址。而前缀列表匹配的是路由前缀格式是 网络地址 掩码长度。举个例子你就明白了。假设有一条路由 10.1.1.0/24你用ACL规则rule permit source 10.1.0.0 0.0.255.255这条路由是能匹配上的。但如果你只想匹配掩码长度恰好是24位的路由ACL就无能为力了——它没法表达掩码必须是24这个条件。前缀列表可以写成ip ip-prefix test permit 10.1.0.0 16 less-equal 24这样就能精确控制掩码范围。这个区别在实际项目里影响很大。比如做BGP路由汇总的时候你只想接收汇总路由而不接收明细路由用ACL根本做不到必须用前缀列表配合掩码长度范围来精确匹配。2.2 匹配规则的五种写法前缀列表的匹配规则看起来简单但里面的门道不少。核心语法是ip ip-prefix 名称 [index 序号] permit|deny 网络地址 掩码长度 [匹配模式]掩码长度后面可以跟几种匹配模式这是最容易搞混的地方。我把它整理成表格方便对照匹配模式含义示例匹配结果不写精确匹配掩码长度permit 10.1.0.0 24只匹配 10.1.0.0/24greater-equal X掩码长度大于等于Xpermit 10.1.0.0 16 greater-equal 24匹配 10.1.0.0/24 到 /32less-equal X掩码长度小于等于Xpermit 10.1.0.0 16 less-equal 24匹配 10.1.0.0/16 到 /24greater-equal X less-equal Y掩码长度在X到Y之间permit 10.1.0.0 16 greater-equal 20 less-equal 24匹配 /20 到 /24只写网络地址不写掩码匹配所有掩码permit 10.1.0.0匹配 10.1.0.0 开头的所有路由这里有个关键点当你不写掩码长度、只写网络地址的时候它匹配的是网络地址部分相同的所有路由掩码长度不限。这个用法在需要放行某个大网段下所有子网时很方便但也很容易误放行不该放的路由用的时候要小心。还有一个细节greater-equal 和 less-equal 后面的数字必须大于等于前面写的掩码长度。比如你写permit 10.1.0.0 24 greater-equal 16这是非法的因为16小于24。设备会直接报错。这个规则背后的逻辑是前缀列表匹配的前提是网络地址部分要先匹配上掩码长度范围是在这个基础上做进一步筛选。2.3 序号和匹配顺序的坑前缀列表和ACL一样是按序号从小到大依次匹配的一旦匹配上就停止不再往下查。默认情况下如果你不写index设备会自动分配序号步长是10。比如你连续写三条规则序号就是10、20、30。这里有个很多人踩过的坑前缀列表末尾有一个隐式的deny。也就是说如果你写的规则没有匹配上某条路由默认行为是拒绝。这和ACL的隐式拒绝是一样的逻辑。但问题是很多人写前缀列表的时候只写了permit规则忘了考虑没匹配上的路由会被拒绝结果导致一些本该放行的路由被过滤掉了。我的习惯是在写permit规则之前先想清楚哪些要放行、哪些要拒绝如果需求是只拒绝少数几条、其余全放行那就要在末尾显式加一条permit 0.0.0.0 0 less-equal 32来放行所有路由。这条规则的意思是匹配所有网络地址、掩码长度从0到32的路由相当于放行一切。序号还有一个作用方便后续插入或删除规则。如果你一开始用默认序号10、20、30后来想在中间插一条就得重新规划序号。我的建议是初始就留出间隔比如用10、20、30这样中间留空位方便插入。如果要更灵活可以手动指定序号比如10、15、20这样中间还能插12、13。2.4 匹配过程到底怎么走的理解匹配过程对排查问题特别重要。当一条路由过来的时候前缀列表的匹配逻辑是这样的第一步取出路由的网络地址部分和规则里的网络地址做比对。注意这里比对的是网络地址不是掩码。比如规则写的是 10.1.0.0 16那路由的网络地址前16位必须和 10.1.0.0 的前16位一致。第二步如果网络地址匹配上了再看掩码长度是否在规则指定的范围内。如果规则没写掩码范围就精确匹配规则里写的掩码长度。第三步如果网络地址和掩码长度都匹配就执行这条规则的动作permit或deny匹配过程结束。如果没匹配上继续查下一条规则。第四步如果所有规则都没匹配上执行隐式deny路由被拒绝。这个流程看起来简单但实际排查问题的时候经常是网络地址匹配上了、掩码长度没匹配上导致路由被意外拒绝。比如你写permit 10.1.0.0 16结果来了一条 10.1.0.0/24 的路由网络地址部分是一样的但掩码长度是24不是16所以匹配不上继续往下查。如果后面没有能匹配的规则这条路由就被拒绝了。3. 华为设备上的配置实操3.1 基础配置命令逐条拆解先看最基本的配置。假设我们要创建一个名为test-prefix的前缀列表只允许 192.168.1.0/24 这条路由通过ip ip-prefix test-prefix index 10 permit 192.168.1.0 24这条命令拆开看ip ip-prefix是固定开头test-prefix是列表名称自己起建议见名知意index 10是序号可省略省略时自动分配permit是动作192.168.1.0 24是匹配条件。如果要放行一个网段下的所有子网比如 192.168.0.0/16 下面的所有路由ip ip-prefix test-prefix index 10 permit 192.168.0.0 16 less-equal 32这里less-equal 32表示掩码长度从16到32都匹配。为什么是32因为IPv4最大掩码长度就是32。这条规则会匹配 192.168.0.0/16、192.168.1.0/24、192.168.1.1/32 等等。如果要匹配掩码长度在某个区间内的路由比如只要 /20 到 /24 的ip ip-prefix test-prefix index 10 permit 192.168.0.0 16 greater-equal 20 less-equal 24注意这里 greater-equal 后面的20必须大于等于前面写的16否则报错。3.2 在路由策略里调用前缀列表前缀列表本身只是一个匹配工具要真正生效得在路由策略route-policy或者过滤策略filter-policy里调用。最常见的用法是在BGP里做路由过滤。假设我们要在BGP邻居上做入方向过滤只接收 10.1.0.0/16 到 /24 的路由ip ip-prefix bgp-in index 10 permit 10.1.0.0 16 less-equal 24 ip ip-prefix bgp-in index 20 deny 0.0.0.0 0 less-equal 32 route-policy bgp-filter permit node 10 if-match ip-prefix bgp-in bgp 100 peer 10.0.0.2 as-number 200 peer 10.0.0.2 ip-prefix bgp-in import这里有几个点要注意。第一前缀列表里我加了一条显式的deny规则序号20匹配所有路由。为什么要加这条因为如果不加末尾的隐式deny也会拒绝所有没匹配上的路由效果是一样的。但显式写出来更清晰方便后续维护的时候一眼看出意图。第二route-policy 里的 if-match 调用前缀列表node 10 的动作是 permit。如果前缀列表匹配上了route-policy 就放行如果没匹配上route-policy 继续查下一个node如果没有下一个node默认是deny。第三BGP邻居上直接用ip-prefix import也可以不一定要走route-policy。但route-policy更灵活可以在匹配前缀列表的同时还匹配其他条件比如AS路径、团体属性等。3.3 在OSPF里做路由过滤OSPF里用前缀列表做过滤通常是在ABR或者ASBR上。比如在ABR上过滤区域间的路由ip ip-prefix ospf-filter index 10 deny 172.16.0.0 16 less-equal 32 ip ip-prefix ospf-filter index 20 permit 0.0.0.0 0 less-equal 32 ospf 1 area 0 filter ip-prefix ospf-filter import这里我用了先拒绝、后放行的写法。第一条规则拒绝 172.16.0.0/16 及其所有子网第二条规则放行其余所有路由。这种写法在需要排除少数、放行多数的场景里很常见。注意OSPF的filter命令是在area视图下配置的import方向表示过滤进入这个区域的路由export方向表示过滤从这个区域发布出去的路由。具体用哪个方向取决于你的需求。3.4 配置检查与验证命令配完之后怎么确认生效了几个常用命令display ip ip-prefix test-prefix这条命令查看前缀列表的内容包括序号、匹配条件、已匹配的计数。计数这个信息很有用如果某条规则的计数一直是0说明没有路由匹配上可能是规则写错了。display route-policy bgp-filter查看路由策略的配置和匹配计数。display bgp routing-table peer 10.0.0.2 received-routes查看从BGP邻居接收到的路由确认过滤是否生效。display ospf routing查看OSPF路由表确认过滤后的路由情况。我习惯在配完之后用display ip ip-prefix看一眼计数如果计数不对再回头检查规则。这个习惯帮我省了很多排查时间。4. 完整实验过程记录4.1 实验拓扑与目标实验拓扑很简单两台路由器直连R1和R2之间跑BGP。R1上配置若干条静态路由通过BGP发布给R2。R2上用前缀列表做入方向过滤只接收特定的路由。具体目标R1发布 10.1.0.0/16、10.1.1.0/24、10.1.1.1/32、10.2.0.0/16、10.2.1.0/24 这五条路由。R2只接收 10.1.0.0/16 到 /24 范围内的路由10.2.0.0/16 及其子网全部拒绝。拓扑用eNSP搭建R1和R2用GE0/0/0直连网段 192.168.12.0/24。R1的接口地址 192.168.12.1R2的接口地址 192.168.12.2。4.2 R1的配置先配接口和BGPsysname R1 interface GigabitEthernet0/0/0 ip address 192.168.12.1 255.255.255.0 bgp 100 peer 192.168.12.2 as-number 200 ipv4-family unicast peer 192.168.12.2 enable network 10.1.0.0 255.255.0.0 network 10.1.1.0 255.255.255.0 network 10.1.1.1 255.255.255.255 network 10.2.0.0 255.255.0.0 network 10.2.1.0 255.255.255.0这里有个细节BGP用network命令发布路由的时候对应的路由必须在IP路由表里存在。所以我需要先在R1上配静态路由指向这些网段。为了简化我用黑洞路由ip route-static 10.1.0.0 255.255.0.0 NULL0 ip route-static 10.1.1.0 255.255.255.0 NULL0 ip route-static 10.1.1.1 255.255.255.255 NULL0 ip route-static 10.2.0.0 255.255.0.0 NULL0 ip route-static 10.2.1.0 255.255.255.0 NULL0配完之后用display bgp routing-table确认五条路由都发布出去了。4.3 R2的过滤配置R2上先配接口和BGP邻居sysname R2 interface GigabitEthernet0/0/0 ip address 192.168.12.2 255.255.255.0 bgp 200 peer 192.168.12.1 as-number 100 ipv4-family unicast peer 192.168.12.1 enable然后配前缀列表和路由策略ip ip-prefix bgp-in index 10 permit 10.1.0.0 16 less-equal 24 ip ip-prefix bgp-in index 20 deny 0.0.0.0 0 less-equal 32 route-policy bgp-filter permit node 10 if-match ip-prefix bgp-in bgp 200 ipv4-family unicast peer 192.168.12.1 route-policy bgp-filter import这里我用了route-policy来调用前缀列表。也可以直接用peer 192.168.12.1 ip-prefix bgp-in import效果一样。用route-policy的好处是后续如果要加其他匹配条件直接在这个策略里加就行。4.4 验证过滤效果配完之后在R2上查看BGP路由表display bgp routing-table预期结果是10.1.0.0/16、10.1.1.0/24、10.1.1.1/32 这三条路由应该被接收10.2.0.0/16 和 10.2.1.0/24 应该被拒绝。实际验证下来结果符合预期。10.1.0.0/16 的掩码长度是16在16到24范围内匹配第一条规则放行。10.1.1.0/24 的掩码长度是24也在范围内放行。10.1.1.1/32 的掩码长度是32不在16到24范围内第一条规则匹配不上继续查第二条规则第二条规则匹配所有路由动作是deny所以被拒绝。等等这里有个问题。我原本的意图是只接收 10.1.0.0/16 到 /24 的路由10.1.1.1/32 应该被拒绝。但实际结果是它被拒绝了这符合预期。但如果你希望 /32 的主机路由也被接收就需要把 less-equal 改成 32。再看 10.2.0.0/16网络地址是 10.2.0.0第一条规则匹配的是 10.1.0.0网络地址不匹配继续查第二条规则被拒绝。10.2.1.0/24 同理被拒绝。用display ip ip-prefix bgp-in查看匹配计数可以看到第一条规则匹配了3次10.1.0.0/16、10.1.1.0/24、10.1.1.1/32 都匹配了第一条规则但 10.1.1.1/32 因为掩码长度不在范围内实际上没有匹配上第一条规则而是匹配了第二条规则被拒绝。这里计数显示的是匹配次数不是放行次数要注意区分。4.5 调整规则验证不同效果为了验证 greater-equal 和 less-equal 的组合效果我改了一下规则ip ip-prefix bgp-in index 10 permit 10.1.0.0 16 greater-equal 24 less-equal 32这样改完之后10.1.0.0/16 的掩码长度是16不在24到32范围内匹配不上第一条规则被第二条规则拒绝。10.1.1.0/24 的掩码长度是24在范围内放行。10.1.1.1/32 的掩码长度是32在范围内放行。这个实验说明了一个重要点前缀列表的掩码长度范围是精确控制的greater-equal 和 less-equal 的边界值都包含在内。写规则的时候一定要想清楚边界值要不要包含。5. 常见问题与排查技巧5.1 规则写了但不生效这是最常见的问题。原因通常有几个一是前缀列表没被正确调用比如route-policy里忘了写if-match或者BGP邻居上忘了应用route-policy。二是匹配方向搞反了import和export弄混了。三是序号顺序问题前面的规则把后面的规则挡住了。排查方法先用display ip ip-prefix看计数如果计数是0说明没有路由匹配上检查规则本身。如果计数不为0但路由还是被过滤了检查route-policy的node顺序和动作。如果route-policy也没问题检查BGP邻居上是否应用了正确的策略。5.2 掩码长度匹配不上这个问题的根源通常是对 greater-equal 和 less-equal 的理解有偏差。记住一个原则前面写的掩码长度是基准greater-equal 和 less-equal 是在这个基准上做范围扩展。比如permit 10.1.0.0 16 less-equal 24意思是网络地址匹配 10.1.0.0/16掩码长度在16到24之间。如果你写permit 10.1.0.0 24 less-equal 16这是非法的因为16小于24。设备会报错Error: The less-equal value must be greater than or equal to the mask length.还有一个容易忽略的点如果你只写网络地址不写掩码长度比如permit 10.1.0.0它匹配的是所有以 10.1.0.0 开头的路由掩码长度不限。这个用法要慎用容易误放行。5.3 隐式拒绝导致的意外过滤前面提过前缀列表末尾有隐式deny。很多人写规则的时候只写了permit忘了考虑没匹配上的路由会被拒绝。比如你写permit 10.1.0.0 16结果来了一条 10.1.0.0/24 的路由匹配不上被隐式拒绝。如果你本意是放行所有 10.1.0.0 开头的路由那就应该写permit 10.1.0.0 16 less-equal 32。我的习惯是在写完permit规则后如果需求是放行多数、拒绝少数就在末尾加一条permit 0.0.0.0 0 less-equal 32放行所有。如果需求是拒绝多数、放行少数就不加让隐式deny生效。5.4 序号冲突和插入规则默认序号是10、20、30这样递增的。如果你后来想在10和20之间插一条可以手动指定序号15。但要注意如果15已经被占用了会报错。所以规划序号的时候最好留出间隔比如用10、20、30中间留空位。如果要删除某条规则用undo ip ip-prefix test-prefix index 10。删除后其他规则的序号不变。如果要修改某条规则也是先删再加。5.5 常见问题速查表问题现象可能原因排查方法解决方法规则不生效未调用或调用错误检查route-policy和BGP邻居配置确认if-match和import/export方向路由被意外拒绝隐式deny生效查看前缀列表计数末尾加permit 0.0.0.0 0 less-equal 32掩码长度匹配不上greater/less-equal理解偏差检查规则中的掩码范围调整greater-equal和less-equal的值序号冲突手动指定序号重复查看已有规则序号重新规划序号留出间隔部分路由匹配不上网络地址不匹配对比路由网络地址和规则调整规则中的网络地址5.6 几个实操心得第一个心得配前缀列表的时候我习惯先写一条permit 0.0.0.0 0 less-equal 32放在最后然后再往上加具体的规则。这样做的目的是先保证默认放行然后再逐步收紧。如果反过来先写拒绝规则再写放行规则很容易因为隐式deny导致意外过滤。第二个心得前缀列表的命名要有意义。比如bgp-in-filter、ospf-out-filter一看就知道用在哪、什么方向。不要用test1、test2这种名字过两天自己都忘了是干嘛的。第三个心得配完之后一定要用display ip ip-prefix看计数。计数为0的规则要么是写错了要么是没路由匹配。这个习惯能帮你快速定位问题。第四个心得在BGP里做过滤的时候如果同时用了前缀列表和AS路径过滤要注意匹配顺序。route-policy里的if-match是与的关系所有条件都匹配才执行动作。如果只想用其中一个条件就不要写另一个。6. 进阶用法与场景扩展6.1 配合AS路径过滤做精细控制前缀列表单独用已经很强了但配合AS路径过滤能实现更精细的控制。比如你要拒绝来自某个AS的路由同时只接收特定网段ip ip-prefix bgp-in index 10 permit 10.1.0.0 16 less-equal 24 ip as-path-filter 1 deny _300_ ip as-path-filter 1 permit .* route-policy bgp-filter permit node 10 if-match ip-prefix bgp-in if-match as-path-filter 1这样配置之后只有同时满足网段在10.1.0.0/16到/24范围内和AS路径中不包含300的路由才会被接收。两个条件是与的关系。6.2 在路由引入时的过滤OSPF引入外部路由的时候也可以用前缀列表做过滤。比如只引入特定的静态路由ip ip-prefix import-filter index 10 permit 172.16.0.0 16 less-equal 24 ip ip-prefix import-filter index 20 deny 0.0.0.0 0 less-equal 32 ospf 1 import-route static route-policy import-filter这里route-policy的名字和前缀列表的名字可以一样也可以不一样。我习惯用不同的名字避免混淆。6.3 前缀列表的匹配效率前缀列表的匹配效率比ACL高因为它是基于树形结构存储的查找速度快。但在规则数量很多的时候还是要注意优化。我的经验是把最常匹配的规则放在前面减少匹配次数。比如你有一条规则匹配了90%的路由就把它放在序号10的位置。另外前缀列表的规则数量不宜过多一般建议控制在几十条以内。如果规则太多考虑用社区属性或者其他的过滤方式替代。6.4 和其他过滤工具的对比工具匹配维度适用场景优点缺点ACL数据包地址接口过滤、NAT简单直观不能匹配掩码长度前缀列表路由前缀掩码路由过滤精确匹配掩码不能匹配数据包AS路径过滤AS路径BGP路由过滤灵活匹配AS只适用于BGP社区属性过滤社区属性BGP路由过滤可标记路由需要提前规划选择哪个工具取决于你的具体需求。如果只是过滤数据包用ACL。如果是过滤路由且需要精确控制掩码用前缀列表。如果是BGP场景且需要按AS过滤用AS路径过滤。7. 我踩过的几个坑第一个坑有一次做BGP过滤我写了一条permit 10.1.0.0 16本意是放行 10.1.0.0/16 这条汇总路由。结果发现 10.1.1.0/24 这条明细路由也被放行了。我当时很纳闷后来才想明白10.1.1.0/24 的网络地址前16位和 10.1.0.0 是一样的掩码长度24虽然不等于16但前缀列表在匹配的时候网络地址部分匹配上了掩码长度不匹配按理说应该继续往下查。但问题是我后面没有其他规则了隐式deny应该拒绝它才对。为什么会被放行后来仔细查文档才发现我犯了一个低级错误我把permit 10.1.0.0 16写成了permit 10.1.0.0没写掩码长度。这样它匹配的是所有以 10.1.0.0 开头的路由掩码长度不限。所以 10.1.1.0/24 也被放行了。这个坑让我记住了写前缀列表一定要写掩码长度除非你确实想匹配所有掩码。第二个坑有一次在OSPF里做过滤我用了filter ip-prefix ospf-filter import结果发现过滤没生效。排查了半天发现是方向搞反了。import是过滤进入区域的路由export是过滤发布出去的路由。我的需求是过滤从区域0进入区域1的路由应该在区域1的视图下配import。但我配在了区域0的视图下方向反了。第三个坑有一次配前缀列表的时候我用了默认序号写了三条规则10、20、30。后来想在10和20之间插一条手动指定序号15。结果设备报错说序号15已经被占用了。我查了一下发现之前有一条规则用了序号15但我忘了。这个坑让我养成了习惯配前缀列表的时候先display ip ip-prefix看一下已有的序号再规划新的序号。第四个坑有一次做BGP过滤我用了route-policynode 10 的动作是permitif-match调用了前缀列表。结果发现所有路由都被拒绝了。排查后发现route-policy的node 10 里if-match没匹配上的路由会继续查下一个node如果没有下一个node默认是deny。而我以为route-policy的默认动作是permit。这个坑让我记住了route-policy的默认动作是deny不是permit。如果要放行没匹配上的路由需要在末尾加一个route-policy xxx permit node 100里面不写if-match表示匹配所有。这些坑踩下来我的体会是前缀列表本身不复杂但和route-policy、BGP、OSPF配合使用的时候细节很多。配完之后一定要验证用display命令看计数、看路由表确认过滤效果符合预期。不要想当然觉得配了就一定生效。最后分享一个小技巧如果你不确定前缀列表的匹配效果可以先在一个测试环境里验证用display ip ip-prefix看计数确认每条规则匹配了哪些路由。确认无误后再应用到生产环境。这个习惯能帮你避免很多生产事故。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑