⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stp_api.c

📁 stp代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Function:
 *     stp_show
 * Purpose:
 *     Show STP parameters and states
 * Parameters:
 *     none
 * Returns:
 *     none
 */
void
stp_show(stp_id_t tree_id, int detail)
{
    spantree_t *stp;
    stp_port_t *stport;
    char t[6];
    uint16 priority, designated_port,temp_bridge_id,vlan_id;

    stp = stp_lookup_from_stp_id(tree_id);
    if (stp == NULL) {
        return;
    }

    if (!stp_is_running(stp)) {
        trace(TRACE_STP, TR_ERROR, "STP %d not running\n", tree_id);
        return;
    }

    printk("This Bridge is executing IEEE compatible Spanning Tree Protocol\n\n");
    printk("STP instance ID %d\n", tree_id);

    temp_bridge_id = soc_ntohs_load(stp->bridge_id);
    priority = (temp_bridge_id & 0xf000)>>12 ;
    vlan_id = temp_bridge_id & 0x0fff;
    
    sal_memcpy(t, (stp->bridge_id + 2), 6);
    printk("Root bridge priority - %d.%d\n", priority,vlan_id);
    printk("Bridge ID - %X:%X:%X:%X:%X:%X\n", t[0], t[1], t[2], t[3], t[4], t[5]);

    if (stp->root_path_cost != 0) {
        sal_memcpy(t, (stp->designated_root + 2), 6);
        printk("Root Bridge - %X:%X:%X:%X:%X:%X\n",
                t[0], t[1], t[2], t[3], t[4], t[5]);
        printk("Root Port - %d\n", get_global_port(stp->root_port->unit,stp->root_port->port));
    } else {
        printk("\nRoot Bridge - self\n");
    }

    printk("HelloInterval = %d, MaxTime = %d, ForwardDelay = %d\n",
            stp->bridge_hello_time, stp->bridge_max_age, 
            stp->bridge_forward_delay);
    printk("TopologyChangeTime = %d, HoldTime = %d\n\n", 
            stp->topology_change_time, stp->hold_time);
    
    printk("Bridge filter aging time is %d.\n\n", stp->l2_age);

    if (stp->topology_change) {
        printk("Topology change flag set, ");
    } else {
        printk("Topology change flag not set, ");
    }

    if (stp->topology_change_detected) {
        printk("Topology change detected flag set\n\n");
    } else {
        printk("Topology change detected flag not set\n\n");
    }

    if (!detail) {
        return;
    }

    FOR_ALL_PORTS_IN_STP(stp, stport) {
        if (stport->state != STP_DISABLED) {
            printk("Port %d (%s, operating speed = %s) is %s\n", get_global_port(stport->unit,stport->port),
                    stp_port_type_string(stport->port_type),
                    stp_port_speed_string(stport->path_cost),
                    stp_port_state_string(stport->state));
            priority = stport->port_id >> 12;
            printk("   Port path cost %d, Port priority %d\n",
                    stport->path_cost, priority);

            temp_bridge_id = soc_ntohs_load(stport->designated_root);
            priority = (temp_bridge_id & 0xf000)>>12 ;
            vlan_id = temp_bridge_id & 0x0fff;            
            sal_memcpy(t, (stport->designated_root + 2), 6);
            printk("   Designated root has priority %d.%d, ", priority,vlan_id);
            printk("address %X:%X:%X:%X:%X:%X\n",
                    t[0], t[1], t[2], t[3], t[4], t[5]);

            temp_bridge_id = soc_ntohs_load(stport->designated_bridge);
            priority = (temp_bridge_id & 0xf000)>>12 ;            
            vlan_id = temp_bridge_id & 0x0fff;                    
            sal_memcpy(t, (stport->designated_bridge + 2), 6);
            printk("   Designated bridge has priority %d.%d, ", priority,vlan_id);
            printk("address %X:%X:%X:%X:%X:%X\n",
                    t[0], t[1], t[2], t[3], t[4], t[5]);

            designated_port = stport->designated_port & 0x00ff;
            designated_port = get_global_port(designated_port&0x20,designated_port&0x1f);
            printk("   Designated port is %d, path cost %d\n",
                    designated_port, stport->designated_cost); 

            printk("   BPDU send count = %d,  BPDU receive count = %d\n",
                    stport->bpdu_out, stport->bpdu_in);
            printk("\n");
        } else {
            if (stport->link_flags & STP_LF_TRUNKMEMBER) {
                printk("Port %d is trunk port\n\n", stport->lport);
            } else if (stport->link_flags & STP_LF_STACK) {
                printk("Port %d is stack port\n\n", stport->lport);
            }
        }
   }
}




