Ejemplo n.º 1
0
/*
 * void igmp_group_handle_isex()
 *
 * Handle a is_ex{A} report for a group 
 * the report have only one source
 */
void
igmp_group_handle_isex(
        igmp_router_t* router,
	igmp_interface_t* ifp,
	igmp_group_t* gp,
	int numsrc,
	struct in_addr *sources)
{
        igmp_src_t *src,*old_src_set;
	int i;
	membership_db* member;
	/* Reset timer */
	gp->igmpg_timer = IGMP_GMI; /* 260 */
	/* Do the v3 logic */
	old_src_set=gp->igmpg_sources;
	if (gp->igmpg_fmode == IGMP_FMODE_EXCLUDE) {
	  /* $6.4.1: State = Excl(X,Y), Report = IS_EX(A) */
	  for (i=0;i < numsrc;i++){
	    src=igmp_group_src_add(gp,sources[i]);
	    /* (A-X-Y) = GMI */
	    if ((check_src_set(src->igmps_source,old_src_set) == FALSE) && (check_src(src->igmps_source,sources,numsrc) == TRUE)){
	      src->igmps_timer = IGMP_GMI;
	      src->igmps_fstate = FALSE;
	    }
	    else
	      /* delete ( X-A)  delete (Y-A) */
	      if ((check_src(src->igmps_source,sources,numsrc) == FALSE) && (check_src_set(src->igmps_source,old_src_set) == TRUE)){
		//eddie igmp_src_cleanup(gp,sr);
		//eddie k_proxy_del_mfc (router->igmprt_socket, sr->igmps_source.s_addr, gp->igmpg_addr.s_addr);
	      }
	  }	  
	}
	else {
	  /* $6.4.1: State = Incl(X,Y), Report = IS_EX(A) */
	  for (i=0;i< numsrc; i++){
	    src=igmp_group_src_add(gp,sources[i]);
	    if ((check_src_set(src->igmps_source,old_src_set) == FALSE) && (check_src(src->igmps_source,sources,numsrc) == TRUE)){	
	      /*(B-A) = 0*/
	      src->igmps_timer = 0;
	    }else{
	      if ((check_src(src->igmps_source,sources,numsrc) == FALSE) && (check_src_set(src->igmps_source,old_src_set) == TRUE)){ 
		/* delete (A-B)*/
		igmp_src_cleanup(gp,src);
		k_proxy_del_mfc (router->igmprt_socket, src->igmps_source.s_addr, gp->igmpg_addr.s_addr);
	      } 
	    }
	  }
	}
	gp->igmpg_fmode = IGMP_FMODE_EXCLUDE;

