搭建的目标网络描述
单个源节点S,一个中间路由转发节点M,两个组播目的节点D1和D2。
S通过非组播组成员M的路由转发向D1和D2发送组播消息,网络中存在两个虚拟局域网vlan,其中vlan1包含源节点S和中间路由器节点M,vlan2包含中间路由器节点M以及两个组播目的节点D1和D2。
他们的IP地址配置如下所示:
节点编号 | Vlan1 | Vlan2 |
---|---|---|
S | wlan0:10.10.10.1 | |
M | wlan2:10.10.10.2 | wlan6:192.168.3.1 |
D1 | wlan1:192.168.3.2 | |
D2 | wlan1:192.168.3.3 |
这里的关键点是中间路由转发节点M配备有两张网卡,这两张网卡分别工作在vlan1和vlan2中,使得M节点能够同时与vlan1中的源节点S以及vlan2中的接收节点D1、D2同时进行通信,进而实现数据转发的任务。
所有节点都需要运行单播路由协议,使得每个节点在本地生成单播路由表,这是组播路由表生成的前提,也可以通过手动配置静态路由的方式加以设定,这里我们采用的是自组网路由协议olsrd辅助生成静态路由,在每一个节点上运行,包括S、M、D1和D2。
关于组播,可以为S、D1和D2上配置组播转发路由,在中间路由器节点运行pimd,组播网络就能开始运行。
在D1、D2节点上开启组播数据接收程序./receiver加入组播组224.5.5.5,并且等待接收组播数据,然后在源节点S无需加入组播组,只需要启动发送数据程序./sender即可。
网络搭建
查看本机是否支持组播操作
广播需要在局域网内才能实现,另外得查看linux系统是否支持组播和广播。
查看本机是否支持组播操作,有两种可选方法:
方法A:输入命令:ifconfig
如果出现
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
则说明本机支持组播。
方法B:查看/boot/config-x.x.xx 文件中是否有如下内容
CONFIG_IP_MULTICAST=y
CONFIG_NET_IPIP=m
CONFIG_IP_MROUTE=y
由于从linux 2.4内核开始,linux操作系统默认添加了对组播操作的支持,如果使用老版本的linux操作系统的话,可能会存在不支持的情况,此时可以选择更新操作系统,如果不想更新操作系统,就需要重新编译内核了,具体编译步骤如下:
运行
make menuconfig
进 Networking support -> Networking options里面就有选项:
IP: multicasting
IP: tunneling
IP: multicast routing
IP: PIM-SM version 1 support
IP: PIM-SM version 2 support
选中这几项,保存退出
make && make modules_install && make install
重启,用新内核启动。
启动主机转发功能
使得普通的linux主机也具有路由器的数据包转发功能
echo 1 >/proc/sys/net/ipv4/ip_forward
解释:出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将包发往本机另一网卡,该网卡根据路由表继续发送数据包。这通常就是路由器所要实现的功能。
配置Linux系统的ip转发功能,首先保证硬件连通,然后打开系统的转发功能
less /proc/sys/net/ipv4/ip_forward
该文件内容为0,表示禁止数据包转发,1表示允许,将其修改为1。可使用命令
echo "1" > /proc/sys/net/ipv4/ip_forward
修改文件内容,重启网络服务或主机后效果不再。若要其自动执行,可将命令
echo "1" > /proc/sys/net/ipv4/ip_forward
写入脚本/etc/rc.d/rc.local 或者 在/etc/sysconfig/network脚本中添加
FORWARD_IPV4="YES"
设置网关
发送多播包的主机需要设置网关,否则运行sendto()会出现"network is unreachable",网卡可以随便设置,但是一定要设。
接收多播包的主机也需要设置网关,否则运行时会出现IP_ADD_MEMBERSHIP错误。
下面以为无线网卡wlan0添加静态组播路由为例进行说明:
sudo route add -net 224.0.0.0 netmask 240.0.0.0 dev wlan0
sudo route add default gw "192.168.2.20" dev wlan0
实际上只需要配置如下路由即可,默认网关的配置可有可无.
下面进行S节点的组播静态路由配置:
sudo route add -net 224.0.0.0 gw "10.10.10.2" netmask 240.0.0.0 dev wlan0
下面进行接收节点D1的组播静态路由配置:
sudo route add -net 224.0.0.0 gw "192.168.3.1" netmask 240.0.0.0 dev wlan1
D2配置与D1完全相同,故而不再赘述。
另外:
sudo route del -net 224.0.0.0 netmask 240.0.0.0 wlan0 #删除添加的组播路由
配置pimd,运行PIM协议
将下载的pimd-2.1.8.tar.bz2解压,进入解压目录,并进行编译和安装
# tar -jxvf pimd-2.1.8.tar.bz2
# cd pimd-2.1.8
# make
# make install
组播转发前提条件
IP组播模块提供了创建和删除转发缓存的基本功能,但只有通过组播路由协议守护进程(通常是mrouted),依靠路由协议(如静态路由、OSPF、RIP、PIM)来生成转发缓存,才能真正实现组播功能。
因此,IP组播模块提供用于创建和删除转发缓存和虚拟接口套接口选项,供组播路由协议守护进程来操作。创建转发缓存过程通常如下:当接收到组播报文后,便根据组播报文的源和目的地址为其创建一个临时的转发缓存,然后给组播路由协议守护进程发送IGMPMSG_NOCACHE报告。当组播路由协议守护进程收到IGMPMSG_NOCACHE报告后,便在协议维护的组播路由表里选路,然后通过套接口选项创建新的转发缓存,完成后组播报文便可以转发了。
因此,如果要实现组播路由,必须具备的前提条件为:路由转发缓存和组播路由协议守护进程。由于我们在本次测试中使用的是PIM-SM协议,因此其对应的守护进程为pimd。
实验过程及现象
- 源节点s启动组播发送程序
# ./sender
- 当中间路由转发节点M未运行pimd守护进程时,
此时目的节点D1和D2启动组播接收程序后无法接收到组播数据包(原因很简单,此时还无路由信息,所以中间节点M不会转发源节点s发送的组播数据包)
查看中间路由转发节点M的组播虚拟转发接口信息如下:
查看命令:
# more /proc/net/ip_mr_vif
节点M的虚拟转发接口上也无任何数据。
- 在中间路由转发节点M上运行pimd守护进程
查看组播路由协议pimd运行状态
通过如下指令显示的调试信息:
# pimd -d
从调试信息可以看出,pimd以密集模式启动,并且选举IP地址为192.168.3.1的节点为汇聚点。
通过如下指令显示的路由信息:
# pimd -r
查看中间路由转发节点M的单播路由表
查看中间路由转发节点M的组播路由表
查看中间路由转发节点M的组播虚拟转发接口信息
从上图可知,中间路由转发节点wlan2接口有组播数据包的接收,然后组播数据包从M节点的wlan6节点转发,即建立了组播虚拟转发接口。
查看组播转发缓存表:
上图显示的是,组播源节点IP为10.10.10.1即s节点。组播组IP地址为224.5.5.5,组播转发缓存已建立。
-
最后目的节点D1和D2都能正确接收到组播数据包
总结
从上面的测试结果和分析可以知道,为了实现组播源和组播成员之间通信,必须建立起来正确的输入输出通道(即组播转发表)。即
同时在linux 内核中必须要有正确的路由表支持,linux 内核中的路由表是不会自动建立的,需要借助组播路由守护进程。如pimd。
再者,需要加入组播组的组播成员本身要支持IGMP 协议,来实现对自身状态的管理和报告。
参考资料
- 使用如下命令来查看当前网卡上加入的组播组
#netstat -gn
IPv4/IPv6 Group Memberships
Interface RefCnt Group
- 查看本机内核IP路由表
route -ne
内核IP路由表
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.2.20 0.0.0.0 UG 0 0 0 wlan0
192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
192.168.2.60 192.168.2.60 255.255.255.255 UGH 0 0 0 wlan0
224.0.0.0 192.168.2.20 255.255.255.0 UG 0 0 0 wlan0
- 查看多播转发缓存表
[root@linux ~]# more /proc/net/ip_mr_cache
Group Origin Iif Pkts Bytes Wrong Oifs
010101E0 010A0A0A 0 17637 18695220 0 1:1
FAFFFFEF 010A0A0A 0 30 12393 0
- 查看多播虚拟转发接口
[root@linux ~]# more /proc/net/ip_mr_vif
Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote
0 eth0 18348036 17362 9784860 9231 00000 020A0A0A 00000000
1 eth 1 113304460 106891 18009400 16990 00000 016FA8C0 00000000
2 pimreg 0 0 0 0 00004 020A0A0A 00000000
- 列出多播路由表
[root@linux ~]# ip mroute
(10.10.10.1, 224.1.1.1) Iif: eth0 Oifs: eth1
- 重要的组播IP地址
224.0.0.0 - Base address
224.0.0.1 - 网段中所有支持多播的主机,即任何具有多播功能的主机在接口启动后都会自动加入该组. 因此该地址不需要设置的,只要开启组播功能就会自动加入该组.
224.0.0.2 - 网段中所有支持多播的路由器,任何具有组播功能的路由器在接口启动后都会自动加入该组.
224.0.0.4 - 网段中所有的DVMRP路由器
224.0.0.5 - 所有的OSPF路由器
224.0.0.6 - 所有的OSPF指派路由器
224.0.0.7 - 所有的ST路由器
224.0.0.8 - 所有的ST主机
224.0.0.9 - 所有RIPv2路由器
224.0.0.10 - 网段中所有支的路由器
224.0.0.11 - Mobile-Agents
224.0.0.12 - DHCP server / relay agent.
224.0.0.13 - 所有的PIM路由器
224.0.0.22 - 所有的IGMP路由器
224.0.0.251 - 所有的支持组播的DNS服务器