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

📄 stp_api.c

📁 stp代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        (bpdu.max_age > STP_MAX_MAX_AGE)) {
        bpdu.max_age = STP_DEF_MAX_AGE;
    }

    if ((bpdu.hello_time < STP_MIN_HELLO_TIME) ||
        (bpdu.hello_time > STP_MAX_HELLO_TIME)) {
        bpdu.hello_time = STP_DEF_HELLO_TIME;
    }

    if ((bpdu.forward_delay < STP_MIN_FWD_DELAY) ||
        (bpdu.forward_delay > STP_MAX_FWD_DELAY)) {
        bpdu.forward_delay = STP_DEF_FWD_DELAY;
    }

    trace(TRACE_STP, TR_VERBOSE, "Config BPDU received on Port %d\n", stport->lport);
 
    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);

    stport->bpdu_in++;

    /*
     * now call config BPDU receive (stp.c)
     */
    received_config_bpdu(stp, stport, &bpdu);
}

/*
 * Function:
 *     stp_rcv_tcn
 * Purpose:
 *     Handles incoming TCN BPDU packets
 * Parameters:
 *     bpdu_msg - the TCN message received
 *     port - the port on which this is received
 * Returns:
 *     none
 */
void
stp_rcv_tcn(spantree_t *stp, bpdu_config_t *bpdu_msg, stp_port_t *stport)
{
    Tcn_bpdu stp_tcn_bpdu;

    stp_tcn_bpdu.type = bpdu_msg->msg_type;

    stport->bpdu_in++;

    /* now call topology change BPDU receive(from stp.c) */
    received_tcn_bpdu(stp, stport, &stp_tcn_bpdu);
}

/*
 * Function:
 *     stp_handle_bpdu_packet
 * Purpose:
 *     Handles STP BPDU packets
 * Parameters:
 *     bpdu_msg - BPDU
 *     port - port where packets comes in
 * Returns:
 *     none
 */
void
stp_handle_bpdu_packet(stp_id_t tree_id, uint8 *bpdu_buf, int lport)
{
    spantree_t *stp;
    stp_port_t *stport;
    bpdu_config_t *bpdu_msg;
    uint16 protocol_id;
    uint8 version;
    uint16 vlan_id;

/* zhouguis added this 2005-12-15 for trunk */
    bpdu_msg = (bpdu_config_t *)bpdu_buf;

    vlan_id = soc_ntohs_load((uint16 *)&bpdu_msg->bridge_id);
    vlan_id = vlan_id & 0x0fff;
    debugk(DK_STP,"packet send to vlan_id = %d\n",vlan_id);
    protocol_id = soc_ntohs_load(bpdu_msg->identifier);
    version = bpdu_msg->version;    
    if (version == 0) {
       stp = stp_lookup_from_stp_id(vlan_id);
    if (stp == NULL) {
        return;
    }

    stport = stp_port_lookup_from_id(stp, lport);
    if (stport == NULL) {
        return;
    }

    /* check protocol ID and version */
    protocol_id = soc_ntohs_load(bpdu_msg->identifier);
    version = bpdu_msg->version;

    if (protocol_id != 0) {
        trace(TRACE_STP, TR_ERROR,
              "invalid BPDU protocol id %d\n", protocol_id);
        return;
    }

    if (bpdu_msg->msg_type == BPDU_TYPE_CONFIG) {
        /* check flags */
        if ((bpdu_msg->flags & ~0x81) != 0) {
            trace(TRACE_STP, TR_ERROR, "Invalid flags 0x%x\n", bpdu_msg->flags);
            return;
        }
        stp_rcv_bpdu_config(stp, bpdu_msg, stport);
    } else if (bpdu_msg->msg_type == BPDU_TYPE_TCN) {
        stp_rcv_tcn(stp, bpdu_msg, stport);
    } else {
        trace(TRACE_STP, TR_ERROR,
             "invalid bpdu type %d\n", bpdu_msg->msg_type);
        return;
    }
}

  
    
}

/*
 * Function:
 *     stp_port_enable
 * Purpose:
 *     Enable port for example by CLI
 * Parameters:
 *     lport - identify the port to be disabled
 * Returns:
 *     none
 */