/* zgs added this for port remove from vlan  begin */

/*------------------------------------------------------------------------------
* FUNCTION:stp_sdd_new_stp_port
* DESCRIPTION:当把一个端口从一个VLAN中移到另外一个VLAN的时候。
*             则需要把从原来的STP移到新STP中。
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
    	                   		
int
stp_sdd_new_stp_port(spantree_t *stp, stp_port_t *stport)
    	                    	{
    stport->next = stport;
    stport->prev = stport;
    stport->stp = stp;
    stport->state = STP_DISABLED;  /* Disable port until it is enabled */
    /* 统一由链路UP的时候决定 */
/*    stport->path_cost = STP_PATH_COST_1GB; */ /* default */
/*    stport->port_type = STP_PORT_TYPE_GE;  */
    stport->link_flags = 0;
    stport->bpdu_out = 0;
    stport->bpdu_in = 0;
    	                    		
    stp_port_list_insert(stp, stport);
    stp->port_count++;
         									       		 
    stport->link_flags |= STP_LF_LOCAL;     
     
    if(!(stport->link_flags & STP_LF_LINKDISABLED))
    	{
        enable_port(stp, stport);                     
    }        	                    		
                                      
    return 0;
}                

      
/*------------------------------------------------------------------------------
* FUNCTION:stp_removed_port_todefault_stp
* DESCRIPTION:当从VLAN中删除一个端口的时候,如果VLAN有STP,这个端口是活动端口,
*             则把它添加到缺省STP中。
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

void stp_removed_port_todefault_stp(int lport,vlan_id_t	vid,int unit,vlan_id_t	def_vid)
                       	{
      spantree_t *defstp,*curstp;
      stp_port_t *sport = (stp_port_t *)NULL;
      int find_flag=0;      
      /*找到生成树中的STP,并且删除连接*/
      curstp=stp_lookup_from_stp_id(vid);
      if(curstp == NULL){
      	   return;
            }      		
      FOR_ALL_PORTS_IN_STP(curstp, sport) {
        if ((sport->port == lport)&&(sport->unit == unit)) {
          disable_port(curstp, sport);
          dll_remove(sport);
          curstp->port_count--;        	
        	find_flag = 1;
          break;
      	}	       
      	}	       
    if(find_flag){
      defstp=stp_lookup_from_stp_id(def_vid);  
      if(defstp == NULL){
      	   return;
    }  
      stp_sdd_new_stp_port(defstp, sport);
    }
      return;
}


/*------------------------------------------------------------------------------
* FUNCTION:stp_delete_ifvlan_has_stp
* DESCRIPTION:当删除一个VLAN的时候,如果VLAN有STP,则停止它的STP.
*             
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

void stp_delete_ifvlan_has_stp(vlan_id_t vid)
{
	spantree_t *stp;

      /* 检查VLAN的生成树是否存在 */
      stp=stp_lookup_from_stp_id(vid);
      if(stp == NULL){
                    return;
    }
                      
      stp_delete_section(vid);                    
      stp_lock_link();                  
      stp_stop(vid);
      stp_unlock_link();
      decrease_stg_number(vid); 
  		return;
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_check_stpofthe_vlanexist
* DESCRIPTION:检查一个VLAN是否拥有STP.
* RETURN:
*      -1 :STP使能并且VLAN的STP已经存在;
*      -2 :STP使能并且VLAN的STP不存在;
*       0 :STP没有使能;           
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

int stp_check_stpofthe_vlanexist(vlan_id_t vid)
{
	       spantree_t *stp;
	  if(stp_instance_q != NULL){
          stp=stp_lookup_from_stp_id(vid);
          if(stp == NULL){
              return -2;	           /*stp enable&& vlan's stp not exist*/
         }
          else{
          	   return -1;  /* stp enable&& vlan's stp exist */
          }
         }
    return 0;     
}

/*------------------------------------------------------------------------------
* FUNCTION:vlan_ifhastp_addporto_stp
* DESCRIPTION:当添加一个端口到VLAN的时候,检查STP是否使能;
*             如果使能,这个端口又不处于DISABLE状态,那就
*             把这个端口从以前的STP中移到VLAN所在的STP中。
* RETURN:
         NONE
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/

void vlan_ifhastp_addporto_stp(int unit,int lport,vlan_id_t vid,vlan_id_t def_vid)
{
   spantree_t *defstp,*curstp;
   stp_port_t *sport = (stp_port_t *)NULL;
   int lcport;

   lcport = stp_port_p2l(stp_my_cpuid, unit, lport);
   /*找到生成树中的STP,并且删除连接*/
   FOR_ALL_STP(curstp)
      {
        sport = stp_port_lookup_from_id(curstp, lcport);
        if (sport == NULL) {
           continue;
        }
        disable_port(curstp, sport);
        dll_remove(sport);
        curstp->port_count--;
        break;
    }
   /*如果找到端口,就把它添加到生成树中去*/
   if(sport != NULL)
            	{
   	    defstp=stp_lookup_from_stp_id(vid);
   	    if(defstp == NULL){
   	    	return;
   	    }
   	    stp_sdd_new_stp_port(defstp, sport);
   	}
    return;
            		
}

/* FUNCTION:    stp_check_relation_for_trunk
 * DESCRIPTION: 当创建TRUNK的时候,需要把TRUNK生成树中的信息删除。
 * AUTHOR/DATE: zhouguis 2005-12-9
 */

void stp_check_relation_for_trunk(int gport)
{
     spantree_t *curstp;
     stp_port_t *sport = (stp_port_t *)NULL;
	   int unit,lport,lcport,link;
	   unit  = get_gport_unit(gport);
     lport = gport_to_lport(gport); 
     lcport = stp_port_p2l(stp_my_cpuid, unit, lport);
     /*如果链路状态为DOWN,则返回*/
     if (bcm_port_link_status_get(unit, lport, &link) < 0) {
/*         debugk(DK_STP,"bcm_port_link_status_get error\n");*/
                                   return;
    	                       	}
     if(link){
       FOR_ALL_STP(curstp){
       	    if(curstp == NULL) return;
            sport = stp_port_lookup_from_id(curstp, lcport);
            if (sport == NULL) {
               continue;
            }
            disable_port(curstp, sport);
            dll_remove(sport);
            curstp->port_count--;
            sal_free(sport);
            break;
            }
        }        	                    		
}                
/* FUNCTION:    stp_add_active_port_to_itstp
 * DESCRIPTION: 当把TRUNK作为VLAN的时候服务的时候,需要把TRUNK口添加到VLAN的生成树中去。
 * AUTHOR/DATE: zhouguis 2005-12-9
 */

void stp_add_active_port_to_itstp(int gport,vlan_id_t vid)
{
	   spantree_t *curstp;
     stp_port_t *sport = (stp_port_t *)NULL;
	   int unit,lport,lcport,link,speed;	   
	   unit  = get_gport_unit(gport);
     lport = gport_to_lport(gport); 
	   /*如果链路状态为UP,否则等到UP的时候再添加*/
     if (bcm_port_link_status_get(unit, lport, &link) < 0) {
/*         debugk(DK_STP,"bcm_port_link_status_get error\n");*/
         return;
                       }
	   if(link){	   
	        /*如果生成树已经启动*/
	        curstp = stp_lookup_from_stp_id(vid);
          if(curstp == NULL){
          	  return;
          }
          lcport = stp_port_p2l(stp_my_cpuid, unit, lport);
          sport = stp_port_lookup_from_id(curstp, lcport);  
          /*如果TRUNK口还没有在生成树中就创建一个端口,并把它添加到生成树中*/
          if (sport == NULL) {
                       
               if (bcm_port_speed_get(unit, lport, &speed) < 0) {
                   /*trace(TRACE_STP, TR_ERROR, */
                    debugk(DK_STP,"bcm_port_speed_get error\n");
                   speed = 100;
               }
               if (stp_create_stp_port(&sport, curstp, lcport, "stp port") < 0) {
                   return;
               }
               sport->cpu = stp_my_cpuid;
               sport->unit = unit;
               sport->port = lport;
               sport->port_type = stp_get_porttype(unit, lport);
               sport->link_flags = 0 ;
               sport->link_flags |= STP_LF_LOCAL;
               /* for port id = pri + port id zhouguis adde 2005-12-22*/
               sport->port_id |= gport;                     
               stp_link_up(curstp, sport, speed);
               }
      }
}
      
/* FUNCTION:    stp_deltrunk_inmoved_vlantree
 * DESCRIPTION: 当TRUNK不为VLAN服务的时候,需要把TRUNK口从相应的生成树中删除。
 * AUTHOR/DATE: zhouguis 2005-12-9
 */
void stp_deltrunk_inmoved_vlantree(int gport,vlan_id_t vid)
                       	{
	   spantree_t *curstp;
     stp_port_t *sport = (stp_port_t *)NULL;
	   int unit,lport,lcport,link;	   
	   unit  = get_gport_unit(gport);
     lport = gport_to_lport(gport); 
     /* 如果链路为DOWN,则在link_down事件处理中删除 */
     if (bcm_port_link_status_get(unit, lport, &link) < 0) {
/*         debugk(DK_STP,"bcm_port_link_status_get error\n");*/
         return;
                        }
	   if(link){
	   	  FOR_ALL_STP(curstp){
	        if(curstp == NULL){
          	  continue;
                    }
          lcport = stp_port_p2l(stp_my_cpuid, unit, lport);
          sport = stp_port_lookup_from_id(curstp, lcport);  
          /*如果TRUNK口已经在生成树中就删除*/
          if (sport != NULL){
               disable_port(curstp, sport);
               dll_remove(sport);
               curstp->port_count--;
               sal_free(sport);          	
            }      		
      	}	       
	 	}
	   return;     	   
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_moveporto_defaultstp
* DESCRIPTION:如果使活动端口,就把它添加到缺省的STP中去。
*             否则删除这个端口。
* RETURN:
         NONE
* AUTHOR:ZHOUGUIS
-------------------------------------------------------------------------------*/
void stp_moveporto_defaultstp(stp_port_t *stport)
{
    spantree_t *stp,*curstp;
    stp = stport->stp;
    /* 检查端口状态 */
    	      disable_port(stp, stport);
            dll_remove(stport);
            stp->port_count--;
            curstp = stp_lookup_from_stp_id(1);
            if(curstp == NULL){
          	     return;
            }      		
            stp_sdd_new_stp_port(curstp, stport); 
            return;
}

/****************************************************************************
* FUNCTION NAME:port_is_edgeport
* DESCRIPTION:返回端口的属性信息。
* AUTHOR/DATE: ZHOUGUIS
****************************************************************************/
int port_is_edgeport(int gport)
	    {
	    if(check_gport_valid(gport)) {	    	   
	    			return edgeport_array[gport-1].port_state;
	    }
	    else{    		 
	    		 return 0;
	    	}
}



/****************************************************************************
* FUNCTION NAME:stp_set_edgeport
* DESCRIPTION:设置边缘端口。
* AUTHOR/DATE: ZHOUGUIS
****************************************************************************/
void stp_set_edgeport(int gport)
{
	int unit,lport;
	   if(check_gport_valid(gport)&&(!edgeport_array[gport-1].port_state))
	   	{
	   		edgeport_array[gport-1].port_state = 1;
	   	
	      unit = get_gport_unit(gport);
	      lport = gport_to_lport(gport);  
	      
	      check_config_port_to_forwarding(unit,gport,lport);
	   
	   }
	   else
	   	{
	   		printL("Port has been setted to edge port state!\n","");
	   	}
}

/****************************************************************************

⌨️ 快捷键说明

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