
我最早对 CIDR 产生敬畏心是在一次给分公司做路由汇总的深夜。公司刚接入了一个新办公区路由表里本来静静躺着几条 /24 的明细路由。我贪省事想着合并成大网段能少几行配置就在出口设备上写了一条更大的汇总路由。结果第二天工单群就炸了——好几个本不该被覆盖的网段全跑到这条新链路上来。当时带我的导师只扔过来一句话你先把无分类编址 CIDR 的边界画清楚再动手。后来我才明白那晚栽的不是配置是对“CIDR”的理解。这篇继续我的计算机网络笔记第十九篇专门把 CIDR 从出生背景到计算原理、再到路由聚合和真实排错现场完整捋一遍。如果你也经常被“/23 到底有多大”“为什么 10.10.9.0/23 不能直接当一个网段”“路由器既然有两条匹配路由凭什么走最长前缀这条”这类问题绕晕这篇文章应该能帮你把线头一根根理开。1. 分类编址为什么撑不住了CIDR 诞生前的困局1.1 固定分界带来的浪费现在的年轻人可能很难想象IPv4 地址当初是按“类”来分配的。32 位地址被切成三类固定长度的网络号加主机号A 类网络号 8 位每个网络能容纳约 1677 万台主机B 类网络号 16 位每个网络能容纳 65534 台C 类网络号 24 位每个网络只能容纳 254 台。听起来好像还凑合问题出在分配粒度太粗。一个五百人的公司按真实需求可能只需要三百个 IP 地址这在分类编址时代特别尴尬申请 C 类不够用申请 B 类又严重浪费。很多单位实际只有几百台机器却抱着一整个 B 类地址段剩下六万多个地址从此“消失”在路由表里没人能够再用。反过来如果一家公司规模稍大需要三个 C 类网段传统路由协议又必须逐条通告这三个 C 类每一条都独立占一路由项地址虽然没有浪费多少路由表却被硬生生撑大了三倍。这个浪费有多夸张当时业界做过统计按分类方式继续分配下去B 类地址会在几年内被分光。而 C 类虽然还有余量但越来越多的 C 类被零散分配出去之后骨干路由器的路由条目开始爆炸式增长。地址耗尽和路由表膨胀两个问题同时逼近靠原来的“分整类”思路已经彻底走不通。1.2 路由表爆炸比地址耗尽更先到来的危机上世纪九十年代初骨干网上的路由条目增长速度快到吓人。每多分配一批 C 类地址核心路由器就要多背一条路由而互联网规模还在指数级增长。路由器内存不是无限的CPU 处理路由查找的耗时也在快速上升。可以说即便 IPv4 地址没有立刻耗尽这种“按类通告”的方式也会先把路由器内存撑爆。CIDR 的思路其实很朴素不再管一个 IP 原本属于 A 类还是 B 类直接用“IP 地址 斜杠 前缀长度”来描述网络。前缀长度告诉你这串地址里前多少位是网络部分剩下的是主机部分。网络规模需要多大你就用多长前缀既不按整类硬切也不浪费多余地址。这套机制在九十年代初的 RFC 里被正式定下来后来逐步成为互联网地址分配和路由通告的基本方式。如果你觉得抽象拿买菜类比就好懂了分类编址像是只能整头猪一起买不管你要两斤还是五斤都至少得扛走一头CIDR 则是按需切割要多少切多少。更妙的是CIDR 还允许把几块“散装”地址拼成一大块向外发布这就是后面要讲的路由聚合。所以也有人把 CIDR 翻译成“无类域间路由”核心就是取消了类与类之间的硬边界。提示直到今天互联网上大部分路由依然延续了 CIDR 的“前缀 掩码”模型。IPv6 也沿用了这套逻辑只是地址位长从 32 位变成了 128 位。2. 无类编址的核心网络前缀、主机号与斜杠记法2.1 一个算例彻底搞懂地址范围CIDR 的正确读法很简单IP 地址后面加斜杠斜杠后面跟一个数字数字表示网络前缀长度。比如 10.10.10.0/23意思是从 32 位二进制地址的高位开始数前 23 位是网络部分后 9 位全部是主机部分。前缀长度等于多少相当于网络掩码里有多少个连续的 1。所以 /23 的子网掩码展开就是 255.255.254.0。关键计算来了。主机部分是 9 位能组合出 2 的 9 次方也就是 512 个地址。这就是这个地址块的大小。那这个块到底从哪到哪从 10.10.10.0 开始主机位从全 0 到全 1所以地址范围是 10.10.10.0 到 10.10.11.255。很多人第一次算到这里会愣住怎么还跨到 10.10.11 段去了原因在于 /23 已经跨越了第三个八位组的边界。前 23 位里第三个八位组只被占了前 7 位最低的 1 位仍然属于主机部分。于是第三段的最后一个二进制位可以自由变化导致这个地址块既包含 10.10.10.x也包含 10.10.11.x。换句话说/23 是把两个 C 类规模的小网段拼在一起的一个“超网”。再看 /26 的例子。192.168.1.64/26前缀长度 26主机位 6 位地址块大小是 64。范围从 192.168.1.64 到 192.168.1.127。网络地址是 192.168.1.64广播地址是 192.168.1.127中间能分配给终端用的就是 192.168.1.65 到 192.168.1.126一共 62 个可用地址。这个 /26 在云厂商的私有网络划分里非常常见一个小型业务子网用 /26 刚刚好。2.2 为什么网络地址和广播地址不能分配有朋友会问为什么计算可用主机数时总是要减 2因为一个地址块里有两个特殊地址主机位全 0 的那个是网络地址用来描述“这个网段本身”主机位全 1 的那个是广播地址用来给这个网段内所有主机发广播。这两个地址不能被分配给任何一台终端。用生活例子解释网络地址相当于一个小区的门牌号 0 号广播地址相当于小区大喇叭的频道而 1 号到 N 号才是可以住人的房间。你不可能把门牌号 0 号或广播频道分配给某户住人否则整个小区通信的基本规则就乱了。还有一个容易踩坑的边界对齐问题。CIDR 地址块不是随便给一个 IP 加个前缀就算数。地址块起始位置必须是“块大小整数倍”对齐的。比如 10.10.10.0/23 是合法网段因为它的网络地址经掩码一算还是 10.10.10.0。但你写 10.10.9.0/23 试试拿掩码 255.255.254.0 去与运算得到的结果是 10.10.8.0根本不等于 10.10.9.0。也就是说10.10.9.0/23 这个写法本身就在描述一个不存在的网段边界正确的写法应该是 10.10.8.0/23。这种“边界对齐”的意识非常关键尤其在做路由汇总和撰写防火墙地址对象的时候一旦写错你放通或阻塞的范围就会和你预想的不一致。3. 最长前缀匹配数据包在 CIDR 路由表里到底怎么走3.1 一个选择实验同一 IP 同时匹配多条路由时路由器转发数据包不是拿目标 IP 去和路由表里所有条目做“等于”判断而是做“包含”判断。一个目标 IP 很可能同时落在好几条路由条目描述的范围内。这时选谁答案是谁描述的范围更小、更精确就选谁。这就是最长前缀匹配原则。举个例子。路由表里有三条路由100.100.0.0/16 下一跳是 10.0.0.1100.100.50.0/24 下一跳是 10.0.0.2还有一个默认路由 0.0.0.0/0 下一跳是 10.0.0.254。现在有一个数据包要去 100.100.50.6。你拿这个地址去匹配三条路由结果三条全都匹配上100.100.50.6 落在 100.100.0.0/16 的范围内因为 /16 覆盖了从 100.100.0.0 到 100.100.255.255 的整个区域。它也落在 100.100.50.0/24 的范围内因为 /24 精确覆盖了 100.100.50.0 到 100.100.50.255。默认路由 /0 更是命中一切目标。最终路由器会选 /24 这条。因为 /24 的前缀长度最长代表它给出的路径信息最具体。你可以脑补一个快递场景包裹上写得很清楚杭州西湖区文三路某号快递员先看到浙江省也匹配再看到杭州市也匹配最后看到具体街道直接按最细地址送不可能按“浙江省”去投递。3.2 管理距离不是第一优先容易被忽略的前置条件很多人配置网络时会有一个模糊印象静态路由优先级高所以静态路由一定优先。这个说法在“所有候选路由前缀长度相同”时才成立。如果一条 /16 的静态路由管理距离是 5而一条 /24 的动态路由管理距离是 200目标地址落在两者公共范围内实际转发的仍然是 /24 那条。原因很简单设备先比前缀长度前缀一样长的候选才会进入下一轮优先级比较。这在实际排错里特别重要。我见过有人排查“为什么流量没走静态路由”查了一下午最后发现根源是旁边自动学习到了一条更长的明细路由。行政上确实静态优先不假但技术上前缀更长的路由在比较环节就已经赢了。路由查找的顺序如果写成口诀就是先最长匹配再管理距离最后才比度量值。你配置策略路由时也要顺着这个逻辑推不要被“优先级”三个字带偏。提示默认路由 0.0.0.0/0 是前缀长度为 0 的特殊路由任何目标 IP 都能和它匹配但也是所有候选中最“不精确”的一个所以总是最后才被考虑。没有更优路由时它才出场兜底。4. 路由聚合用 CIDR 给路由表“瘦身”的实战操作4.1 聚合条件的数学本质连续、成块、起点对齐CIDR 在工程上最有价值的地方不是帮你省地址而是帮你把多条路由合并成一条。假设一个分支分部有 8 个 C 类网段172.16.0.0/24、172.16.1.0/24一直到 172.16.7.0/24。如果不做任何处理分部向上级通告 8 条路由上级路由表就多 8 条条目。如果分部出口设备上配置一条 172.16.0.0/21 的聚合路由上级只需学一条。那是不是任意几个网段都能硬并不是。能聚合的地址段必须满足三个条件第一地址范围连续第二数量必须是 2 的整数次幂第三起始地址必须落在聚合后大地址块的边界上。比如四个连续的 /24 可以并成 /22172.16.0.0/24、172.16.1.0/24、172.16.2.0/24、172.16.3.0/24合并结果就是 172.16.0.0/22。但如果分部只有 172.16.0.0/24 和 172.16.2.0/24 两个网段你能把这两个网段直接合并吗不能。因为 /23 这个块要么包含 0 和 1 两个 C 段要么包含 2 和 3 两个 C 段中间那一段不是你的。如果强制用 /22 汇总会把 1 和 3 两个不属于你的网段也包进去上线之后极可能踩到别人的网络。真实规划时我习惯先在纸质表格里列一遍网段起止确认连续性之后再算前缀。有时候少一个网段就得拆出一条单独的明细路由反而更安全。4.2 聚合之后的反直觉风险黑洞与环路聚合不是越高越好它有一个反直觉的风险聚合范围越大包含的“未知区域”也越大。假如你在核心交换机上配了 172.16.0.0/21 的汇总路由指向某个出口但实际网络中 172.16.5.0/24 根本不存在上层设备一旦收到目标是 172.16.5.x 的流量就会顺着聚合路由一股脑送到出口链路。设备到达出口后又发现没有更明细路由只能再次转回核心——造成路由环路。应对这种问题业界常用的方案是给聚合网段配一条指向 NULL0 的“黑洞路由”。比如华为风格设备上可以写ip route-static 172.16.0.0 255.255.252.0 NULL0这条路由的优先级通常要调高让它在路由表里“只兜底、不抢跑”。当真实子网的明细路由存在时流量走明细当目标是聚合范围内但不存在具体子网时流量被丢进黑洞不再回环。这个细节在很多教学文档里不会写但生产环境里几乎必配。聚合配置示例也顺手给你一份# 在分部出口设备上把 172.16.0.0/24 ~ 172.16.3.0/24 汇总成一条 /22 ip route-static 172.16.0.0 255.255.252.0 10.0.0.1不同厂商命令语法略有差异但思路是一致的聚合条目越靠近出口边界越好越靠近骨干越好同时别忘了黑洞兜底。5. 反向用法如何根据终端数量反推 CIDR 前缀5.1 三步反推法设备数到前缀长度正着算 CIDR 地址范围是基本功但日常网络规划更多是反向操作知道一个房间有多少台设备要反推出应该分配多大的子网。我的方法很固定一共三步。第一步把设备数量加上 2留出网络地址和广播地址的位置。比如办公区会规划出 60 台终端、2 台打印机、1 个网关、再加 2 个预留地址那我们按 65 个算加 2 得到 67。第二步找一个刚好大于等于 67 的 2 的整数次幂这里 67 对应的就是 128。第三步前缀长度等于 32 减去这个幂次对应的指数。128 是 2 的 7 次方所以前缀长度是 32 - 7 25也就是 /25。不过我一直不建议卡得刚刚好。生产环境的设备数预测永远会偏小今天 60 台下个月可能就变成 80 台。我通常会在第一步就把数量乘上 1.5 到 2 倍再算。还是上面那个场景按 100 台预留加 2 后向上取 128同样得到 /25。如果原来想给 /26 就有点紧了后面扩一次网段就要重新规划 VLAN代价远大于刚开始多给几个地址。下面这张表可以直接作为规划速查表需求场景最小推荐前缀地址块大小可用主机数点对点链路传统方案/3042极小型子网或主备设备/2986小型服务器区/281614小型终端区/273230常见业务子网/266462中大型办公区/25128126默认常见的 C 类规模/242562545.2 别把 /31 和 /32 用错场景很多网工一看到 /31 就头大因为按传统“减 2”的算法一个 /31 块大小是 2减 2 之后可用主机数是 0简直没法用。但 RFC 3021 规定了点对点链路可以特殊对待/31 不再保留网络地址和广播地址两个地址都能分配给链路两端。比如两个路由器之间做互联传统方案用 /30浪费一半地址如果两端设备都支持 /31就可以各配一个 IP一点也不浪费。要注意的是不是所有设备都完整支持 /31。一些老型号的防火墙、路由器交换芯片可能把 /31 里主机位全 1 的那个地址仍然当作广播来处理配置后一端通一端不通的现象并不少见。遇到这种情况别死磕 RFC 标准直接改回 /30 最省事。/32 则用于精确描述“单台主机”。它常用于指定某个需要单独放通或单独丢弃的公网 IP也常用于环回口地址和黑洞拦截。在 Linux 上你可以这么用# 把目标指向黑洞实现精准丢弃 ip route add blackhole 203.0.113.8/32一个 /32 不代表子网里有可用主机它代表的是一个独立 IP 的路由表现。把防火墙地址对象、安全组规则里那些“只允许某个公网出口访问”的权限写成 /32是再常见不过的操作。6. 排错现场CIDR 配置中最常见的翻车姿势6.1 子网掩码换算表与“看着像 /24 其实不是”的场景先给你一张平时最容易用到的换算表建议收藏CIDR子网掩码地址块大小可用主机数/20255.255.240.040964094/21255.255.248.020482046/22255.255.252.010241022/23255.255.254.0512510/24255.255.255.0256254/25255.255.255.128128126/26255.255.255.1926462/27255.255.255.2243230/28255.255.255.2401614/29255.255.255.24886/30255.255.255.25242有个高频翻车点是把 /22 当成了一个稍大点的“C 类网段”。其实 /22 包含 1024 个地址可用 1022 个。你在防火墙地址对象里写一条 10.10.0.0/22意味着你同时放通了原来规划的 10.10.0.0/24 到 10.10.3.0/24 四个网段。如果另外三个网段里有不想暴露的测试环境这就是安全事件了。6.2 防火墙地址对象和接口地址的 CIDR 写法坑某次排查一个跨办公区互访问题发现 VLAN 接口配置的是 192.168.1.1/24但下面终端自己配了 192.168.2.50 这类地址。从网关接口的角度看它所在的子网只认识 192.168.1.1 到 192.168.1.254 这些地址。终端发来的 ARP 请求询问“谁知道 192.168.1.1”网关应答后终端把数据发给网关但网关收到目标为 192.168.2.50 的报文按 /24 掩码判断这不在自己的直连网段内于是又把它当成外部流量路由表里又没有对应的明细路由自然就丢了。你抓包能看到 ARP 正常数据也确实到了网关但转发就是不成功。排查到最后发现根本不是链路问题而是接口地址的掩码范围压根没把终端覆盖进去。防火墙安全组里也常遇到地址对象写错的情况。比如把内网区域地址从 10.20.10.0/24 误写成 10.20.0.0/16安全策略的放通范围瞬间扩大 256 倍。这种问题不是网络不通而是“不该通的地方通了”比不通更隐蔽也更危险。再看看 CIDR 写法本身的低级错误。很多人手滑把 192.168.0.0/16 写成 192.168.0.0/16.0或者把地址写成 192.168.10.0/24 却漏了一位变成 192.168.10.0/23。后者在设备上不会报错但它把整个 192.168.11.x 也一起纳入策略范围了。配置之前先把地址按表格算一遍能省很多事。提示IPv6 同样使用 CIDR只是没有了广播地址概念所以“减 2”这一步在 IPv6 的普通子网里通常不适用。规划 IPv6 时用 /64、/48 这些前缀思路完全一致但别再把“网络地址 广播地址”的老观念直接搬过去。回到开头那次深夜割接。后来我把所有分支网段的边界在模拟器里画了一遍才发现问题出在自己没把“可聚合条件”和“明细路由优先级”想清楚。CIDR 难的不是公式而是脑子里有没有那根“边界对齐”的弦。我现在每个新项目的 IP 规划都会先在表格里把网段起止、掩码、下一跳列出来对照前缀长度再动手敲命令。建议你也先养成这个习惯能少熬好几个夜。