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

📄 stp_api.c

📁 stp代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    stport->next = stport;
    stport->prev = stport;
    stport->stp = stp;
    stport->lport = lport;
    stport->namestring = namestring;

    stport->state = STP_DISABLED;  /* Disable port until it is enabled */
/*    stport->port_id = (uint16)((STP_DEF_PORT_PRIORITY << 12) | lport);*/
    /* zhouguis changed this 2005-12-22 */
    stport->port_id = (uint16)(STP_DEF_PORT_PRIORITY << 8);
    stport->path_cost = STP_PATH_COST_100MB;  /* default */
    stport->port_type = STP_PORT_TYPE_FE;
    stport->link_flags = 0;
    stport->bpdu_out = 0;
    stport->bpdu_in = 0;

    /* default port mac address, use stp_set_stport_mac_address to change it */
    /*  changed by zhouguis 2005-11-25   */
    /*
    sal_memcpy(stport->mac_addr, (stp->bridge_id + 2), 6);
    stport->mac_addr[4] += lport / 256;
    stport->mac_addr[5] = lport % 256;
    */
    sysSwitchAddrGet(mac);
    sal_memcpy(stport->mac_addr, mac, 6);
    stport->mac_addr[4] += lport / 256;
    stport->mac_addr[5] = lport % 256;

    stp_port_list_insert(stp, stport);
    stp->port_count++;

    *stport_out = stport;

    return 0;
}

/*
 * Delete a spanning tree port data structure
 */
int
stp_delete_stp_port(stp_port_t *stport)
{
    spantree_t *stp;

    stp = stport->stp;

    /* tell stp to stop timers and etc */
    if (stport->state != STP_DISABLED) {
        disable_port(stp, stport);
        stp_port_state_set(stp, stport, STP_FORWARDING);
    }

    /* unlink the port from the STP port list */
    dll_remove(stport);
    stp->port_count--;

    sal_free(stport);

    return 0;
}

/*
 * Delete all ports from STP
 */
int
stp_delete_all_port(spantree_t *stp)
{
    stp_port_t *port;

    while (stp->port_list.next != &stp->port_list) {
        port = stp->port_list.next;
        dll_remove(port);
        sal_free(port);
    }

    stp->port_count = 0;

    return 0;
}

/*
 * Set the MAC address for a spanning tree port
 */
int
stp_set_stport_mac_address(stp_port_t *port, uint8 *port_mac)
{
    sal_memcpy(port->mac_addr, port_mac, 6);

    return (0);
}

/*
 * return the MAC address of a spanning tree port
 */
int
stp_get_stport_mac_address(stp_port_t *port, uint8 *port_mac)
{
    if (port_mac == NULL) {
        return (-1);
    } else {
        sal_memcpy(port_mac, port->mac_addr, 6);
    }

    return (0);
}

/*
 * Initialize bridge wide parameters to default values
 */
void
stp_config_params_set(spantree_t *stp, stp_params_t *in)
{
	 
    if (in == NULL) {
        stp->bridge_max_age = STP_DEF_MAX_AGE;
        stp->bridge_hello_time = STP_DEF_HELLO_TIME;
        stp->bridge_forward_delay = STP_DEF_FWD_DELAY;
        stp->hold_time = STP_HOLD_TIME;
           stp->saved_priority = STP_DEF_BRIDGE_PRIORITY;
    } else {
        stp->bridge_max_age = in->max_age_interval;
        stp->bridge_hello_time = in->hello_interval;
        stp->bridge_forward_delay = in->forward_delay;
        stp->hold_time = in->hold_time;
    }

    stp->topology_change_time = stp->bridge_max_age + stp->bridge_forward_delay;
}

/*
 * return the configuration parameters of a spanning tree
 */
int
stp_get_spanning_tree_parms(spantree_t *stp, stp_params_t *out)
{
    out->max_age_interval = stp->bridge_max_age;
    out->hello_interval = stp->bridge_hello_time;
    out->forward_delay = stp->bridge_forward_delay;
    out->hold_time = stp->hold_time;

    return (0);
}

/*
 * Set forward delay time value
 */
