Skip to content

Commit

Permalink
RFC 4605: Forward packets from one downstream interface to the others
Browse files Browse the repository at this point in the history
4.2.  Forwarding Packets
A proxy device forwards packets received on any downstream interface to to each
downstream interface other than the incoming interface based upon the
downstream interfaces' subscriptions and whether or not this proxy
device is the IGMP/MLD Querier on each interface.
  • Loading branch information
haibbo committed Feb 11, 2014
1 parent c4e5377 commit 4a7f5e2
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 37 deletions.
3 changes: 2 additions & 1 deletion include/kernel_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ void k_del_ip4_vif (int socket, int ifindex);
STATUS k_start4_mproxy(int socket);
void k_stop4_mproxy(int socket);
int k_get_vmif(int ifindex,int family);
int k_get_rlif(int ifindex, int family);
void k_add_ip6_mif (int socket, int ifindex);
void k_del_ip6_mif (int socket, int ifindex);
STATUS k_start6_mproxy(int socket);
void k_stop6_mproxy(int socket);
/*protocol independent code*/
STATUS k_mcast_join( pi_addr* pia, char* ifname);
STATUS k_mcast_leave(pi_addr* pia, char* ifname);
STATUS k_add_mfc(pi_addr *p_mcastgrp , pi_addr *p_origin, if_set *p_ttls);
STATUS k_add_mfc(int iif_index, pi_addr *p_mcastgrp , pi_addr *p_origin, if_set *p_ttls);
STATUS k_del_mfc(pi_addr *p_mcastgrp, pi_addr *p_origin);
STATUS k_mcast_msfilter(pi_addr* p_addr, pa_list *p_addr_list,int fmode);
#endif
3 changes: 2 additions & 1 deletion include/membership.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef struct imp_mfc {
LIST_ENTRY(imp_mfc) link;
struct if_set ttls;
pi_addr pia;
int iif_index;
}imp_mfc;

typedef struct imp_membership_db {
Expand Down Expand Up @@ -70,7 +71,7 @@ void imp_membership_db_cleanup(imp_membership_db *p_md);
* Return : NULL
*------------------------------------------------------------------------
*/
void imp_membership_db_mfc_add(pi_addr *p_ga, pi_addr *p_src, if_set *p_ttls);
void imp_membership_db_mfc_add(int iif_index, pi_addr *p_ga, pi_addr *p_src, if_set *p_ttls);
/*-----------------------------------------------------------------------
* Name : imp_membership_db_mfc_find
*
Expand Down
42 changes: 23 additions & 19 deletions src/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static int imp_get_is_forward(imp_interface* p_if, pi_addr *pigp, pi_addr *pip)
}

static int imp_get_mfcc_ttls(if_set *p_ttls, int length, pi_addr *pi_src,
pi_addr *p_group)
pi_addr *p_group, int iif_index)
{
imp_interface *p_if = imp_interface_first();
unsigned char flag = 0;
Expand All @@ -138,10 +138,12 @@ static int imp_get_mfcc_ttls(if_set *p_ttls, int length, pi_addr *pi_src,
while(p_if) {
if (p_if->type != INTERFACE_UPSTREAM &&
imp_get_is_forward(p_if, p_group, pi_src) &&
p_if->if_index < length) {
p_if->if_index < length &&
p_if->if_index != iif_index) {

int vmif = 0;
vmif = k_get_vmif(p_if->if_index, p_group->ss.ss_family);

vmif = k_get_vmif(p_if->if_index, p_group->ss.ss_family);
IF_SET(vmif, p_ttls);
flag = 1;
}
Expand Down Expand Up @@ -541,6 +543,7 @@ void mcast_recv_mld(int sockfd, int version)
*/
struct mrt6msg *p_mrmsg;
int mif = 0;
int iif_index;

p_mrmsg = msg.msg_iov->iov_base;

Expand All @@ -551,23 +554,23 @@ void mcast_recv_mld(int sockfd, int version)
imp_build_piaddr(AF_INET6, &p_mrmsg->im6_dst, &pig);
imp_build_piaddr(AF_INET6, &p_mrmsg->im6_src, &pia);

mif = k_get_vmif(get_up_if_index(), AF_INET6);

//mif = k_get_vmif(get_up_if_index(), AF_INET6);
iif_index = k_get_rlif(mif, AF_INET6);
IMP_LOG_DEBUG("k_get_vmif = %d im6_mif %d\n", mif, p_mrmsg->im6_mif);

if (mif == p_mrmsg->im6_mif) {
//if (mif == p_mrmsg->im6_mif) {

if_set ttls;
if_set ttls;

bzero(&ttls, sizeof(ttls));
bzero(&ttls, sizeof(ttls));

/*get ttls*/
if (imp_get_mfcc_ttls(&ttls, MAXVIFS, &pia, &pig) != 0) {
/*get ttls*/
if (imp_get_mfcc_ttls(&ttls, MAXVIFS, &pia, &pig, iif_index) != 0) {

IMP_LOG_DEBUG("add MFC:src -- %s group -- %s\n\n", imp_pi_ntoa(&pia), imp_pi_ntoa(&pig));
imp_membership_db_mfc_add(&pig, &pia, &ttls);
}
IMP_LOG_DEBUG("add MFC:src -- %s group -- %s\n\n", imp_pi_ntoa(&pia), imp_pi_ntoa(&pig));
imp_membership_db_mfc_add(iif_index, &pig, &pia, &ttls);
}
//}
return;

}
Expand Down Expand Up @@ -672,15 +675,16 @@ void mcast_recv_igmp(int sockfd, int version)
if(p_if->if_index == if_index && p_if->if_addr.ss.ss_family == AF_INET)
break;
}

