stp_process.c

来自「stp代码」· C语言 代码 · 共 1,383 行 · 第 1/3 页

C
1,383
字号

/*
 * Start Hello timer
 */
static void
start_hello_timer(spantree_t *stp)
{
    stp->hello_timer.value = 0;
    stp->hello_timer.active = True;
}

/*
 * Stop Hello timer
 */
static void
stop_hello_timer(spantree_t *stp)
{
    stp->hello_timer.active = False;
}

/*
 * Is Hello timer expired
 */
static Boolean
hello_timer_expired(spantree_t *stp)
{
    if (stp->hello_timer.active &&
        (++(stp->hello_timer.value) >= stp->hello_time)) {
        stp->hello_timer.active = False;
        return(True);
    }

    return(False);
}

/*
 * Start TCN timer
 */
static void
start_tcn_timer(spantree_t *stp)
{
    stp->tcn_timer.value = 0;
    stp->tcn_timer.active = True;
}

/*
 * Start TCN timer
 */
static void
stop_tcn_timer(spantree_t *stp)
{
    stp->tcn_timer.active = False;
}

/*
 * Is TCN timer expired
 */
static Boolean
tcn_timer_expired(spantree_t *stp)
{
    if (stp->tcn_timer.active &&
        (++(stp->tcn_timer.value) >= stp->bridge_hello_time)) {
        stp->tcn_timer.active = False;
        return(True);
    }

    return(False);
}

/*
 * Start topology change timer
 */
static void
start_tc_timer(spantree_t *stp)
{
    stp->tc_timer.value = 0;
    stp->tc_timer.active = True;
}

/*
 * Stop topology change timer
 */
static void
stop_tc_timer(spantree_t *stp)
{
    stp->tc_timer.active = False;
}

/*
 * Is topology change timer expired
 */
static Boolean
tc_timer_expired(spantree_t *stp)
{
    if (stp->tc_timer.active &&
        ((++(stp->tc_timer.value) >= stp->topology_change_time))) {
        stp->tc_timer.active = False;
        return(True);
    }

    return (False);
}

/*
 * Start message age timer
 */
static void
start_message_age_timer(spantree_t *stp, stp_port_t *port, uint16 message_age)
{
    port->message_age_timer.value = message_age;
    port->message_age_timer.active = True;
}

/*
 * Stop message age timer
 */
static void
stop_message_age_timer(spantree_t *stp, stp_port_t *port)
{
    port->message_age_timer.active = False;
}

/*
 * Is message age timer expired
 */
static Boolean
message_age_timer_expired(spantree_t *stp, stp_port_t *port)
{
    if (port->message_age_timer.active &&
        (++(port->message_age_timer.value) >= stp->max_age)) {
        port->message_age_timer.active = False;
        return(True);
    }

    return(False);
}

/*
 * Start forward delay timer
 */
static void
start_forward_delay_timer(spantree_t *stp, stp_port_t *port)
{
    port->forward_delay_timer.value = 0;
    port->forward_delay_timer.active = True;
}

/*
 * Stop forward delay timer
 */
static void
stop_forward_delay_timer(spantree_t *stp, stp_port_t *port)
{
    port->forward_delay_timer.active = False;
}

/*
 * Is forward delay timer expired
 */
static Boolean
forward_delay_timer_expired(spantree_t *stp, stp_port_t *port)
{
    if (port->forward_delay_timer.active &&
        (++port->forward_delay_timer.value >= stp->forward_delay)) {
        port->forward_delay_timer.active = False;
        return(True);
    }

    return(False);
}

/*
 * Start HOLD timer
 */
static void
start_hold_timer(spantree_t *stp, stp_port_t *port)
{
    port->hold_timer.value = 0;
    port->hold_timer.active = True;
}

/*
 * Stop HOLD timer
 */
static void
stop_hold_timer(spantree_t *stp, stp_port_t *port)
{
    port->hold_timer.active = False;
}

/*
 * Is HOLD timer expired
 */
static Boolean
hold_timer_expired(spantree_t *stp, stp_port_t *port)
{
    if (port->hold_timer.active &&
        ((++(port->hold_timer.value) >= stp->hold_time))) {
        port->hold_timer.active = False;
        return(True);
    }

    return(False);
}



/*
 * A single thread to handle multiple spanning tree algorithm
 */
static void
stp_main_process(void *arg)
{
    spantree_t *stp;
    int i;
    /* Run forever */
    while (!stp_exit) {
        i = 0;
        FOR_ALL_STP(stp) {
            sal_usleep(5000);
            if (stp->running) {
            	  stp_lock_link();
                stp_tick(stp);
                stp_unlock_link();
            }
            i++;
        }
        sal_usleep(1000000 - (5000 * i));
    }

    stp_thread_id = NULL;
    sal_thread_exit(0);
    
}

/*
 * Start up the STP process
 */
int
start_stp_process(void)
{
    stp_exit = 0;

    if (stp_thread_id == NULL) {
        stp_thread_id = sal_thread_create("spantree", SAL_THREAD_STKSZ*2, 50,
                                            stp_main_process, NULL);
        if (stp_thread_id == SAL_THREAD_ERROR) {
            stp_thread_id = NULL;
            printf("start stp process failure\n");
            return -1;
        }
        printf("Start stp sucess.\n");
    }

    return 0;
}