void
set_forward_delay_api(spantree_t *stp, uint16 t)
{
    if (t < STP_MIN_FWD_DELAY || t > STP_MAX_FWD_DELAY) {
        return;
    }

    stp->bridge_forward_delay = t;
    stp->topology_change_time = stp->bridge_max_age + stp->bridge_forward_delay;
}

/*
 * Set max age timer value
 */
void
set_max_age_api(spantree_t *stp, uint16 t)
{
    if (t < STP_MIN_MAX_AGE || t > STP_MAX_MAX_AGE) {
        return;
    }

    stp->bridge_max_age = t;
    stp->topology_change_time =
        stp->bridge_max_age + stp->bridge_forward_delay;
}

/*
 * Set STP HELLO interval
 */
void
set_hello_interval_api(spantree_t *stp, uint16 t)
{
    if (t < STP_MIN_HELLO_TIME || t > STP_MAX_HELLO_TIME) {
        return;
    }

    stp->bridge_hello_time = t;
}

/*
 * Function:
 *     stp_send_config_bpdu
 * Purpose:
 *     Send config BPDU packet out on lport(called from stp.c)
 * Parameters:
 *     lport - logical port
 *     bpdu - BPDU message
 * Returns:
 *     none
 */
void
stp_send_config_bpdu(spantree_t *stp, stp_port_t *stport, Config_bpdu *bpdu)
{
    tag_bpdu_packet_t *enet_hdr;
    bpdu_config_t *bpdu_msg;
    int enet_hdr_len, plen;
    int flag;
    pbmp_t pbm, upbm;


    if (!stp_is_running(stp)) {
        return;
    }

    /* Only send BPDU for local ports in stacking mode */
    if (!(stport->link_flags & STP_LF_LOCAL)) {
        return;
    }

    /*
     * BPDU ethernet header
     */
    sal_memset(stp->bpdu_send_buff, 0, sizeof(stp->bpdu_send_buff));
    enet_hdr = (tag_bpdu_packet_t *)stp->bpdu_send_buff;
    enet_hdr_len = STP_BPDU_TAG_802_LEN; /* STP_BPDU_802_LEN */
    bpdu_msg = (bpdu_config_t *)((uint8*)stp->bpdu_send_buff + enet_hdr_len);

    /* 802.3 destination MAC address */
    sal_memcpy(enet_hdr->da, stp->bpdu_mac, 6);

    /* 802.3 source MAC address */
    sal_memcpy(enet_hdr->sa, stport->mac_addr, 6);

    /* tagged 802 packet */
    enet_hdr->type = soc_htons(0x8100);
    enet_hdr->vtag = soc_htons(stp->external_id);
    /*enet_hdr->vtag = soc_htons(0x0002);*/
    /* 802 tagged length */ 
    enet_hdr->tlen = soc_htons(STP_CONFIG_BPDU_LENGTH + 3);

    /* LSAP for BPDU is 0x42(0100 0010), 802.3 CTL is 0x03 */
    enet_hdr->dsap = BPDU_SAP;
    enet_hdr->ssap = BPDU_SAP;
    enet_hdr->ctrl = 0x03;

    /*
     * BPDU data
     */

    /* Protocol identifier (Always 0) */
    bpdu_msg->identifier[0] = 0;
    bpdu_msg->identifier[1] = 0;

    /* Protocol Version (Always 0) */
    bpdu_msg->version = 0;

    /* message type */
    bpdu_msg->msg_type = bpdu->type;

    /* TCA, TC flags */
    bpdu_msg->flags = (bpdu->tc_acknowledgment ? 0x80 : 0x00);
    if (bpdu->topology_change) {
        bpdu_msg->flags |= 0x01;
    	}
	
    /* root ID */
    sal_memcpy(bpdu_msg->root_id, bpdu->root_id, ID_BYTES);

    /* root path cost */
    soc_htonl_store(bpdu_msg->root_path_cost, bpdu->root_path_cost);

    /* bridge ID */
    sal_memcpy(bpdu_msg->bridge_id, bpdu->bridge_id, ID_BYTES);

    /* port ID */
    soc_htons_store(bpdu_msg->port_id, bpdu->port_id);

    /* Message age */
    soc_htons_store(bpdu_msg->message_age, (bpdu->message_age << 8)); 

    /* max age */
    soc_htons_store(bpdu_msg->max_age, (bpdu->max_age << 8)); 

    /* hello time */
    soc_htons_store(bpdu_msg->hello_time, (bpdu->hello_time << 8)); 

    /* forward delay */
    soc_htons_store(bpdu_msg->forward_delay, (bpdu->forward_delay << 8)); 

    trace(TRACE_STP, TR_VERBOSE, "Send config BPDU on port: %d\n", get_global_port(stport->unit,stport->port));
    trace(TRACE_STP, TR_VERBOSE, 
          "Type %x RootId:%08x%08x PathCost:%d BridgeId:%08x%08x\n", 
           bpdu->type, soc_ntohl_load(bpdu->root_id),
           soc_ntohl_load(bpdu->root_id + 4),
           bpdu->root_path_cost, soc_ntohl_load(bpdu->bridge_id), 
           soc_ntohl_load(bpdu->bridge_id + 4));

    trace(TRACE_STP, TR_VERBOSE, 
          "PortId %04x MsgAge %d MaxAge %d HelloTime %d, FwdDelay %d", 
           bpdu->port_id, bpdu->message_age, bpdu->max_age,
           bpdu->hello_time, bpdu->forward_delay);
    trace(TRACE_STP, TR_VERBOSE, " ACK %d top %d\n", 
            bpdu->tc_acknowledgment, bpdu->topology_change);

 	{ /*对于非TRUNK口 我们应该只对这个端口发送 2005-12-09*/
    /* Must send 802.1Q tagged packet, otherwise the VLAN ID will be lost */
    SOC_PBMP_CLEAR(pbm);
    SOC_PBMP_CLEAR(upbm);
    SOC_PBMP_PORT_ADD(upbm, stport->port);  
    SOC_PBMP_PORT_ADD(pbm, stport->port);
    
    plen = (STP_CONFIG_BPDU_LENGTH + enet_hdr_len + 3)&~0x3; /* round to x*4 bytes */
    flag = BCM_PACKET_CRC_APPEND | BCM_PACKET_COS(1);
    bcm_packet_send_pbmp(stport->unit, pbm, upbm,
                         stp->bpdu_send_buff, plen, flag);

  }
  stport->bpdu_out++;
#ifdef STP_DEBUG
    stk_pak_dump(stp->bpdu_send_buff, plen);
#endif

    return;
}