IMP_LOG_DEBUG("src addr = %s\nreceived interface %d\n",
imp_inet_ntoa(((struct sockaddr_in*)&sa)->sin_addr.s_addr), if_index);

if(p_if == NULL){

IMP_LOG_WARNING("Don't exist this VIF\n", if_index);
IMP_LOG_WARNING("Don't exist this VIF %d\n", if_index);
return;
}

IMP_LOG_DEBUG("src addr = %s\nreceived interface %d\n",
imp_inet_ntoa(((struct sockaddr_in*)&sa)->sin_addr.s_addr), if_index);


ip = (struct iphdr*)buf;
Expand All @@ -702,17 +706,17 @@ void mcast_recv_igmp(int sockfd, int version)
}

/*when protocol is zero, we need add MFC base one this kind of packet*/
if (ip->protocol == 0 && p_if->type == INTERFACE_UPSTREAM) {
if (ip->protocol == 0) {

if_set ttls;

bzero(&ttls, sizeof(ttls));

/*get ttls*/
if(imp_get_mfcc_ttls(&ttls, MAXVIFS, &pia, &pig) != 0){
if(imp_get_mfcc_ttls(&ttls, MAXVIFS, &pia, &pig, if_index) != 0){

IMP_LOG_DEBUG("add MFC:src -- %s group -- %s\n\n", imp_pi_ntoa(&pia), imp_pi_ntoa(&pig));
imp_membership_db_mfc_add(&pig, &pia, &ttls);
imp_membership_db_mfc_add(if_index, &pig, &pia, &ttls);
}
return;
} else if (ip->protocol == 0) {
Expand Down
62 changes: 51 additions & 11 deletions src/kernel_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,22 @@ static int get_mifi_ipv6(int ifindex)
return 0;
}


static int get_rifi_ipv4(int vif)
{
if (vif > MAXMIFS - 1)
return 0;
return vif2phyif[vif];

}

static int get_rifi_ipv6(int mif)
{
if (mif > MAXMIFS - 1)
return 0;
return mif2phyif[mif];
}

#endif
int k_get_vmif(int ifindex, int family)
{
Expand All @@ -93,6 +109,26 @@ int k_get_vmif(int ifindex, int family)
return 0;
}

/*get real interface index*/
int k_get_rlif(int vif, int family)
{
if (family == AF_INET) {
#ifdef VIF_NOT_EQUAL_MIF
return get_rifi_ipv4(vif);
#else
return vif;
#endif

} else if (family == AF_INET6) {
#ifdef VIF_NOT_EQUAL_MIF
return get_rifi_ipv6(vif);
#else
return vif;
#endif
}

return 0;
}

void k_add_ip4_vif (int socket, struct in_addr* sin, int ifindex)
{
Expand Down Expand Up @@ -140,8 +176,8 @@ void k_stop4_mproxy(int socket)
}


static STATUS k_add_ip4_mfc(int socket, pi_addr *p_mcastgrp
, pi_addr *p_origin, if_set *p_ttls)
static STATUS k_add_ip4_mfc(int socket, int iif_index, pi_addr *p_mcastgrp
,pi_addr *p_origin, if_set *p_ttls)
{
struct mfcctl mfc;
int i;
Expand All @@ -151,7 +187,8 @@ static STATUS k_add_ip4_mfc(int socket, pi_addr *p_mcastgrp
memcpy(&mfc.mfcc_origin, &p_origin->v4.sin_addr, sizeof(struct in_addr));
memcpy(&mfc.mfcc_mcastgrp, &p_mcastgrp->v4.sin_addr, sizeof(struct in_addr));

mfc.mfcc_parent = k_get_vmif(get_up_if_index(), AF_INET);
//mfc.mfcc_parent = k_get_vmif(get_up_if_index(), AF_INET);
mfc.mfcc_parent = k_get_vmif(iif_index, AF_INET);

IMP_LOG_DEBUG("upif_index = %d\n", get_up_if_index());
for (i = 0;i < MAXVIFS;i++) {
Expand Down Expand Up @@ -229,7 +266,7 @@ void k_stop6_mproxy(int socket)
}


static STATUS k_add_ip6_mfc(int socket, pi_addr *p_mcastgrp
static STATUS k_add_ip6_mfc(int socket, int iif_index, pi_addr *p_mcastgrp
, pi_addr *p_origin, if_set *p_ttls)
{

Expand All @@ -238,7 +275,7 @@ static STATUS k_add_ip6_mfc(int socket, pi_addr *p_mcastgrp
memcpy(&mf6c.mf6cc_origin, &p_origin->v6, sizeof(mf6c.mf6cc_origin));
memcpy(&mf6c.mf6cc_mcastgrp, &p_mcastgrp->v6, sizeof(mf6c.mf6cc_mcastgrp));

mf6c.mf6cc_parent = k_get_vmif(get_up_if_index(), AF_INET6);
mf6c.mf6cc_parent = k_get_vmif(iif_index, AF_INET6);

mf6c.mf6cc_ifset = *p_ttls;

Expand Down Expand Up @@ -285,10 +322,9 @@ STATUS k_mcast_join(pi_addr* p_addr, char* ifname)

STATUS k_mcast_leave( pi_addr* p_addr, char* ifname)
{
#if 0
#if 1
struct group_req req;
int socket = 0;
int ifindex = 0;

if (ifname != NULL) {
if ((req.gr_interface = if_nametoindex(ifname)) == 0) {
Expand All @@ -304,21 +340,23 @@ STATUS k_mcast_leave( pi_addr* p_addr, char* ifname)
socket = get_udp_socket(p_addr->ss.ss_family);
return setsockopt(socket, imp_family_to_level(p_addr->ss.ss_family), MCAST_LEAVE_GROUP,
&req, sizeof(struct group_req));
#endif
#else
return k_mcast_msfilter(p_addr, NULL, MCAST_INCLUDE);
#endif

}

STATUS k_add_mfc(pi_addr *p_mcastgrp , pi_addr *p_origin, if_set *p_ttls)
STATUS k_add_mfc(int iif_index, pi_addr *p_mcastgrp , pi_addr *p_origin, if_set *p_ttls)
{
int socket = 0;
socket = get_igmp_mld_socket(p_mcastgrp->ss.ss_family);

if (p_mcastgrp->ss.ss_family == AF_INET) {

return k_add_ip4_mfc(socket, p_mcastgrp, p_origin, p_ttls);
return k_add_ip4_mfc(socket, iif_index, p_mcastgrp, p_origin, p_ttls);
} else {

return k_add_ip6_mfc(socket, p_mcastgrp, p_origin, p_ttls);
return k_add_ip6_mfc(socket, iif_index, p_mcastgrp, p_origin, p_ttls);
}
}

Expand All @@ -336,6 +374,7 @@ STATUS k_del_mfc(pi_addr *p_mcastgrp, pi_addr *p_origin)
}


#if 0
STATUS k_mcast_msfilter(pi_addr* p_addr, pa_list *p_addr_list, int fmode)
{

Expand Down Expand Up @@ -390,3 +429,4 @@ STATUS k_mcast_msfilter(pi_addr* p_addr, pa_list *p_addr_list, int fmode)
free(p_gf);
return res;
}
#endif
11 changes: 6 additions & 5 deletions src/membership.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ void imp_membership_db_print_all(void)
* Return : NULL
*------------------------------------------------------------------------
*/
void imp_membership_db_mfc_add(pi_addr *p_ga, pi_addr *p_src, if_set *p_ttls)
void imp_membership_db_mfc_add(int iif_index, pi_addr *p_ga, pi_addr *p_src, if_set *p_ttls)
{
imp_membership_db *p_md;
imp_mfc *p_mfc;
Expand All @@ -177,7 +177,7 @@ void imp_membership_db_mfc_add(pi_addr *p_ga, pi_addr *p_src, if_set *p_ttls)
return;
}

if ( k_add_mfc(p_ga, p_src, p_ttls) < 0 ) {
if ( k_add_mfc(iif_index, p_ga, p_src, p_ttls) < 0 ) {

IMP_LOG_ERROR("add mfc fail %s\n", strerror(errno));
return;
Expand All @@ -191,7 +191,8 @@ void imp_membership_db_mfc_add(pi_addr *p_ga, pi_addr *p_src, if_set *p_ttls)

memcpy(&p_mfc->pia, p_src, sizeof(pi_addr));
memcpy(&p_mfc->ttls, p_ttls, sizeof(if_set));

p_mfc->iif_index = iif_index;

LIST_INSERT_HEAD(&p_md->mfc_list, p_mfc, link);


Expand Down Expand Up @@ -288,7 +289,7 @@ void imp_membership_db_mfc_update(pi_addr *p_ga, pi_addr *p_src,
/*pp need MRT_DEL_MFC first to update*/
k_del_mfc(&p_md->pig, &p_mfc->pia);
/*change mfc*/
k_add_mfc(&p_md->pig, &p_mfc->pia, &p_mfc->ttls);
k_add_mfc(p_mfc->iif_index, &p_md->pig, &p_mfc->pia, &p_mfc->ttls);
}

if(p_src != NULL)
Expand Down Expand Up @@ -507,7 +508,7 @@ void imp_membership_db_update(pi_addr *p_ga)
return;
}

k_mcast_msfilter(&p_md->pig, p_md->src_list, p_md->type);
//k_mcast_msfilter(&p_md->pig, p_md->src_list, p_md->type);
p_md->update_flag = 0;
return;
}
Expand Down

0 comments on commit 4a7f5e2

Please sign in to comment.