/*
 * Kill the STP process
 */
void
stp_process_teardown(void)
{
    if (stp_instance_q != NULL) {
        return;
    }
    debugk(DK_STP,"stp process exit.\n");
    stp_exit = 1;
 /*   while(stp_thread_id != NULL);*/
}

/*------------------------------------------------------------------------------
* FUNCTION:set_all_port_to_forward
* DESCRIPTION:设置交换机的所有活动端口的为转发状态。
* 
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
void set_all_port_to_forward(void)
{
	int unit,port,link=0,pport;
	for(unit =0;unit<soc_ndev_attached;unit++)
	{
		#if BOARD_TYPE==RHS8012GE_3T8F
		for(port = RHG_MIN_GEPORT+2;port <= RHG_MAX_GEPORT; port++)
		{       pport = port - 2;
            if (bcm_port_link_status_get(unit, pport, &link) < 0) {
                 printL("bcm_port_link_status_get error\n","");
                continue;
            }	
            if(link)
            {		
			           bcm_stg_stp_set(unit, 1, pport, STP_FORWARDING);
			      }
		}
		#else 
		for(port = RHG_MIN_GEPORT;port <= RHG_MAX_GEPORT; port ++)
		{
			      pport = port - 1;
            if (bcm_port_link_status_get(unit, pport, &link) < 0) {
                printL("bcm_port_link_status_get error\n","");
                continue;
            }	
            if(link)
            {	
			          bcm_stg_stp_set(unit, 1,pport, STP_FORWARDING);
			      }
		}		
		#endif
	}
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_thread_shutdown
* DESCRIPTION:关闭生成树功能。正常退出spantree进程和stp_pkt进程。
* 
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

void stp_thread_shutdown(void)
{

	 /* empty stp list; */
	 stp_exit_all = 1;
   stp_sys_cleanup();
	 debugk(DK_STP,"stp system clean up.\n");
	 stk_pakq_release();
   debugk(DK_STP,"stp packet precess exit.\n");	 
	 stp_shutdown(); 
   debugk(DK_STP,"stp spanning tree clean up.\n");    
   /* mstp globe flag */
   stp_close_mstp_flag_valued(); 

   stp_exit_all = 0;
   
}
/*------------------------------------------------------------------------------
* FUNCTION:stp_get_stop_method
* DESCRIPTION:通过全局变量判断是删除一棵生成树还是删除所有的生成树。
*             删除一棵生成树:把当前生成树活动端口移到缺省生成树,跟vlan匹配。
*             删除所有的生成树:删除所有的资源,退出生成树进程和收发包进程。
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

int stp_get_stop_method(void)
{
	return stp_exit_all;
}

/*------------------------------------------------------------------------------
* FUNCTION:edgeport_make_forwarding
* DESCRIPTION:如果是边缘端口,则直接置为转发状态。
*
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

static void
edgeport_make_forwarding(spantree_t *stp, stp_port_t *port)
{

    		set_port_state(stp, port, STP_FORWARDING);

}
/*------------------------------------------------------------------------------
* FUNCTION:check_config_port_to_forwarding
* DESCRIPTION:检查当前所设置的边缘端口是否为UP状态。如果UP则直接置为转发状态。
* 
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

void check_config_port_to_forwarding(int unit,int ingport,int lport)
{


    spantree_t *stp,*stptemp;
    stp_port_t *sport;
    
    int gport;
    
    FOR_ALL_STP(stp) 
    {
    	   if(stp == NULL)
    	 	 {
/*	  		  debugk(DK_STP,"Port is not up!\n");*/
    	 		return;
    	 	 }
    	 	 stptemp = stp;
    	   /*printL("PORT    STATE\n","");*/
    	   sport = stp->port_list.next ;
         while (sport != &stp->port_list) 
           {
           	   gport = get_global_port(sport->unit,sport->port);
           	   if(gport == ingport)
           	   	{
/*	  				 		debugk(DK_STP,"Found sport %d in stp %d\n",gport,stp->external_id);*/
	  				 		make_forwarding(stp, sport);
	  				 		return;
                }
               sport = sport->next;
           }    
         
    }
}

/*------------------------------------------------------------------------------
* FUNCTION:port_changed_cause_state_selection
* DESCRIPTION:端口状态改变要重新计算生成树。
* 
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/


void port_changed_cause_state_selection(spantree_t *stp)
{
	     port_state_selection(stp);
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_make_all_active_port_forwarding
* DESCRIPTION:等待系统所有的活动端口状态变迁完成。。
* 
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
void stp_make_all_active_port_forwarding(void)
{
	spantree_t *stp;
	stp_port_t *sport;
	int flag = 1;
	printL("Waiting state change: \n","");
	FOR_ALL_STP(stp)
	{
		     if(stp == NULL)
		     	{
	  				 		return;
}
		     	
		     	sport = stp->port_list.next;
         while (sport != &stp->port_list) 
           {
                    flag = 1;
                   while(flag)
                   {
                  	if((sport->state == STP_BLOCKING)||(sport->state == STP_FORWARDING))
                   		{
                   		    flag = 0;
                   	  }
                   	else
                   		{
                   			 printL(".","");
                         taskDelay(sysClkRateGet()*1);
                      }
                   	
                   }
                   sport = sport->next;
           }        	                   		
	}
	printL("Over.\n","");
}



⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?