/*
 * Function:
 *     stp_send_tcn_bpdu
 * Purpose:
 *     send TCN BPDU out the designated port
 * Parameters:
 *     lport - port
 *     bpdu - TCN BPDU message
 * Returns:
 *     none
 */
void
stp_send_tcn_bpdu(spantree_t *stp, stp_port_t *stport, Tcn_bpdu * bpdu)
{
    tag_bpdu_packet_t *enet_hdr;
    bpdu_config_t *tcn_msg;
    int enet_hdr_len, plen;
    int flag;
    pbmp_t pbm, upbm;

    if (!stp_is_running(stp)) {
        return;
    }

    /* Only send TCN BPDU on local ports(for stacking mode) */
    if (!(stport->link_flags & STP_LF_LOCAL)) {
        return;
    }

    /*
     * BPDU ethernet header
     */
    sal_memset(stp->bpdu_send_buff, 0, sizeof(stp->bpdu_send_buff));
    enet_hdr = (tag_bpdu_packet_t *)stp->bpdu_send_buff;
    enet_hdr_len = STP_BPDU_TAG_802_LEN; /* STP_BPDU_802_LEN */
    tcn_msg = (bpdu_config_t *)((uint8*)stp->bpdu_send_buff + enet_hdr_len);

    /* 802.3 destination MAC address */
    sal_memcpy(enet_hdr->da, stp->bpdu_mac, 6);

    /* 802.3 source MAC address */
    sal_memcpy(enet_hdr->sa, stport->mac_addr, 6);

    /* tagged 802 packet */
    enet_hdr->type = soc_htons(0x8100);
    enet_hdr->vtag = soc_htons(stp->external_id);
/*    debugk(DK_STP,"stp packets vlan tag = %d\n", enet_hdr->vtag);*/
    /* 802 tagged length */
    enet_hdr->tlen = soc_htons(STP_TCN_BPDU_LENGTH + 3);

    /* LSAP for BPDU is 0x42(0100 0010), 802.3 CTL is 0x03 */
    enet_hdr->dsap = BPDU_SAP;
    enet_hdr->ssap = BPDU_SAP;
    enet_hdr->ctrl = 0x03;

    /*
     * TCN BPDU data
     */

    /* Protocol identifier (Always 0) */
    tcn_msg->identifier[0] = 0;
    tcn_msg->identifier[1] = 0;

    /* Protocol Version (Always 0) */
    tcn_msg->version = 0;

    /* message type */
    tcn_msg->msg_type = bpdu->type;


 	{ /*对于非TRUNK口 我们应该只对这个端口发送 zhouguis 2005-12-09*/
    /* Must send 802.1Q tagged packet, otherwise the VLAN ID will be lost */
    plen = (STP_TCN_BPDU_LENGTH + enet_hdr_len + 3) & ~0x3; /* round to x*4 bytes */
    flag = BCM_PACKET_CRC_APPEND | BCM_PACKET_COS(1);
    SOC_PBMP_CLEAR(pbm);
    SOC_PBMP_CLEAR(upbm);
    SOC_PBMP_PORT_ADD(pbm, stport->port);
    
     /*    debugk(DK_STP,"send packets to port %d\n",stport->port);*/
    
    bcm_packet_send_pbmp(stport->unit, pbm, upbm, stp->bpdu_send_buff, plen, flag);
  }

   stport->bpdu_out++;
#ifdef STP_DEBUG
    trace(TRACE_STP, TR_LOGIT, "Send TCN BPDU on port: %d\n", stport->lport);
    stk_pak_dump(stp->bpdu_send_buff, plen);
#endif

    return;
}

