CIDR 记法详解
CIDR 从何而来、前缀长度为何取代了网络类别,以及如何在路由表、防火墙规则和云控制台里读懂你会遇到的斜杠记法。
CIDR 之前:固定的类别
1993 年之前,IPv4 地址的大小由它的前几个比特决定。第一个字节以 0 开头表示 A 类、有 16,777,216 个地址;以 10 开头表示 B 类、有 65,536 个地址;以 110 开头表示 C 类、有 256 个地址。边界是硬性的,中间任何尺寸都申请不到。
| 类别 | 起始位 | 第一个字节 | 默认掩码 | 每个网络的地址数 |
|---|---|---|---|---|
| A | 0 | 1–126 | 255.0.0.0 | 16,777,216 |
| B | 10 | 128–191 | 255.255.0.0 | 65,536 |
| C | 110 | 192–223 | 255.255.255.0 | 256 |
| D | 1110 | 224–239 | — | 组播,不按网络划分尺寸 |
| E | 1111 | 240–255 | — | 保留作实验用途 |
两个问题交织在一起。第一是浪费:一个需要 2,000 个地址的组织不得不申请一个 B 类,然后空着 63,000 个不用。第二是路由表膨胀:每一个 A、B、C 类分配都会变成全局路由表里的一条独立条目,与它的大小无关。
CIDR 改变了什么
CIDR 去掉了固定边界,改用显式的前缀长度。一个需要 1,000 个地址的网络现在就是 /22 —— 1,024 个地址,浪费 4% 而不是 98%。由此带来两个结果,也正是这次变革的目的。
- 地址空间利用更高效。分配可以按需求定尺寸,而不必往上取到最近的类别,地址空间因此能用得久得多。
- 路由聚合。因为地址不再与类别边界绑定,一个持有 203.0.112.0/21 的运营商可以用一条路由通告它全部的八个 /24。正是聚合让全局路由表在 1990 年代保持可控,也是今天互联网仍能扩展的原因。
192.168.1.0/24 前缀长度 24 子网掩码 255.255.255.0 通配符掩码 0.0.0.255 反向写法 192.168.1.0 0.0.0.255 (Cisco ACL 语法)
不用数位也能读前缀
一旦记住最后一个字节的数列,就完全不必从头数位。比 /24 长的前缀只会涉及第四个字节,而掩码值遵循一个固定数列。
| 前缀 | 最后一个字节 | 该字节的二进制 | 块大小 | 可用主机 |
|---|---|---|---|---|
| /24 | 0 | 00000000 | 256 | 254 |
| /25 | 128 | 10000000 | 128 | 126 |
| /26 | 192 | 11000000 | 64 | 62 |
| /27 | 224 | 11100000 | 32 | 30 |
| /28 | 240 | 11110000 | 16 | 14 |
| /29 | 248 | 11111000 | 8 | 6 |
| /30 | 252 | 11111100 | 4 | 2 |
| /31 | 254 | 11111110 | 2 | 2(RFC 3021) |
| /32 | 255 | 11111111 | 1 | 1 |
规律是每走一步网络部分就多一位,掩码字节因此获得下一个位权:先 128,再 64,再 32,依此类推。把 /27 读成 224,靠的是认出这个数列,而不是做算术。
实践中的最长前缀匹配
前缀长度必须是连续的一段比特,原因在于路由器靠"匹配到的最长前缀"来消除歧义。设想一台路由器上有三条路由:
10.0.0.0/8 via 192.0.2.1 10.1.0.0/16 via 192.0.2.2 10.1.2.0/24 via 192.0.2.3 目的地址 10.1.2.55 与三条都匹配。 最长匹配胜出 -> 10.1.2.0/24 via 192.0.2.3
这正是能从一条宽泛的汇总路由里挖出一个特例的原因。/8 承载大部分流量;/24 为某一个子网提供更精确的路径,而不必把 /8 拆散。如果掩码可以是不连续的,就没有哪个单一数字能表达"精确程度",整个算法也会失效。
哪些地方会遇到 CIDR 记法
- 路由表。每一条路由都是一个前缀加一个下一跳。默认路由是 0.0.0.0/0,出现在每一台路由器的表中。
- 防火墙规则。源与目的地址范围都写成前缀,而前缀的选择直接决定了会匹配到多少流量。
- 云网络。VPC 与 VNet 的地址范围都用 CIDR 块指定,子网从其中划分 —— 也就是说,前缀算术直接决定你的子网到底装不装得下。
- 厂商配置。接口地址、OSPF network 语句与路由汇总都用前缀,而 Cisco ACL 用的是同一信息的通配符写法。
- IPv6。同一套记法适用于 /0 到 /128,而 /64 —— 标准子网尺寸 —— 实在太常见,以至于 IPv6 划分子网通常问的是"一个分配里能装多少个 /64",而不是掩码问题。
常见错误
- 写了一个不是网络地址的地址。192.168.1.5/24 记法上合法,但网络是 192.168.1.0/24。多数系统会接受并归一化前一种写法,但在文档里这样写会误导人。
- 以为数字越大网络越大。/28 比 /24 小。这个数字数的是网络位,位越多主机地址越少。
- 把前缀和掩码搞混。/24 不是"24 台主机" —— 它是 24 个网络位和 254 个可用主机。匆匆阅读时这两个数字很容易看串。
- 使用不连续的掩码。255.255.0.255 看起来像模像样,但它不合法,也无法表示为前缀长度,所以没有任何路由器会接受它。
前缀范围汇总
| 范围 | 典型用途 | 说明 |
|---|---|---|
| /0 | 默认路由 | 匹配所有地址;路由表中的最后选择 |
| /1 – /7 | 历史 A 类聚合 | 除超大型路由表外很少见到 |
| /8 – /15 | 运营商与云厂商分配 | 一个 /8 有 16,777,216 个地址 |
| /12 | RFC 1918 私有块 | 172.16.0.0/12 就是该私有范围 |
| /16 – /22 | 企业与园区 | 一个 /16 含 256 个 /24 可供细分 |
| /23 – /24 | 站点与 VLAN 网络 | 一个 /24 是标准 LAN 尺寸,254 台主机 |
| /25 – /29 | 部门网段 | 把一个 /24 拆成更小的广播域 |
| /30 | 广域网链路(传统) | 四个地址中两个可用主机 |
| /31 | 广域网链路(RFC 3021) | 两个地址,零浪费 |
| /32 | 主机路由 | 环回地址与指向单一目的地的静态路由 |
对 IPv6 来说整张表平移 96 位:/64 是标准 LAN 尺寸,/128 是单个主机,/127 相当于 IPv4 点对点链路上的 /31。
常见问题
CIDR 是什么的缩写,什么时候出现的?
Classless Inter-Domain Routing,无类域间路由。它由 1993 年的 RFC 1518 与 RFC 1519 引入,用来取代固定的 A、B、C 类边界 —— 那些边界对于不断扩张的互联网来说过于粗糙。CIDR 引入了前缀长度,让从 /32 单主机到 /0 默认路由的任意尺寸网络都成为可能。
前缀长度和子网掩码有什么区别?
它们用不同的记法表达完全相同的信息。前缀长度数的是网络位数,所以 /24 表示 24 个 1。子网掩码把这些比特用点分十进制写出来,所以 /24 是 255.255.255.0。每个前缀恰好对应一个合法掩码,每个合法掩码也恰好映射回一个前缀。
有类寻址的问题在哪里?
A 类给 1,600 万个地址,B 类给 65,536 个,C 类给 256 个,中间什么都没有。一个需要 1,000 个地址的组织只能申请 B 类,白白浪费 98%;而每一次这样的分配都会给全局路由表增加一条路由。到 1990 年代初,路由表的增长速度已经超出路由器能承受的范围,地址空间也被消耗得远比必要的快。
斜杠记法在实践中长什么样?
它跟在地址后面,例如 192.168.1.0/24 或 2001:db8::/32;当你只关心前缀时它也可以单独出现,例如路由表条目或防火墙规则里。云控制台通常把它作为一个独立字段,标注为 prefix 或 CIDR。
前缀的最长与最短分别是多少?
IPv4 的范围是 /0 到 /32。/0 匹配所有地址,用作默认路由。/32 精确匹配一个地址,用于主机路由与环回接口。IPv6 的范围是 /0 到 /128,因为 IPv6 地址是 128 位。
子网掩码可以是不连续的吗?
不可以。合法掩码是一串 1 后面跟一串 0,中间不能夹杂。255.255.0.255 不是合法掩码,因为 1 之间出现了 0。这项限制存在的原因是网络与主机的划分必须能表示为单一的前缀长度,而正是这一点让最长前缀匹配路由成为可能。
什么是最长前缀匹配?
当路由器有多条可能匹配同一目的地的路由时,它会选择前缀最长的那条 —— 也就是最精确的匹配。/32 主机路由胜过 /24 子网路由,/24 胜过 /16 汇总,/16 又胜过 /0 默认路由。这正是能从一条大范围聚合中挖出一个小特例、而不打扰其余部分的原因。