为什么组播需要单独映射
以太网帧用四十八位目标地址寻址,而组播地址是逻辑地址,必须有一套固定规则把它映射成二层地址,交换机才能按帧转发。标准规定用固定的前导加地址低位合成目标二层地址,于是同一组播组在全网使用同一个二层标识。
为什么会出现三十二个组共享一个二层地址
组播标识有二十八位有效位,而映射时只取低位二十三位,位宽不足导致每三十二个组播组落到同一个二层地址上。网卡按二层地址过滤,会把不属于自己的帧也收上来,因此最终还需要在协议层再做一次精确过滤,这正是接收侧必须做双重判断的原因。
基本信息
| 前导部分 | 固定的六个十六进制位 |
|---|---|
| 映射依据 | 取组播地址的低二十三位 |
| 位宽差异 | 组播有效位二十八位,映射只用二十三位 |
| 重合比例 | 每三十二个组播组共用一个二层地址 |
| 二层地址取值范围 | 固定前导加低位范围,最高一位恒为零 |
典型使用场景
- 分析为何多收流量:主机收到不属于自己加入的组的帧,是因为二层地址重合,属于预期
- 排查组播不通:先确认二层地址是否被交换机正确学习,再检查协议层是否加入该组
- 交换机配置:组播侦听功能按二层地址转发,重合的组会被一并转发到同一端口
- 写过滤规则:二层规则无法精确区分重合的组,必须在协议层补充精确过滤
- 教学演示:用一次映射计算说明“看起来不同的地址为何落到同一个二层标识”
- 工具验证:用脚本验算映射结果,与抓包中的实际二层地址对照确认
映射规则与例子
映射规则与例子
# 规则:目标二层地址 = 固定前导 + 组播地址的低二十三位
# 224.0.0.5 → 01:00:5e:00:00:05
# 239.255.255.250 → 01:00:5e:7f:ff:fa
# 下面用地址库验算第二个例子
import ipaddress
addr = int(ipaddress.IPv4Address('239.255.255.250'))
low23 = addr & 0x7FFFFF
print('01:00:5e:%02x:%02x:%02x' % ((low23 >> 16) & 0xff, (low23 >> 8) & 0xff, low23 & 0xff))
# 输出 01:00:5e:7f:ff:fa,与上例一致重合对照
| 组播地址 | 低二十三位 | 映射结果 | 是否重合 |
|---|---|---|---|
| 224.0.0.1 | 000001 | 01:00:5e:00:00:01 | 常见控制组 |
| 239.1.1.1 | 010101 | 01:00:5e:01:01:01 | 与下一行重合 |
| 239.129.1.1 | 010101 | 01:00:5e:01:01:01 | 与上一行重合 |
| 242.1.1.1 | 420101 | 01:00:5e:42:01:01 | 与组播段外地址重合 |
三十二路重合意味着网卡可能收到别的组的帧,必须在协议层过滤:例如两个常见地址会共享同一二层标识,只靠二层过滤无法区分。
排查时按两层分别看:二层看交换机端口是否收到该二层地址的帧,三层看主机是否已加入该组、组播路由是否存在。两层都正常才说明链路完整。