/*
 * Function:
 *     stp_rcv_bpdu_config
 * Purpose:
 *     handles incoming BPDU packets
 * Parameters:
 *     bpdu - the received BPDU message
 *     port - the port on which this is received
 * Returns:
 *     none
 */
void
stp_rcv_bpdu_config(spantree_t *stp, bpdu_config_t *bpdu_msg, stp_port_t *stport)
{
    Config_bpdu bpdu;
    uint16 message_age, max_age, hello_time, forward_delay;
    uint8 flags;

    /* flag */
    flags = bpdu_msg->flags;
    bpdu.tc_acknowledgment = (flags >> 7) & 0x01; 
    bpdu.topology_change = flags & 0x01;

    /* message type */
    bpdu.type = bpdu_msg->msg_type;

    /* root ID */
    sal_memcpy(bpdu.root_id, bpdu_msg->root_id, ID_BYTES);

    /* root path cost */
    bpdu.root_path_cost = soc_ntohl_load(bpdu_msg->root_path_cost);

    /* bridge ID */
    sal_memcpy(bpdu.bridge_id, bpdu_msg->bridge_id, ID_BYTES);

    /* port ID */
    bpdu.port_id = soc_ntohs_load(bpdu_msg->port_id);

    /* message age */
    message_age = soc_ntohs_load(bpdu_msg->message_age);
    bpdu.message_age = message_age >> 8; 

    /* max age */
    max_age = soc_ntohs_load(bpdu_msg->max_age);
    bpdu.max_age = max_age >> 8; 

    /* hello time */
    hello_time = soc_ntohs_load(bpdu_msg->hello_time);
    bpdu.hello_time = hello_time >> 8; 

    /* forward delay */
    forward_delay = soc_ntohs_load(bpdu_msg->forward_delay);
    bpdu.forward_delay = forward_delay >> 8; 

    if ((bpdu.max_age < STP_MIN_MAX_AGE) ||

⌨️ 快捷键说明

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