int
stp_port_enable(spantree_t *stp, int lport)
{
    stp_port_t *stport;

    if (!stp_is_running(stp)) {
        trace(TRACE_STP, TR_ERROR, "STP not enabled\n");
        return (-1);
    }

    stport = stp_port_lookup_from_id(stp, lport);
    if (stport == NULL) {
        return -1;
    }

    /* This is a hard enable */
    trace(TRACE_STP, TR_VERBOSE, "STP: Enabling port %d\n", lport);

    if (stport->link_flags & STP_LF_LINKDISABLED) {
        stport->link_flags &= ~STP_LF_LINKDISABLED;
        enable_port(stp, stport);
    }

    return (0);
}

/*
 * Function:
 *     stp_port_disable
 * Purpose:
 *     Disable port for example by CLI
 * Parameters:
 *     lport - identify the port to be disabled
 * Returns:
 *     none
 */
int
stp_port_disable(spantree_t *stp, int lport)
{
    stp_port_t *stport;

    if (!stp_is_running(stp)) {
        trace(TRACE_STP, TR_ERROR, "STP not enabled\n");
        return (-1);
    }

    stport = stp_port_lookup_from_id(stp, lport);
    if (stport == NULL) {
        return -1;
    }

    /* This is a hard disable */
    trace(TRACE_STP, TR_VERBOSE, "STP: Disabling port %d\n", lport);

    if (!(stport->link_flags & STP_LF_LINKDISABLED)) {
        stport->link_flags |= STP_LF_LINKDISABLED;

        if (stport->state != STP_DISABLED) {
            disable_port(stp, stport);
        }
    }

    return (0);
}

/*
 * Mark this port as stack link
 */
void
stp_mark_stack_port(spantree_t *stp, int lport)
{
    stp_port_t *stport;

    stp_create_stp_port(&stport, stp, lport, "stack port");

    /* stack ports does not participate in STP calculation */
    stport->link_flags |= STP_LF_STACK;
    stport->link_flags |= STP_LF_LINKDISABLED;
    stport->state = STP_DISABLED;
}

/*
 * Function:
 *     stp_link_up
 * Purpose:
 *     Called when port state changes to UP
 * Parameters:
 *     lport - identify the port(logical number)
 * Returns:
 *     none
 */
int
stp_link_up(spantree_t *stp, stp_port_t *stport, int speed)
{
	  /* 为了聚合端口添加 */
	  int lport;
	  
    if (speed == 1000) {
        stport->path_cost = STP_PATH_COST_1GB;
    } else if (speed == 100) {
        stport->path_cost = STP_PATH_COST_100MB;
    } else {
        stport->path_cost = STP_PATH_COST_10MB;
    }

    if (!(stport->link_flags & STP_LF_LINKDISABLED)) {
        enable_port(stp, stport);
    }
    /* 为了聚合端口添加 */

    lport = stp_port_p2l(stp_my_cpuid, stport->unit, stport->port);

    if (stp_trunk_running()) {
        stp_trunk_link_up(stp, lport);
    }

    return (0);
}

/*
 * Function:
 *     stp_link_down
 * Purpose:
 *     Called when port state changes to DOWN
 * Parameters:
 *     lport - identify the port(logical number)
 * Returns:
 *     none
 */
int
stp_link_down(spantree_t *stp, int lport)
{
    stp_port_t *stport;

    /* Trunk member going down */
    if (stp_trunk_running()) {
        stp_trunk_link_down(stp, lport);
    }


    stport = stp_port_lookup_from_id(stp, lport);
    if (stport != NULL) {
        stp_delete_stp_port(stport);
    }
    return (0);
}

/*
 * Function:
 *     stp_port_state_string
 * Purpose:
 *     Returns the port states string
 * Parameters:
 *     state - port state
 * Returns:
 *     none
 */
static char *
stp_port_state_string(int state)
{

    switch (state) {
      case STP_DISABLED:
        return ("Disabled");
      case STP_LISTENING:
        return ("Listening");
      case STP_LEARNING:
        return ("Learning");
      case STP_FORWARDING:
        return ("Forwarding");
      case STP_BLOCKING:
        return ("Blocking");
      default:
        return ("Unkown");
    }
}

