searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

multicast

2024-06-17 07:05:44
5
0

1. 接收
a. 初始化
1). 创建SOCK_DGRAM socket
2). bind multicast addr
int inet_bind()
{
        /*设置inet_rcv_saddr为multicast address, inet_saddr为0*/ 
        inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->inet_saddr = 0;  /* Use device */
}

3) IP_ADD_MEMBERSHIP
/*将multicast address以及所绑定的dev(传递本地ip地址表示绑定该ip地址的dev)告诉给内核*/
struct ip_mc_socklist {
        struct ip_mc_socklist __rcu *next_rcu;
        struct ip_mreqn         multi;
        .....
};

struct ip_mc_list {
        struct in_device        *interface;
        __be32                  multiaddr
};

int ip_mc_join_group()
{
        /*imr_ifindex或者imr_address找dev*/
        in_dev = ip_mc_find_dev(net, imr);
    
        /*检查是否已经有相同的绑定到这个socket上, 一个socket可以加多个multicast组*/
        err = -EADDRINUSE;
        ifindex = imr->imr_ifindex;
        for_each_pmc_rtnl(inet, i) {
                if (i->multi.imr_multiaddr.s_addr == addr &&
                    i->multi.imr_ifindex == ifindex)
                        goto done;
                count++;
        }   

        /*创建一个新的*/
        iml = sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);
        /*放到inet->mc_list上*/
        memcpy(&iml->multi, imr, sizeof(*imr));
        iml->next_rcu = inet->mc_list;
        rcu_assign_pointer(inet->mc_list, iml);


        /*multicast加入到in_dev->mc_list, 设备上的全局multicast list*/
        /*创建ip_mc_list加入到in_dev->mac_list*/
        ip_mc_inc_group(in_dev, addr);
}

b. 收报文
1) route
int ip_route_input_noref()
{
        if (ipv4_is_multicast(daddr)) {
                struct in_device *in_dev = __in_dev_get_rcu(dev);
                if (in_dev) {
                        /*查看in_dev->mc_list上是否有地址位daddr的multicast address*/
                        int our = ip_check_mc_rcu(in_dev, daddr, saddr,
                                                  ip_hdr(skb)->protocol);
                        if (our) {
                                /*设置rth->dst.input = ip_local_deliver;*/
                                /*rt->rt_flags = RTCF_MULTICAST*/
                                int res = ip_route_input_mc(skb, daddr, saddr,
                                                            tos, dev, our);
                        }
                }
        }
}

0条评论
作者已关闭评论
w****n
15文章数
0粉丝数
w****n
15 文章 | 0 粉丝
w****n
15文章数
0粉丝数
w****n
15 文章 | 0 粉丝
原创

multicast

2024-06-17 07:05:44
5
0

1. 接收
a. 初始化
1). 创建SOCK_DGRAM socket
2). bind multicast addr
int inet_bind()
{
        /*设置inet_rcv_saddr为multicast address, inet_saddr为0*/ 
        inet->inet_rcv_saddr = inet->inet_saddr = addr->sin_addr.s_addr;
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->inet_saddr = 0;  /* Use device */
}

3) IP_ADD_MEMBERSHIP
/*将multicast address以及所绑定的dev(传递本地ip地址表示绑定该ip地址的dev)告诉给内核*/
struct ip_mc_socklist {
        struct ip_mc_socklist __rcu *next_rcu;
        struct ip_mreqn         multi;
        .....
};

struct ip_mc_list {
        struct in_device        *interface;
        __be32                  multiaddr
};

int ip_mc_join_group()
{
        /*imr_ifindex或者imr_address找dev*/
        in_dev = ip_mc_find_dev(net, imr);
    
        /*检查是否已经有相同的绑定到这个socket上, 一个socket可以加多个multicast组*/
        err = -EADDRINUSE;
        ifindex = imr->imr_ifindex;
        for_each_pmc_rtnl(inet, i) {
                if (i->multi.imr_multiaddr.s_addr == addr &&
                    i->multi.imr_ifindex == ifindex)
                        goto done;
                count++;
        }   

        /*创建一个新的*/
        iml = sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);
        /*放到inet->mc_list上*/
        memcpy(&iml->multi, imr, sizeof(*imr));
        iml->next_rcu = inet->mc_list;
        rcu_assign_pointer(inet->mc_list, iml);


        /*multicast加入到in_dev->mc_list, 设备上的全局multicast list*/
        /*创建ip_mc_list加入到in_dev->mac_list*/
        ip_mc_inc_group(in_dev, addr);
}

b. 收报文
1) route
int ip_route_input_noref()
{
        if (ipv4_is_multicast(daddr)) {
                struct in_device *in_dev = __in_dev_get_rcu(dev);
                if (in_dev) {
                        /*查看in_dev->mc_list上是否有地址位daddr的multicast address*/
                        int our = ip_check_mc_rcu(in_dev, daddr, saddr,
                                                  ip_hdr(skb)->protocol);
                        if (our) {
                                /*设置rth->dst.input = ip_local_deliver;*/
                                /*rt->rt_flags = RTCF_MULTICAST*/
                                int res = ip_route_input_mc(skb, daddr, saddr,
                                                            tos, dev, our);
                        }
                }
        }
}

文章来自个人专栏
完成任务
15 文章 | 1 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0