Linux IGMP PROXY 学习笔记 之 一 igmp proxy相关的数据结构及ig

前面分析了igmp snooping的实现,最近由于工作比较忙,还有就是个人比较懒的缘故一直没有分析igmpproxy的实现,今天开始分析igmpproxy的实现。

我们首先还是从数据结构开始分析之路。

1. ip_mc_list

struct ip_mc_list {

structin_device *interface;//三层接口

__be32 multiaddr;//组播地址

structip_sf_list *sources;//组播路由表对应的源地址过滤相关的地址链表

structip_sf_list *tomb;

unsignedint sfmode;//过滤模式

unsignedlong sfcount[2];

structip_mc_list *next;//指向下一个组播路由entry

structtimer_list timer;//用于发送igmp report报文的定时器

int users;//引用计数

atomic_t refcnt;

spinlock_t lock;

char tm_running;

char reporter;

char unsolicit_count;//用于发送igmp report使用,目前是允许发送3次igmp report报文

char loaded;

unsignedchar gsquery; /* check source marks? */

unsignedchar crcount;

};

该数据结构用于标示一个组播路由,当应用层通过set_sockopt的IP_ADD_MEMBERSHIP命令,将一个组播路由添加到一个网络设备对应的三层数据结构的mc_list中(in_dev->mc_list)

2. mfc_cache

struct mfc_cache{

struct mfc_cache *next; /*指向 下一个组播路由缓存 */

#ifdefCONFIG_NET_NS

struct net *mfc_net;

#endif

__be32 mfc_mcastgrp; /* 组播组ip */

__be32 mfc_origin; /* 组播源ip*/

vifi_t mfc_parent; /*该组播路由对应的vif,通过该值能够找到该组播路由缓存对应的网络设备*/

int mfc_flags; /*Flags on line */

union {

struct {

unsigned long expires;//组播路由缓存失效超时时间

struct sk_buff_head unresolved; /*未创建组播路由缓存的缓冲队列*/

} unres;

struct {

unsigned long last_assert;

int minvif;

int maxvif;

unsigned long bytes;

unsigned long pkt;

unsigned long wrong_if;

unsigned char ttls[MAXVIFS]; /* TTL thresholds */

} res;

} mfc_un;

};

组播路由缓存,组播路由缓存保存在net->ipv4.mfc_cache_array的数组链表中,该数组中的每一个成员都可以看成一个链表。而数组成员的确定是根据源ip地址与组播组地址经过hash计算得出。

当我们首先根据一个下行接口接收的igmp report报文创建了一个组播路由时,此时还没有创建组播路由缓存,当组播流数据到达多播路由器的上行接口时,会最终由函数ip_mr_input进行处理。在这个函数里如果没有查找到组播路由缓存,则会调用ipmr_cache_unresolved 向应用层igmp proxy的相关的应该程序发送igmp 数据包,让应用层igmpproxy相关的应用向内核中添加路由缓存,并将数据包缓存在mfc_cache. mfc_un.unres.unresolved中。

对于查找到组播路由缓存的组播流数据,则从相应的网络接口中把数据发送出去(即多播路由的下行接口)

3.虚拟网络设备

structvif_device {

struct net_device *dev; /*对应的真实网络设备 */

unsigned long bytes_in,bytes_out;

unsigned long pkt_in,pkt_out; /* Statistics */

unsigned long rate_limit; /* Traffic shaping (NI) */

unsigned char threshold; /* TTL threshold */

unsigned short flags; /* Control flags */

__be32 local,remote; /* Addresses(remote for tunnels)*/

int link; /* Physical interface index */

};

虚拟网络设备主要是对应多播路由的上行、下行设备,我们需要为上行、下行设备都创建一个虚拟网络设备。

关于虚拟网络设备的作用,有专家曾经说过主要是为了兼容ip隧道的。

一、igmp proxy实现分析

前面我们说过igmpproxy的工作原理:

对于IGMPPROXY,主要是拦截lan側pc发送的igmp报文,其在wan側作为客户端响应上行路由的查询操作,而在lan側则作为服务端定期发送查询报文。

当lan側加入的组播组在IGMPPROXY设备上没有相应的组播路由时,才会给上层发送组播加入报文,当lan側加入的组播组在IGMPPROXY设备上已经存在时,则无需再将加入报文转发出去。这样不仅能够达到有效抑制二层组播泛滥的问题,且能更有效的获取和控制用户信息,降低网络负载。

理解了igmpproxy的工作原理后,再基于上面一中所说的数据结构,对于一个多播路由器来说,肯定存在2个以及2个以上的网络设备接口:

一个用于上行口:

a) 主要是向上层发送igmpreport/igmp leave 或者响应上层的igmpquery

b) 接收上层多播路由下发的组播流数据,并根据组播路由缓存决定是否将组播流数据发送给下行端口

c) 向下行接口发送igmpquery数据包,维护上层组播路由表与组播路由缓存表

该接口一般是一个wan接口(static、dhcp、pppoe模式)

一个用于下行口:

用于接收lan侧设备发送的igmpreport、igmpleave报文,并交由上层应用层的程序进行后续处理,并实现转发组播流的功能。一般是br0桥接口

实现igmpproxy的步骤大致如下:

1、 创建2个虚拟接口,一个作为upstream 接口,一个作为downstream接口

2、 上行接口设备与下行接口设备都需要维护一个组播路由表,其中上行接口设备维护的组播路由主要是为了将wan侧接收的组播流流向下行接口。而下行接口设备维护的组播路由表主要是维护lan侧设备的加入请求,当接收到一个lan侧igmpleave报文后,需要检查是否是该组播组的最后一个成员,若是则需要发送igmpquery报文,进行查询操作

3、 写一个创建组播路由或者删除组播路由的接口函数供应用层调用,以便实现组播路由的添加或删除

4、 当创建一个组播路由时,并不代表需要创建组播路由缓存,只有接收到组播流后,内核才会发送igmp报文给应用层igmpproxy应用程序,让应用程序创建组播路由缓存。

5、 组播路由与组播路由缓存的存在需要有一个垃圾回收机制。

基本上也就上面5大方面。

下一节会接着分析igmp类型数据包的接收和组播流数据包的接收处理。

人生就是一次充满未知的旅行,在乎的是沿途的风景,

Linux IGMP PROXY 学习笔记 之 一 igmp proxy相关的数据结构及ig

相关文章:

你感兴趣的文章:

标签云: