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

📄 stp_api.c

📁 stp代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************************
* Copyright (C) 2005,UNE Corporation.
* 
* File Name: stp_api.c
* File Mark: Multiple Spanning Tree (PVST) API functions
* Description:  
* Others: 
 * Note:
 *     1. Although the spanning tree software supports multiple
 *        spanning tree, on early StrataSwitch based systems
 *        (BCM5600, BCM5680) which do not have spanning tree group
 *        table, only one instance of STP can be ran.  Later
 *        generations of chip (Starta II, XGS) supports up to
 *        256 instances of spanning tree.
 *     2. Multiple instances of Spanning Tree all share one thread.
 *        which are started when the first instance of STP is started,
 *        and teared down when the last instance of STP exits.
 *     3. Only supports IEEE 802.1D spanning tree, doesn't support
 *        IBM or DEC spanning tree.
* Version: V1.0
* Author: 
* Date: 
* History 1:
*     Date: 
* 	  Version:
*     Author: 
*     Modification:  
* History 2: …
**********************************************************************/

#include <vxWorks.h>
#include <sysLib.h>
#include <stdio.h>
#include <stdLib.h>
#include <fioLib.h>

#include <sal/kern/libc.h>
#include <sal/user/sal.h>
#include <sal/user/io.h>

#include <sys/types.h>

#include <soc/mem.h>
#include <soc/drv.h>
#include <soc/types.h>
#include <soc/util.h>
#include <soc/debug.h>

#include <bcm/error.h>
#include <bcm/pmux.h>
#include <bcm/port.h>
#include <bcm/stg.h>
#include <bcm/packet.h>
#include <bcm/l2.h>
#include <bcm/mirror.h>
#include <bcm/stack.h>

#include <diag/system.h>

#include <stacking/trace.h>
#include <stacking/stk_transport.h>
#include <stacking/stk_platform.h>
#include <stacking/simplex.h>
#include <stacking/chassis.h>
#include <stacking/rdp.h>

#include <stp/stp.h>
#include <stp/stp_api.h>
#include <stp/stp_appl.h>
#include <stp/stp_trunk.h>

#include "txtdb/h/dbfileCnfg.h"

extern STATUS sysSwitchAddrGet(char macaddr[6]);
extern int trunk_number_get();
extern int bcm_port_link_status_get(int unit, bcm_port_t port, int *up);
extern int bcm_vlan_port_get(int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp);
extern int search_stg_through_vlan(bcm_vlan_t vid);
extern void decrease_stg_number(vlan_id_t vid);
extern int strcasecmp(const char* s1, const char* s2);
/*
 * BPDU packet destination address
 */
static
mac_addr_t stp_bridge_group_addr = {0x1, 0x80, 0xc2, 0x00, 0x00, 0x00};


edgeport_table_t edgeport_array[24] = 
{
{"edgevalue1"   , 0 },   
{"edgevalue2"   , 0 },
{"edgevalue3"   , 0 },
{"edgevalue4"   , 0 },
{"edgevalue5"   , 0 },
{"edgevalue6"   , 0 },
{"edgevalue7"   , 0 },
{"edgevalue8"   , 0 },
{"edgevalue9"   , 0 },
{"edgevalue10"  , 0 },
{"edgevalue11"  , 0 },
{"edgevalue12"  , 0 },
{"edgevalue13"  , 0 },
{"edgevalue14"  , 0 },
{"edgevalue15"  , 0 },
{"edgevalue16"  , 0 },
{"edgevalue17"  , 0 },
{"edgevalue18"  , 0 },
{"edgevalue19"  , 0 },
{"edgevalue20"  , 0 },
{"edgevalue21"  , 0 },
{"edgevalue22"  , 0 },
{"edgevalue23"  , 0 },
{"edgevalue24"  , 0 }
};


/*
 * find a spanning tree, given an external STP ID
 */
spantree_t *
stp_lookup_from_stp_id(stp_id_t stree_id)
{
    spantree_t *stp;

    FOR_ALL_STP(stp) {
        if (stp->external_id == stree_id) {
            return (stp);
        }
    }

    return (NULL);
    }

/*
 * Insert a spanning tree instance into the instance queue
 */
static void
stp_insert_instance(spantree_t *stp)
{
    stp->next = stp_instance_q;
    stp_instance_q = stp;
}

/*
 * Remove a spanning tree instance from the instance queue
 */
static void
stp_detach_instance(spantree_t *stp)
{
    spantree_t *entry;

    if (stp == stp_instance_q) {
        stp_instance_q = stp->next;
        return;
    }

    FOR_ALL_STP(entry) {
        if (entry->next == stp) {
            break;
        }
    }

    entry->next = stp->next;
}

/*
 * create a spanning tree instance
 */
int
stp_create_instance(spantree_t **stp_out, stp_id_t tree_id, uint8 *namestring)
{
    spantree_t *stp;

    /* make sure STP ID does not exist yet */
    if ((stp = stp_lookup_from_stp_id(tree_id)) != NULL ) {
        printk("stp_create_instance: tree_id exists\n");
        *stp_out = stp;
        return (-1);
    }

    /* Allocate spanning tree data structure */
    stp = (spantree_t *)sal_alloc(sizeof(spantree_t), "stp");
    if (stp == NULL) {
        return (-1);
    }

    /* Allocate buffer for transfering BPDU messages */
    stp->bpdu_send_buff = sal_dma_alloc(ENET_MAX_SIZE, "stp");
    if (stp->bpdu_send_buff == NULL) {
        sal_free(stp);
        *stp_out = NULL;
        return (-1);
    }

    *stp_out = stp;

    stp->external_id = tree_id;
    stp->running     = FALSE;
    stp->namestring  = namestring;
    sal_memcpy(stp->bpdu_mac, stp_bridge_group_addr, 6);

    /* empty port list */
    stp->port_list.next = &stp->port_list;
    stp->port_list.prev = &stp->port_list;
    stp->port_count = 0;

    /* Bridge ID */
    sal_memset(stp->bridge_id, 0, ID_BYTES);
    /* added by zhouguis 2005-11-29  */
    stp_set_mac_address(stp);
    /* Set span tree parameters to default value */
    stp_config_params_set(stp, NULL);

    /* Start stp thread if not already started */
    if (start_stp_process() < 0) {
        sal_free(stp);
        return (-1);
    }
    

    /* now we have a valid STP instance, insert into STP list */
    stp_insert_instance(stp);

    return (0);
}

/*
 * delete a spanning tree instance
 */
int
stp_delete_instance(spantree_t *stp)
{
    /*
     * if the stp is currently active, suspend it first
     */
    if (stp_is_running(stp)) {
        stp_deactivate_spantree(stp);
    }

    /* STP is stopped, free up all the port structures */
    /* added by zgs 只有是缺省STP条件或者停止所有生成树的条件下才删除。*/
    if((stp->external_id == 1) ||(stp_get_stop_method())) 
    	{
    while (stp->port_list.next != &stp->port_list) {
        stp_delete_stp_port(stp->port_list.next);
    }
      }
    else   /* 否则把端口添加到缺省STP中去。*/
    	{
          while (stp->port_list.next != &stp->port_list) {
              stp_moveporto_defaultstp(stp->port_list.next);
          }    		
    	}
    /* remove from STP instances list */
    stp_detach_instance(stp);

    /* free the packet buffer */
    if (stp->bpdu_send_buff) {
        sal_dma_free(stp->bpdu_send_buff);
    }

    sal_free(stp);

    /* kill the thread if there is no STP instances */
    if (stp_instance_q == NULL) {
        stp_process_teardown();
    }
    
      /*zhouguis moved this to no stp command*/
    return 0;
}

/*
 * Set the MAC address for a spanning tree when creating
 * a new STP instance structure.
 * Note: Use set_bridge_id_api() to set bridge ID after STP is running.
 */
int
stp_set_spantree_mac_address(spantree_t *stp, uint8 *bridge_mac)
{
   

    uint16 temp_vid; 
    soc_htons_store(stp->bridge_id, STP_DEF_BRIDGE_PRIORITY);

    /* zgs added vlan id to bridge priority 2005-11-29 */
    temp_vid = stp->external_id;
    
    stp->bridge_id[1] = temp_vid & 0x00ff;
    stp->bridge_id[0] = (stp->bridge_id[0] |((temp_vid >> 8) & 0x000f) );
    
    sal_memcpy((stp->bridge_id + 2), bridge_mac, 6);

    return (0);
}

/*
 * return the MAC address of a spanning tree
 */
int
stp_get_spantree_mac_address(spantree_t *stp, uint8 *mac_address)
{
    if (mac_address == NULL) {
        return (-1);
    } else {
        sal_memcpy(mac_address, (stp->bridge_id + 2), 6);
    }

    return (0);
}

/*
 * return a boolean indication as to whether a spanning tree is running
 */
int
stp_is_running(spantree_t *stp)
{
    return (stp->running);
}

/*
function name:stp_get_count
function description:get number of stp
input:none
output:count---number of stp
return:
      number of stp
*/


int 
stp_get_count(int *count)
{
    spantree_t *stp;
    *count=0;	
    FOR_ALL_STP(stp) {
  	(*count)++;
    }

    return *count;
}

/*
function name:stp_get_stp_id_by_number
function description:get external stp id through internal id
input:counte----stp internal id
output:none
return:
      stp external id 
*/
uint32   
stp_get_stp_id_by_number(int count)
{
    spantree_t *stp;
    int internal_count=0;
    FOR_ALL_STP(stp) {
        if (internal_count==(count)) {
            return (stp->external_id);
        }
	else
       {
		internal_count++;
     	}
    }

    return 0;
}


/*
 * given an external ID(a.k.a logical port number), find a spanning tree port
 */
stp_port_t *
stp_port_lookup_from_id(spantree_t *stp, int lport)
{
    stp_port_t *port;

    FOR_ALL_PORTS_IN_STP(stp, port) {
        if (port->lport == lport) {
            return (port);
        }
    }

    /* not found */
    return ((stp_port_t *)NULL);
}

/*
 * dll_insert - insert new "entry" into a doubly-linked list after "pred".
 * Note: an empty list is formed by having the initial element
 * have both the next and prev point to itself. Think of this
 * as a circular list rather than a simple double-linked list where
 * the terminal elements point to NULL.
 */
STATIC void
dll_insert(stp_port_t *entry, stp_port_t *pred)
{
    pred->next->prev = entry;
    entry->next = pred->next;
    entry->prev = pred;
    pred->next = entry;
}

/*
 * dll_remove - remove an "entry" from a doubly-linked list.
 * Note: the removed element has its next & prev set to point to itself.
 */
STATIC void
dll_remove(stp_port_t *entry)
{
    entry->prev->next = entry->next;
    entry->next->prev = entry->prev;
    entry->next = entry->prev = entry;
}

/*
 * Add port into spanning tree port list
 */
static void
stp_port_list_insert(spantree_t *stp, stp_port_t *port)
{
    stp_port_t *port_ndx;

    if (stp->port_list.next == &stp->port_list) {   /* list is empty */
        dll_insert(port, &stp->port_list);
    } else {
        /*
         * insert port in increasing port number, so we get nice view
         * from show command.  This is not required by STP protocol
         */
        FOR_ALL_PORTS_IN_STP(stp, port_ndx) {
            if (port_ndx->lport > port->lport) {
                break;
            }
        }

        /* link into the doubly-linked list */
        dll_insert(port, port_ndx->prev);
    }
}

/*
 * Create a spanning tree port data structure
 */
int
stp_create_stp_port(stp_port_t **stport_out, spantree_t *stp,
                    int lport, uint8 *namestring)
{
    stp_port_t *stport;
    char mac[6];


    /* make sure theres no collision on port id */
    if ((stport = stp_port_lookup_from_id(stp, lport)) != NULL) {
        printk("stp_create_stp_port: port exists\n");
        *stport_out = stport;
        return (-1);
    }

    /* create a spanning tree port data structure */
    stport = (stp_port_t *)sal_alloc(sizeof(*stport), "stp port");
    if (stport == NULL) {
        *stport_out = NULL;
        return (-1);
    }

    sal_memset(stport, 0, sizeof(stp_port_t));

⌨️ 快捷键说明

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