/*
 * Function:
 *     stp_port_state_set
 * Purpose:
 *     Set the port state to chip
 * Parameters:
 *     lport - logical port number
 *     state - new state
 * Returns:
 *     none
 */
void
stp_port_state_set(spantree_t *stp, stp_port_t *stport, stp_portstate_t state)
{
    int clear_arl = 0;
    int stg;
    pbmp_t pbm;

/*    debugk(DK_STP, 
         "Tree %d, lport %d(%d %d %d) -> %s\n",
          stp->external_id, stport->lport,
          stp_port_l2cpu(stport->lport), stp_port_l2unit(stport->lport),
          stp_port_l2p(stport->lport), stp_port_state_string(state));
*/
    /* Only set hardware for local ports */
    if (!(stport->link_flags & STP_LF_LOCAL)) {
        return;
    }

    switch (state) {
      case STP_DISABLED:
        state = BCM_STG_STP_DISABLE;
        clear_arl = 1;
        break;
      case STP_LISTENING:
        state = BCM_STG_STP_LISTEN;
        break;
      case STP_LEARNING:
        state = BCM_STG_STP_LEARN;
        break;
      case STP_FORWARDING:
        state = BCM_STG_STP_FORWARD;
        clear_arl = 1;
        break;
      case STP_BLOCKING:
        state = BCM_STG_STP_BLOCK;
        clear_arl = 1;
        break;
      default:
        trace(TRACE_STP, TR_VERBOSE, "Bad STP port state %d\n", state);
    }

    /* bcm_port_stp_set(stport->unit, stport->port, state);*/
    /* zhouguis changed this 2005-12-15  */
    stg = search_stg_through_vlan(stp->external_id);
    bcm_stg_stp_set(stport->unit, stg, stport->port, state);
    #if 0
    bcm_stg_stp_set(stport->unit, stp->external_id, stport->port, state);
    #endif
    /*
     * What about all addresses on the port ?
     */
    if (clear_arl == 1) {
        SOC_PBMP_CLEAR(pbm);
        SOC_PBMP_PORT_ADD(pbm, stport->port);
        bcm_l2_addr_remove_by_port(stport->unit, pbm, 0);
    }
    /* 同步聚合端口ROOT和MEMBER之间的状态 zhouguis added 2005-12-14 */
    if (stp_trunk_running()) {
        stp_trunk_state_update(stp, stport, state);
    }

}

/*
 * Function:
 *     stp_port_bpdu_enable
 * Purpose:
 *     Enable/Disable BPDUs on the specified port
 * Parameters:
 *     lport - logical port number
 *     enable - True to enable, False to disable (reject bpdu).
 * Returns:
 *     none
 */
void
stp_port_bpdu_enable(spantree_t *stp, int lport, int enable)
{
    stp_port_t *stport;

    stport = stp_port_lookup_from_id(stp, lport);
    if (stport == NULL) {
        return;
    }

    if (!(stport->link_flags & STP_LF_LOCAL)) {
        return;
    }

    bcm_port_bpdu_enable_set(stport->unit, stport->port, enable);
}

/*
 * Function:
 *     stp_port_is_disabled
 * Purpose:
 *     return 1 if disabled 0 otherwise
 * Parameters:
 *     none
 * Returns:
 *     none
 */
int
stp_port_is_disabled(spantree_t *stp, stp_port_t *stport)
{
    return (stport->link_flags & STP_LF_LINKDISABLED);
}

/*
 * returns string for port type
 */
STATIC char *
stp_port_type_string(int type)
{
    switch (type) {
      case STP_PORT_TYPE_GE:
        return ("GigEthernet");
      case STP_PORT_TYPE_FE:
        return ("FastEthernet");
      default:
        return ("Ethernet");
    }
}

/*
 * Return speed for port
 */
STATIC char *
stp_port_speed_string(int cost)
{
    switch (cost) {
      case STP_PATH_COST_1GB:
        return ("1000 mbps");
      case STP_PATH_COST_100MB:
        return ("100 mbps");
      default:
        return ("10 mbps");
    }
}

⌨️ 快捷键说明

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