IPv4/IPv6地址分类、子网划分与组播机制详解
前几天帮一个朋友排查网络故障一台设备的接口IP掩码错写成了/25导致同一网段里一半设备能通、一半设备不通折腾了两个小时才定位到是子网划分算错。这种事在现网里太常见了尤其是现在IPv4、IPv6双栈在跑数据中心和园区网里大量业务又依赖组播地址很多人把地址分类、子网掩码、前缀长度、组播这几个概念混在一起一到排障就抓瞎。这篇文章想把这个知识空缺补上把IPv4地址分类、子网划分计算、IPv6地址结构、组播地址机制放到一条线上来聊。适合刚入行想搭网络知识框架的人也适合做运维的朋友遇到地址相关故障时回来翻一下。内容不贴具体厂商命令只讲通用原理和排查思路你拿任何设备都能对照着用。1. 为什么把IPv4、IPv6、组播、子网划分放进同一篇1.1 地址知识不是彼此孤立的知识点很多人学网络是分块学的今天背IPv4分类明天背IPv6压缩规则后天看组播。学的时候感觉都会真到了现场才发现完全连不起来。其实这几个概念是咬合在一起的。IPv4里你学会了子网掩码和借位到IPv6里换了个名字叫前缀长度底层逻辑完全一致。组播地址在IPv4里叫D类地址在IPv6里则是FF00::/8这个大块但组播的转发机制、成员管理方式、二层封装套路两个协议栈是高度相似的。最典型的是IPv6的邻居发现协议它用组播地址替代了IPv4里的ARP广播你没有组播的基本认知就很难理解为什么IPv6设备会加入那么多组播组。所以我一直建议学地址不要孤立地学要把单播、组播、广播、子网规划放成一张图来看。这篇就是按照这个思路来组织的。1.2 从“分门牌号”到“分区规划”如果把IP地址比作门牌号那IPv4时代是城市早期规划门牌号不够用大家开始想尽办法把一个门牌号拆成多个小隔间这就是子网划分的动机。到了IPv6时代门牌号数量大到离谱你反而不需要精打细算了重点变成了“怎么把整个城市按区、按街道、按楼栋优雅地分区”这就是前缀规划。我们常说的子网划分本质上是回答两个问题网络部分是哪些位、主机部分是哪些位。IPv4用点分十进制和子网掩码来表示IPv6用冒号十六进制和前缀长度来表示工具变了但“网络位主机位”的模型没有变。组播则是另一条独立的编址逻辑它不关心你在哪个网段它只关心“你愿不愿意加入某个订阅组”所以组播地址和单播地址在协议栈里是并行的两套体系。想清楚这层关系后面所有计算和排错就都有了坐标系。2. IPv4地址与子网划分从借位计算到VLSM规划2.1 先弄清分类地址和掩码的底层逻辑IPv4地址是32位二进制写成点分十进制就是为了给人看的。从编址历史上看最初把地址分成A、B、C、D、E五类A类前8位是网络位默认掩码/8B类前16位默认/16C类前24位默认/24D类是组播E类保留。这种分类在设计之初没问题但后来发现太浪费一个B类有6万多个可用地址小公司根本用不完于是有了无类域间路由CIDR。CIDR带来的最大变化是不再死板地按A、B、C类来分而是用“IP地址/前缀长度”来精确表示网段。比如192.168.1.0/24就表示前24位是网络位后8位是主机位。这里有个常见的认知误区有人以为/24就是“24个可用IP”其实/24的意思是网络位有24位主机位只剩8位所以有2的8次方共256个地址可用地址是254个。子网划分的核心操作叫“借位”。要把一个大网段切成多个小网段就从主机位里借出若干位作为子网位。每借一位子网数量翻一倍每个子网里的地址数量减一半。这个逻辑非常像切蛋糕一小刀切下去块数翻倍每块变小。所有子网计算题本质上都是二进制位数的加减法。2.2 手把手算一遍/24切4个子网用一个最经典的例子192.168.1.0/24需要切成4个大小一样的子网。第一步算需要借几位。2的2次方等于4所以要借2位。原来的主机位是8位借走2位后剩下6位新前缀是/26子网掩码从255.255.255.0变成255.255.255.192。第二步算每个子网里的地址数量。主机位剩下6位2的6次方是64也就是说每个子网有64个地址。第三步列出每个子网的范围子网网络地址可用地址范围广播地址第1个192.168.1.0/26192.168.1.1 - 192.168.1.62192.168.1.63第2个192.168.1.64/26192.168.1.65 - 192.168.1.126192.168.1.127第3个192.168.1.128/26192.168.1.129 - 192.168.1.190192.168.1.191第4个192.168.1.192/26192.168.1.193 - 192.168.1.254192.168.1.255这里有两个很多新手会踩的细节。第一每个子网的第一个地址是网络地址最后一个地址是广播地址都不能分配给设备使用所以每个子网的实际可用IP是62个。第二切分之后原来可用地址里有一部分变成了新子网的网络地址和广播地址整体可用地址会比不切分时少几个这是正常现象不是算错了。用同样的方法/27就是每个子网32个地址、可用30个/28就是16个地址、可用14个/30就是4个地址、可用2个。点对点链路常用/30或/31就是为了不浪费地址。2.3 变长子网掩码VLSM怎么分才不浪费等长子网划分简单但现实中各部门设备数量不同一刀切成等大的块会浪费地址。比如某公司从上游拿到一个192.168.10.0/24的网段A部门需要30个可用IPB部门需要10个可用IP如果统一切成4个/26子网每个子网62个可用IPA和B各用一个还空出很多剩下两个也难分配给其他小部门。这时应该用VLSM变长子网掩码先满足地址需求大的再分小的。A部门要30个可用IP找一个可用IP数大于等于30的最小网段。/27有30个可用IP正好够所以给A分192.168.10.0/27范围为0到31可用1到30。B部门要10个可用IP/28有14个可用IP满足接着A的31后面继续分给B分192.168.10.32/28范围为32到47可用33到46。剩下的192.168.10.48/28、192.168.10.64/26这些网段以后还能继续分配给其他需求。VLSM的精髓是“先大后小地址连续不重叠”。划分的时候建议先在纸上画一个地址块地图把每个子网的起始地址和范围标出来免得分着分着把自己绕进去。2.4 子网划分里的三个常见坑第一个坑是把“借位”和“块大小”搞混。有人看到/26就把可用IP当成26个其实需要计算的是32减26等于6个主机位2的6次方是64这才是子网内的地址总数。任何子网计算题先写二进制位再换十进制基本不会错。第二个坑是忽略了全0和全1子网。在CIDR时代全0子网和全1子网都是可以正常使用的和早期分类网络的做法不一样。所以192.168.1.0/26里的网络地址192.168.1.0是可以分配给子网本身的只是不能分配给具体设备。千万不要以为所有网段都必须从“1”开始分配。第三个坑是规划时不留余量。我见过很多小型网络直接把/24切成4个/26每个子网刚好满足当前设备数。结果半年后部门加了几台服务器挤不下了只能重新划网段中间还牵连ARP缓存、路由条目、DHCP配置。地址规划时至少留出一倍的余量比什么高级技术都实用。3. IPv6地址与IPv4最大的思维差异3.1 128位地址的写法与压缩规则IPv6地址是128位二进制理论数量是2的128次方。这个数大到你不需要像IPv4那样计算“一个子网能塞几台设备”因为IPv6里一个/64子网里的地址数量比整个IPv4地址空间乘以自身还要多出天文数字。IPv6用冒号分隔成8组每组4个十六进制位。完整写法长这样2001:0db8:0000:0000:0000:ff00:0042:8329。这么长的地址没法天天手写所以有两个压缩规则第一每组开头的0可以省略。2001:0db8可以写成2001:db80000可以写成00042可以写成42。第二连续的全0组可以用双冒号::压缩一次但一个地址里只能出现一次::。2001:0db8:0000:0000:0000:ff00:0042:8329可以压缩成2001:db8::ff00:42:8329。但2001:db8:0:0:1:0:0:1这种地址压缩时只能选一处用::写成2001:db8::1:0:0:1或2001:db8:0:0:1::1绝不能写成2001:db8::1::1因为双冒号出现了两次设备根本不知道每处压缩了多少组0。我实测发现很多配置错误都是双冒号乱用导致的。写IPv6地址时如果保险起见可以不压缩或者只压缩前导零系统配置里同样能识别。3.2 IPv6的地址类型图谱与/64习惯IPv6的地址类型比IPv4要清晰得多主要分这么几类环回地址是::1相当于IPv4的127.0.0.1。未指定地址是::相当于0.0.0.0。全局单播地址通常是2000::/3相当于IPv4的公网地址。链路本地地址是FE80::/10每个接口开机自动生成只在本链路有效不能跨路由器传递。唯一本地地址是FC00::/7相当于IPv4的私有地址内网使用不冲突。值得强调的是IPv6没有广播地址。IPv4里不管是255.255.255.255还是子网广播地址在IPv6里都由组播地址替代了比如链路本地所有节点的组播地址FF02::1就承担了类似广播的通信功能。IPv6的子网规划和IPv4有个非常大的区别不再以“够用”为标准而是直接一刀切用/64。为什么非要用/64因为SLAAC无状态地址自动配置要求接口标识是64位路由器下发的RA报文里的前缀必须配合64位的接口标识才能生成完整地址。另外很多网络功能比如重复地址检测、隐私扩展临时地址都是围绕/64设计的。你用/64往上数/56就是一个网段包含256个/64子网/48就是65536个/64子网这才是IPv6规划里真正需要算的东西。3.3 IPv6手动配置与SLAAC实测记录在Linux主机上手动配置IPv6地址命令如下ip addr add 2001:db8:1:10::100/64 dev eth0 ip link set eth0 up ip -6 route add default via fe80::1 dev eth0这里有个和IPv4非常不同的细节IPv6的默认路由下一跳通常是链路本地地址而不是全局单播地址。你写ip -6 route时网关写的是fe80开头的地址这样即使全局前缀变了链路内的路由也能正常工作。所以排查IPv6路由时别看到fe80::1就以为地址有问题它作为网关很常见。Windows下配置类似netsh interface ipv6 add address 以太网 2001:db8:1:10::100/64 netsh interface ipv6 add route ::/0 以太网 2001:db8:1:10::1查看命令也很简单Linux下用ip -6 addr showWindows下用ipconfig /all。SLAAC的流程是这样的路由器周期性地向链路内所有节点组播FF02::1发送RA报文RA里带着前缀和其他配置参数。主机收到RA后把前缀和本地生成的接口标识拼接成自己的IPv6地址。接口标识可以是基于MAC的EUI-64格式也可以是为了保护隐私而随机生成的临时地址。现在主流操作系统默认都用随机临时地址出站你在抓包时看到的源地址经常变这不是故障是隐私扩展在工作。3.4 IPv4思维迁移到IPv6时的适配点把IPv4里的旧习惯带到IPv6里是最容易出问题的。最典型的是掩码换算。在IPv4里你要习惯性算“可用主机数2的N次方减2”到IPv6里这个公式基本用不上因为一个/64子网里的地址足够你随便挥霍一台设备就算配几十个地址也毫无压力。另一个点是邻居发现机制。IPv4用ARP广播问“谁是192.168.1.1请把你的MAC告诉我”IPv6用邻居发现协议把询问发给特定组播组也就是solicited-node组播地址而不是全网广播。这个机制既有组播的“订阅”特性又不会打扰无关设备性能和安全都比ARP好。还有一点IPv4时代不少人靠NAT做“端口映射”来访问内网服务IPv6里没有NAT这样的惯例每个设备都有公网地址所以地址规划必须严谨防火墙策略也要重新梳理。你可以用唯一本地地址做内部管理用全局单播地址做业务出口两者的区分本身就承载了原来NAT所要承担的隔离职责。4. 组播地址机制一对多通信的资源节约方案4.1 单播、广播、组播三种模式的本质区别要理解组播先得对比三种通信模式。单播是一对一私聊源和目的都只有一个比如你访问一个网站服务器给你单独发一份数据。广播是一对所有源发一份数据所有人都要去听比如IPv4里的ARP和DHCP在早期就依赖广播但广播会把数据送到很多根本不需要的设备那里浪费严重。组播是一对多订阅源只发一份数据网络设备只在“有人订阅”的链路上复制转发既不是所有人都收也不是只发给一个人。用生活场景类比单播是点对点发私信广播是广场大喇叭组播是订阅型邮件列表。你不订阅就不会收到邮件订阅了即使源地址远在天边也能通过分发网络送到你手上。这个特性让组播成为流媒体直播、股市行情分发、路由协议邻居发现这些场景的首选。比如OSPF路由器之间建立邻居时需要向所有OSPF路由器发Hello报文如果用单播就得知道每个邻居的地址如果用广播就会打扰网段里所有设备组播刚刚好。4.2 IPv4组播地址细解IPv4组播地址就是D类地址范围224.0.0.0到239.255.255.255用CIDR写就是224.0.0.0/4。实际使用中这个范围并不是铁板一块可以分成几块来看。224.0.0.0/24这一段叫本地网络控制块TTL固定为1路由器不会转发只在直连网段内有效。这里有一批大家必须记住的常识地址组播地址用途224.0.0.1本网段所有支持组播的主机224.0.0.2本网段所有路由器224.0.0.5所有OSPF路由器224.0.0.6OSPF指定路由器DR224.0.0.9RIP v2路由器224.0.0.10EIGRP路由器232.0.0.0/8是源特定组播的地址段239.0.0.0/8是私有组播地址段类似IPv4的私有单播地址企业内部随便用公网不会路由。组播地址本身只是“组编号”它不关心接收者在哪个网段。源主机只要往这个地址发数据沿途路由器会根据组成员关系决定是否转发。4.3 加入组的链路和转发链路IGMP、PIM、IGMP snooping组播要能工作需要完成两件事接收者表达愿意接收、网络设备知道往哪转发。第一件靠IGMP协议。主机加入某个组时发IGMP Membership Report告诉本网段的路由器“我想收这个组”。路由器周期性地发IGMP Query组成员收到后回报告以确认还活着。IGMP有三个版本v2支持离开组快速报告v3支持指定组播源现代网络基本都跑v3。第二件靠组播路由协议。路由器之间要建立分发树常用的是PIM协议。PIM不关心单播路由协议类型直接借用单播路由表做RPF检查也就是反向路径转发检查一个组播包从源方向接口进来才对如果从别的接口进来就丢弃这样能有效防止环路。PIM稀疏模式里还有RP的概念所有接收者要先向RP汇聚再由源向RP分发整个树建立起来之后数据才会沿着树流动。二层交换机上还有个关键机制叫IGMP snooping。交换机通过监听IGMP报文学习到某个组播组的流量该从哪些端口转发而不是像传统交换机没见过组播时那样当广播泛洪。很多组播不通的问题查到最后都是交换机没开IGMP snooping或者VLAN里没有IGMP查询器导致组播帧被泛洪到所有端口或者根本不转发。4.4 IPv6组播地址结构解析IPv6组播地址统一以FF开头用CIDR表示就是FF00::/8。它的内部结构比IPv4复杂前8位固定是11111111接着4位是Flags标志位再4位是Scope范围字段剩下的112位是组标识。Flags里最重要的是T位T等于0表示永久分配的知名组播地址T等于1表示临时的动态组播地址。Scope字段决定了这个组播组的活动范围1表示接口本地2表示链路本地5表示站点本地8表示组织本地E表示全局范围。看到FF02开头的地址就知道它只在链路本地有效看到FF0E开头就知道它能跨整个组织甚至全球路由。IPv6里有很多固定组播组必须背下来组播地址用途FF02::1链路本地所有节点FF02::2链路本地所有路由器FF02::5所有OSPFv3路由器FF02::9所有RIPng路由器FF02::A所有EIGRP IPv6路由器FF02::1:FFxx:xxxxSolicited-node组播地址solicited-node组播地址是IPv6邻居发现的核心。每个单播地址都会对应生成一个solicited-node组播地址生成方法是取单播地址的低24位拼接到前缀FF02::1:FF00:0/104后面。比如你的IPv6地址是2001:db8:1:10::100它的solicited-node地址就是FF02::1:FF00:100。当设备需要解析邻居的MAC地址时它发的是邻居请求NS目标就是对方的solicited-node组播地址这样就只有目标设备的网卡会响应比IPv4的ARP广播高效得多。这也解释了为什么看Linux系统的组播成员列表时总能看到一堆FF02::1:FF开头的地址是正常现象。4.5 组播地址的实操验证在Linux主机上查看自己加入了哪些组播组用ip maddr show手动加入一个组用ip maddr add 239.0.0.10 dev eth0。加入之后抓包在接口上执行tcpdump -i eth0 igmp就能看到主机发出去的IGMP Membership Report报文。想验证IPv6的组播通信也比较直接ping6 FF02::1%eth0能测试链路内组播基础的连通性但要注意带上%和网卡名不然系统不知道往哪个接口发。不同的网卡名要带上各自的作用域ID。实际业务里的组播排错通常从两端同时进行。接收端看有没有发出IGMP report抓包最直观接入交换机看IGMP snooping表项是否建立三层设备看PIM邻居有没有起来、组播路由表里有没有对应的(*, G)或(S, G)条目。逐层排查比瞎猜快得多。5. 地址与子网场景下的问题排查速查5.1 子网掩码导致的“能通网关却跨不了网段”这种故障非常典型PC的IP是192.168.1.100网关是192.168.1.1掩码被配成了255.255.255.128也就是/25。PC判断自己去192.168.1.1是否在同一个网段时按照自己的/25来算发现网关在自己网段内所以能ping通网关。但192.168.1.130这台PC如果也在同一VLAN里它按照/25计算认为自己属于另一个网段你从第一台PC去ping它数据包会发给网关可网关上的对应VLAN接口如果配的是/24又会认为还在直接网段内于是数据包在网关和终端之间反复横跳表现为时通时不通。排查思路很清晰先看两端网卡的实际掩码是否一致再对比网关接口的掩码。局域网里所有设备同一广播域的掩码必须一致这是铁律。别一上来就怀疑是不是防火墙拦截了先把基础三层参数对齐。5.2 IPv6配置后不通的排查顺序IPv6测试最常见的现象是ip addr show显示有地址但ping外网不通。排查顺序我一般这样走先ping自己的链路本地地址确认协议栈本身没问题。再ping网关的链路本地地址注意带接口名比如ping6 fe80::1%eth0这一步能确认二层到网关是通的。接着看路由表里有没有默认路由没有就手动添加或者检查RA报文有没有被防火墙挡掉。最后看全局单播地址本身的作用域和前缀是否和上游分配的一致。有一个细节经常被忽略IPv6默认路由的下一跳通常是fe80::开头的链路本地地址这条路由不会显示在常规的路由命令里要用ip -6 route show来查。Windows下用route print -6。如果主机上只有临时地址在变出站流量用临时地址也是正常的别误判为故障。5.3 组播收不到流的检查路径组播不通的排查有个固定套路从接收端往源端一步步推。第一步查终端终端有没有加入组播组抓包看有没有发出IGMP report或者用ip maddr show看组成员列表。第二步查交换机IGMP snooping是否开启查询器是否选举出来对应VLAN的组播表项有没有建立。第三步查三层PIM邻居是否正常有没有RP组播路由表里有没有对应的条目RPF检查是不是把数据包丢了。第四步查防火墙中间链路的防火墙设备有没有放行组播地址段和IGMP/PIM协议。最容易踩的坑是两个一个是交换机没开IGMP snooping组播包在二层被泛洪多播源和接收端之间隔了老远接收端性能被拖垮但流依然不完整另一个是三层设备的单播路由和组播路由不一致RPF检查把合法流量丢光了。遇到组播问题先看RPF能省下大量时间。5.4 我在反复踩坑后留下的几条个人笔记第一IPv4子网规划时至少留一倍余量。地址空着不用没有任何代价但一旦不够用整个网络要重划牵连DHCP、VLAN、防火墙策略代价极大。第二IPv6规划的核心是算/56、/48里能分出多少个/64这类似IPv4里算一个/24能切成几个/27但方向正好相反。IPv4是往小了切IPv6是给你一大块让你从容地按区域、按业务、按环境分层。常见做法是前48位给站点前缀紧接着16位做子网也就是接入网段一个/64的划分方式这样最多能规划出6万多个子网段。第三组播排错一定要从接收端往回查。很多人习惯先看源端但源端通常没问题问题多半出在二层接入和PIM邻居上。抓包是组播排查最好的朋友IGMP和PIM报文都不加密一条tcpdump能告诉你的信息比设备日志还多。第四不要把所有IPv4的经验硬搬到IPv6。IPv6没有广播、默认路由下一跳习惯写链路本地地址、邻居发现依赖组播这些差异做项目前一定要先适配。我见过不止一个人把IPv4的网关地址习惯代到IPv6里把默认路由写成了全局单播地址结果路由配置了半天不生效换成fe80开头的地址立刻通了。这些坑如果提前知道能省掉无数个熬夜排障的晚上。