	/* Member Join from Downstream */
	if (ifp->igmpi_type != UPSTREAM){
	  member = (membership_db*)update_multi(router,gp->igmpg_addr,gp->igmpg_fmode,numsrc,sources);         
	    if (VALID_ADDR(gp->igmpg_addr)) {
			k_proxy_chg_mfc(router->igmprt_socket, 0, gp->igmpg_addr.s_addr, ifp->igmpi_index,1);
	dbg_printf("(%s->%s(%d)) ifp->igmpi_name is %s, ifp->igmpi_index is %d\n", __FILE__, __FUNCTION__, __LINE__, ifp->igmpi_name, ifp->igmpi_index);

			//k_proxy_chg_mfc(router->igmprt_socket, sources[0].s_addr ,gp->igmpg_addr.s_addr,ifp->igmpi_index,1); // Added by Joshua
	     }			
	}
		
}
Ejemplo n.º 2
0
void handle_igmpv3_toex( __u32 group, __u32 src, int srcnum, __u32 *grec_src )
{
	struct mcft_entry *mymcp;
	
	if(!IN_MULTICAST(group))
		return;
	/* check if it's protocol reserved group */
	if((group&0xFFFFFF00)==0xE0000000)
		return;

	if(!chk_mcft(group)) 
	{
		mymcp = add_mcft(group, src);
		if(!mymcp) return;		
		mymcp->igmp_ver = IGMP_VER_3;
		igmp_add_group( group );
	}
		
	mymcp = get_mcft(group);
	if(mymcp)
	{
		switch( mymcp->filter_mode )
		{
		case MCAST_INCLUDE:
			{
				int i;
				struct src_entry *s, *old_set,*s_next;
				
				//printf("handle_igmpv3_toex: MCAST_INCLUDE\n");
#ifdef KEEP_GROUP_MEMBER				
				add_user(mymcp, src);
#endif
				//IN(A), TO_EX(B) => EX(A*B, B-A)
				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{
					// (B-A)=0
					if( check_src_set(grec_src[i], old_set )==0 )
					{
						s = add_to_srclist( mymcp, grec_src[i] );
						if(s){
							
							s->timer.lefttime = 0;
							s->timer.retry_left = 0;
							igmp_add_mr( mymcp->grp_addr, s->srcaddr, 0 );
						}
					}
				}

				i=0;
				s = old_set;
				while(s)
				{
					s_next=s->next;
					
					//Delete (A-B)
					if( check_src( s->srcaddr, grec_src, srcnum )==0 )
					{
						igmp_del_mr( mymcp->grp_addr, s->srcaddr );
						del_from_srclist( mymcp, s->srcaddr );
					}		
					else
					{
						/*lower A*B timer to LMQT*/
						gsrctmp[i]=s->srcaddr;
						s->timer.lefttime=LAST_MEMBER_QUERY_INTERVAL;
						s->timer.retry_left=LAST_MEMBER_QUERY_COUNT;
						
						i++;
						if(i==IGMPV3_MAX_SRCNUM) 
							break;
					}
					s = s_next;
				}
				//send Q(G,A*B)
				if(i>0) igmpv3_query( mymcp, i, gsrctmp );
				
				
				//Group Timer=GMI
				mymcp->timer.lefttime = MEMBER_QUERY_INTERVAL;
				mymcp->timer.retry_left = MEMBER_QUERY_COUNT;
				
				//set the new state
				mymcp->filter_mode = MCAST_EXCLUDE;
				igmp_set_srcfilter( mymcp );
			}
			break;
		case MCAST_EXCLUDE:
			{
				int i;
				struct src_entry *s, *old_set,*s_next;
				
				//printf("handle_igmpv3_toex: MCAST_EXCLUDE\n");
#ifdef KEEP_GROUP_MEMBER				
				add_user(mymcp, src);
#endif	
				//EX(X,Y), TO_EX(A) => EX(A-Y, Y*A)
				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{
									
					if( check_src_set( grec_src[i], old_set )==0 )
					{
						// (A-X-Y)=Group Timer
						s = add_to_srclist( mymcp, grec_src[i] );
						if(s){
							
							s->timer.lefttime = mymcp->timer.lefttime;
							s->timer.retry_left = MEMBER_QUERY_COUNT;
							igmp_add_mr( mymcp->grp_addr, s->srcaddr, 1 );
						}
					}
				}
				
				s = old_set;
				while(s)
				{
					s_next=s->next;
					
					//Delete (X-A), Delete(Y-A)
					if( check_src( s->srcaddr, grec_src, srcnum )==0 )
					{
						igmp_del_mr( mymcp->grp_addr, s->srcaddr );
						del_from_srclist( mymcp, s->srcaddr );
					}
					s = s_next;
				}

				//send Q(G,A-Y)
				i=0;
				s = mymcp->srclist;
				while(s)
				{
					s_next=s->next;				
					if( s->timer.lefttime > 0 )//A-Y
					{
						gsrctmp[i]=s->srcaddr;
						/*lower A-Y timer to LMQT*/
						s->timer.lefttime=LAST_MEMBER_QUERY_INTERVAL;
						s->timer.retry_left=LAST_MEMBER_QUERY_COUNT;
							
						i++;
						if(i==IGMPV3_MAX_SRCNUM) break;
					}
					s=s_next;
				}
				if(i>0) igmpv3_query( mymcp, i, gsrctmp );
				
				//Group Timer=GMI
				mymcp->timer.lefttime = MEMBER_QUERY_INTERVAL;
				mymcp->timer.retry_left = MEMBER_QUERY_COUNT;

				//set the new state
				mymcp->filter_mode = MCAST_EXCLUDE;
				igmp_set_srcfilter( mymcp );
			}
			break;
		default:
			break;
		}
	}
}
Ejemplo n.º 3
0
void handle_igmpv3_isin( __u32 group, __u32 src, int srcnum, __u32 *grec_src )
{
	struct mcft_entry *mymcp;
	
	if(!IN_MULTICAST(group))
		return;
	/* check if it's protocol reserved group */
	if((group&0xFFFFFF00)==0xE0000000)
		return;

	if(!chk_mcft(group)) 
	{
		mymcp = add_mcft(group, src);
		if(!mymcp) return;		
		mymcp->igmp_ver = IGMP_VER_3;
		igmp_add_group( group );
		
		
	}
		
	mymcp = get_mcft(group);
	if(mymcp)
	{
		switch( mymcp->filter_mode )
		{
		case MCAST_INCLUDE:
			{
				int i;
				struct src_entry *s, *old_set;

				//printf("handle_igmpv3_isin: MCAST_INCLUDE\n");	
				
#ifdef KEEP_GROUP_MEMBER				
				add_user(mymcp, src);
#endif	

				//IN(A), IN(B) => IN(A+B)
				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{
					
					if( check_src_set(grec_src[i], old_set )==0 )
						igmp_add_mr( mymcp->grp_addr, grec_src[i], 1 );
					// (B)= GMI
					s = add_to_srclist( mymcp, grec_src[i] );
					if (s)
					{
						s->timer.lefttime = MEMBER_QUERY_INTERVAL;
						s->timer.retry_left = MEMBER_QUERY_COUNT;
					}
				}

				//set the new state
				mymcp->filter_mode = MCAST_INCLUDE;
				igmp_set_srcfilter( mymcp );
			}
			break;
		case MCAST_EXCLUDE:
			{
				int i;
				struct src_entry *s, *old_set;
				
				//printf("handle_igmpv3_isin: MCAST_EXCLUDE\n");
				//EX(X,Y), IS_IN(A) => EX(X+A, Y-A)
#ifdef KEEP_GROUP_MEMBER				
				add_user(mymcp, src);
#endif	

				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{
					s = add_to_srclist( mymcp, grec_src[i] );
					if(s)
					{	// (A)= GMI
						s->timer.lefttime = MEMBER_QUERY_INTERVAL;
						s->timer.retry_left = MEMBER_QUERY_COUNT;
						igmp_add_mr( mymcp->grp_addr, s->srcaddr, 1 );
					}
				}
				
				//set the new state
				mymcp->filter_mode = MCAST_EXCLUDE;
				igmp_set_srcfilter( mymcp );
			}
			break;
		default:
			break;
		}
	}
}
Ejemplo n.º 4
0
void handle_igmpv3_toin( __u32 group, __u32 src, int srcnum, __u32 *grec_src )
{
	struct mcft_entry *mymcp;	
	
	if(!IN_MULTICAST(group))
		return;
	/* check if it's protocol reserved group */
	if((group&0xFFFFFF00)==0xE0000000)
		return;

	if(!chk_mcft(group)) 
	{
		mymcp = add_mcft(group, src);
		if(!mymcp) return;		
		mymcp->igmp_ver = IGMP_VER_3;
		igmp_add_group( group );
	}
		
	mymcp = get_mcft(group);
	if(mymcp)
	{
		switch( mymcp->filter_mode )
		{
		case MCAST_INCLUDE:
			{
				int i;
				struct src_entry *s, *old_set;

				// Mason Yu Test
				//printf("handle_igmpv3_toin: MCAST_INCLUDE\n");
#ifdef KEEP_GROUP_MEMBER
				if ( srcnum != 0 ){

					add_user(mymcp, src);
				}
#endif

				//IN(A), TO_IN(B) => IN(A+B)
				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{
					
					if( check_src_set( grec_src[i], old_set )==0 )
						igmp_add_mr( mymcp->grp_addr, grec_src[i], 1 );
					s = add_to_srclist( mymcp, grec_src[i] );
					if(s)
					{	// (B)= GMI
						s->timer.lefttime = MEMBER_QUERY_INTERVAL;
						s->timer.retry_left = MEMBER_QUERY_COUNT;
					}				
					
				}
				
				//send Q(G,A-B)
				i=0;
				s = old_set;
				while(s)
				{
					if( check_src( s->srcaddr, grec_src, srcnum )==0 )
					{
						gsrctmp[i]=s->srcaddr;
						
						/*lower A-B timer to LMQT*/
						s->timer.lefttime=LAST_MEMBER_QUERY_INTERVAL;
						s->timer.retry_left=LAST_MEMBER_QUERY_COUNT;
						
						i++;
						if(i==IGMPV3_MAX_SRCNUM) break;
					}					
					s = s->next;
				}
				if(i>0) igmpv3_query( mymcp, i, gsrctmp );
				
				//set the new state
				mymcp->filter_mode = MCAST_INCLUDE;
				igmp_set_srcfilter( mymcp );	
				#ifdef KEEP_GROUP_MEMBER
				if ( srcnum == 0 ) {
					int count;
					count = del_user(mymcp, src);
					if (count == 0) {// no member, drop it!
						del_mr(mymcp->grp_addr);				
						del_mcft(mymcp->grp_addr);
					}
				}
				#endif
			}
			
			break;
		case MCAST_EXCLUDE:
			{
				int i;
				struct src_entry *s, *old_set;

				// Mason Yu Test
				//printf("handle_igmpv3_toin: MCAST_EXCLUDE and srcnum=%d\n", srcnum);
#ifdef KEEP_GROUP_MEMBER
				if ( srcnum != 0 ){
					add_user(mymcp, src);
				}
#endif

				//EX(X,Y), TO_IN(A) => EX(X+A, Y-A)
				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{
					s = add_to_srclist( mymcp, grec_src[i] );
					if(s)
					{	// (A)= GMI
						s->timer.lefttime = MEMBER_QUERY_INTERVAL;
						s->timer.retry_left = MEMBER_QUERY_COUNT;
						igmp_add_mr( mymcp->grp_addr, s->srcaddr, 1 );
					}
				}	

				//send Q(G,X-A)
				i=0;
				s = old_set;
				while(s)
				{
					if( s->timer.lefttime>0 )
					{
						if( check_src( s->srcaddr, grec_src, srcnum )==0 )
						{
							gsrctmp[i]=s->srcaddr;

							/*lower X-A timer to LMQT*/
							s->timer.lefttime=LAST_MEMBER_QUERY_INTERVAL;
							s->timer.retry_left=LAST_MEMBER_QUERY_COUNT;
							
							i++;
							if(i==IGMPV3_MAX_SRCNUM) break;
						}
					}					
					s = s->next;
				}
				if(i>0) igmpv3_query( mymcp, i, gsrctmp );
				
				/* lower group filter timer to LMQT*/
				mymcp->timer.lefttime=LAST_MEMBER_QUERY_INTERVAL;
				mymcp->timer.retry_left=LAST_MEMBER_QUERY_COUNT;
				
				//send Q(G)
				if( mymcp->igmp_ver==IGMP_VER_3 )
					igmpv3_query( mymcp, 0, NULL );
				else
					igmp_query(ALL_SYSTEMS, mymcp->grp_addr, LAST_MEMBER_QUERY_INTERVAL);

				//set the new state
				mymcp->filter_mode = MCAST_EXCLUDE;
				igmp_set_srcfilter( mymcp );
				
#ifdef KEEP_GROUP_MEMBER				
				if ( srcnum == 0 )
				{
					int count;
					count = del_user(mymcp, src);
					if (count == 0) {// no member, drop it!
						del_mr(mymcp->grp_addr);    			
						del_mcft(mymcp->grp_addr);
					}
				}
#endif
			}
			break;
		default:
			break;
		}
	}
}
Ejemplo n.º 5
0
void handle_igmpv3_isex( __u32 group, __u32 src, int srcnum, __u32 *grec_src )
{
	struct mcft_entry *mymcp;
	
	// Mason Yu Test
	//printf("handle_igmpv3_isex\n");
		
	if(!IN_MULTICAST(group))
		return;
	/* check if it's protocol reserved group */
	if((group&0xFFFFFF00)==0xE0000000){
		//printf("[%s]:It's protocol | reserved group!\n",__FUNCTION__);
		return;
	}
	
	if(!chk_mcft(group)) 
	{
		//return;
		mymcp = add_mcft(group, src);
		if(!mymcp) return;		
		mymcp->igmp_ver = IGMP_VER_3;
		igmp_add_group( group );
	}
		
	mymcp = get_mcft(group);
	if(mymcp)
	{
		switch( mymcp->filter_mode )
		{
		case MCAST_INCLUDE:
			{
				int i;
				struct src_entry *s, *old_set,*s_next;
				
				// Mason Yu Test
				//printf("handle_igmpv3_isex: MCAST_INCLUDE\n");
	
#ifdef KEEP_GROUP_MEMBER				
				add_user(mymcp, src);
#endif	

				//IN(A), IS_EX(B) => EX(A*B, B-A)
				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{	
					//(B-A)=0 
					if (check_src_set(grec_src[i],old_set)==0)
					{
						s = add_to_srclist( mymcp, grec_src[i] );
						if(s)
						{
							s->timer.lefttime = 0;
							s->timer.retry_left = 0;
							igmp_add_mr( mymcp->grp_addr, s->srcaddr, 0 );
						}
					}
				}
				
				s = old_set;
				while(s)
				{
					s_next=s->next;
					//Delete (A-B)
					if( check_src( s->srcaddr, grec_src, srcnum )==0 )
					{
						igmp_del_mr( mymcp->grp_addr, s->srcaddr );
						del_from_srclist( mymcp, s->srcaddr );
					}					
					s = s_next;
				}

				//Group Timer=GMI
				mymcp->timer.lefttime = MEMBER_QUERY_INTERVAL;
				mymcp->timer.retry_left = MEMBER_QUERY_COUNT;
				
				//set the new state
				mymcp->filter_mode = MCAST_EXCLUDE;
				igmp_set_srcfilter( mymcp );
			}
			break;
		case MCAST_EXCLUDE:
			{
				int i;
				struct src_entry *s, *old_set,*s_next;
				
				// Mason Yu Test
				//printf("handle_igmpv3_isex: MCAST_EXCLUDE\n");
#ifdef KEEP_GROUP_MEMBER
				add_user(mymcp, src);
#endif

				//EX(X,Y), IS_EX(A) => EX(A-Y, Y*A)
				old_set = mymcp->srclist;
				for(i=0;i<srcnum;i++)
				{
					// (A-X-Y)=GMI
					if( check_src_set( grec_src[i],old_set )==0 )
					{
						s=add_to_srclist( mymcp, grec_src[i] );
						if(s)
						{
							s->timer.lefttime = MEMBER_QUERY_INTERVAL;
							s->timer.retry_left = MEMBER_QUERY_COUNT;
							igmp_add_mr( mymcp->grp_addr, s->srcaddr, 1 );
						}
					}
				}
				
				s = old_set;
				while(s)
				{
					s_next =s->next;
					
					//Delete (X-A), Delete(Y-A)
					if( check_src( s->srcaddr, grec_src, srcnum )==0 )
					{
						igmp_del_mr( mymcp->grp_addr, s->srcaddr );
						del_from_srclist( mymcp, s->srcaddr );
					}
					s = s_next;
				}
								
				//Group Timer=GMI
				mymcp->timer.lefttime = MEMBER_QUERY_INTERVAL;
				mymcp->timer.retry_left = MEMBER_QUERY_COUNT;
				//printf("grp_addr:%s.mymcp->timer.lefttime=%d,mymcp->timer.retry_left=%d,[%s]:[%d].\n",inet_ntoa(group),mymcp->timer.lefttime,mymcp->timer.retry_left,__FUNCTION__,__LINE__);
				//set the new state
				mymcp->filter_mode = MCAST_EXCLUDE;
				igmp_set_srcfilter( mymcp );
			}
			break;
		default:
			break;
		}
	}
}