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

📄 stp_trunk.c

📁 stp代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Parameters:
 *     tid - trunk group id
 *     pbmp - port bitmap(physical)
 * Returns:
 *    
 */
int
stp_trunk_port_remove(stp_id_t tree_id, bcm_trunk_t tid, pbmp_t pbmp)
{
    spantree_t *stp;
    soc_port_t port;
    int lport, r;

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

    if (!stp_trunk_initialized) {
        trace(TRACE_TRUNK, TR_ERROR, "Trunk not initialized!\n");
        return 1;
    }

    PBMP_ITER(pbmp, port) {
        lport = stp_port_p2l(stp_my_cpuid, DEF_UNIT, port);
        /*
         * Remove port from trunk in the local module
         */
        if ((r = stp_trunk_remove_one_port(stp, tid, lport)) < 0) {
            return (r);
        }

    }

    return (BCM_E_NONE);
}

/*
 * Function:
 *     stp_trunk_psc_set
 * Purpose:
 *     Set the RTAG for a trunk
 * Parameters:
 *     tid - trunk id
 *     rtag - the new rtag value
 * Returns:
 */
int
stp_trunk_psc_set(stp_id_t tree_id, bcm_trunk_t tid, int rtag)
{
    /* int p, linkup; */
    int unit;
    if (!stp_trunk_initialized) {
        trace(TRACE_TRUNK, TR_ERROR, "Trunk not initialized!\n");
        return 1;
    }

    trunk_table[tid].rtag = rtag;
    trace(TRACE_TRUNK, TR_VERBOSE,
          "Trunk: rtag changes to %d for trunk %d\n", rtag, tid); 
    unit  = get_gport_unit(tid);
    bcm_trunk_psc_set(unit, tid, rtag);

    return (0);
}

/*
 * Function:
 *     stp_rcv_trunk_info
 * Purpose:
 *     Handles trunk packets received from other modules of stack
 * Parameters:
 *     value - trunk port add/del info
 */
void
stp_rcv_trunk_info(uint32 clientid, void *data, int length, int s_cpu)
{
    spantree_t *stp;
    stp_rdp_trunk_t *tpi;
    stp_id_t tree_id;
    int tid, lport, link;

    tpi = (stp_rdp_trunk_t *)data;

    if (!stp_trunk_initialized) {
        trace(TRACE_TRUNK, TR_ERROR, "Trunk not initialized!\n");
        return;
    }

    tree_id = soc_ntohs(tpi->tree_id);
    tid     = soc_ntohs(tpi->tid);
    lport    = soc_ntohl(tpi->lport);
    link    = soc_ntohl(tpi->link_up);

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

    if (soc_ntohl(tpi->add) == TRUE) {
        /* Add port to trunk in the module */
        stp_trunk_add_one_port(stp, tid, lport, link);
        trace(TRACE_TRUNK, TR_VERBOSE,
           "rcv_trunk_pkts: add port %d tid %d\n", lport, tid);
    } else {
        /* Remove port from trunk in the module */
        stp_trunk_remove_one_port(stp, tid, lport);
        trace(TRACE_TRUNK, TR_VERBOSE,
           "rcv_trunk_pkts: remove port %d tid %d\n", lport, tid);
    }

    return;
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_link_up
* DESCRIPTION:当端口链路UP的时候,如果这个端口是聚合组的第一个UP成员,就被选为ROOT端口。
*             否则就是聚合组的普通成员(MEMBER)。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

int
stp_trunk_link_up(spantree_t *stp, int lport)
{
    stp_port_t *stport;

    int p, t;

    stport = stp_port_lookup_from_id(stp, lport);
    if (stport == NULL) {
        return -1;
    }
    if (!stp_trunk_is_trunk_port(lport)) {
        return -1;
    }    
    for (t = 0; t < BCM_TRUNK_GROUP_MAX; t++) {
        for (p = 0; p < BCM_TRUNK_MAX_PORTCNT; p++) {
            if (trunk_table[t].port[p].num == lport) {
                
                if (trunk_table[t].active_count) {
                    stp_trunk_member_add(stp, t, lport);
                    debugk(DK_STP,
                      "trunk_link_up: add %d to trunk %d\n",
                       lport, t);
                } else {
                    stp_trunk_root_add(stp, t, lport);
                    trunk_table[t].port[p].flag |= TRUNK_PORT_ROOT;
                    debugk(DK_STP,
                      "trunk_link_up: add %d to tid %d as root\n",
                       lport, t);
                }

                trunk_table[t].port[p].flag |= TRUNK_PORT_ACTIVE;
                return (0);
            }
        }
    }

    return (0);
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_link_down
* DESCRIPTION:当端口链路DOWN的时候,如果这个端口是聚合组的一个成员,就把她的状态转为非ACTIVE。
*             如果是ROOT端口,那么需要从其它的活动成员中选择一个作为ROOT端口。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

int
stp_trunk_link_down(spantree_t *stp, int lport)
{
    int t, p, i,find =0;

    
    if (!stp_trunk_is_trunk_port(lport)) {
        return (0);
    }

    for (t = 0; t < BCM_TRUNK_GROUP_MAX; t++) {
        for (p = 0; p < BCM_TRUNK_MAX_PORTCNT; p++) {
            if (trunk_table[t].port[p].num == lport) { /* find it */
            	  debugk(DK_STP,"find in trunk %d\n",t);
            	  find = 1;
                break;
            }
        }
        if(find){  break;}
    }
   if(find)
   {
    if (trunk_table[t].port[p].flag & TRUNK_PORT_ACTIVE) {
        trunk_table[t].port[p].flag &= ~TRUNK_PORT_ACTIVE;

        if (trunk_table[t].port[p].flag & TRUNK_PORT_ROOT) {
            for (i = 0; i < BCM_TRUNK_MAX_PORTCNT; i++) {
                if (trunk_table[t].port[i].flag & TRUNK_PORT_ACTIVE) {
                    stp_trunk_root_add(stp, t, trunk_table[t].port[i].num);
                    trunk_table[t].port[i].flag |= TRUNK_PORT_ROOT;
                    debugk(DK_STP,
                          "trunk_link_down: change %d as root for trunk %d\n",
                           trunk_table[t].port[i].num, t);
                    trunk_table[t].active_count--;
                    break;
                }
            }
        }
        trunk_table[t].port[p].flag &= ~TRUNK_PORT_ROOT;
    }
        trunk_table[t].active_count--;
  }
    return (0);
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_state_update
* DESCRIPTION:当聚合组根成员(ROOT)的状态改变的时候,它的成员(MEMBER)
*             的状态也要跟着改变,并且跟(ROOT)的状态一致。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

void
stp_trunk_state_update(spantree_t *stp, stp_port_t *stport, int state)
{
    stp_port_t *port;
    /* 如果ROOT端口的状态发生改变的时候,它的成员端口的状态也要发生改变:跟它一致 */
    if (stport->link_flags & STP_LF_TRUNKROOT) {
        FOR_ALL_PORTS_IN_STP(stp, port) {
            if (stport->lport != port->lport && port->tid == stport->tid &&
                port->link_flags & STP_LF_TRUNKMEMBER) {
                bcm_port_stp_set(port->unit, stp_port_l2p(port->lport), state);
            }
        }
    }
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_root_add
* DESCRIPTION:添加聚合组ROOT成员。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

int
stp_trunk_root_add(spantree_t *stp, int tid, int lport)
{
    stp_port_t *stport;
    stp_port_t *root_port;


    stp_port_bpdu_enable(stp, lport, TRUE);

    debugk(DK_STP,"Add root lport= %d\n",lport);
    root_port = stp_port_lookup_from_id(stp, lport);
    if (root_port == NULL) {
        return -1;
    }

    root_port->path_cost = STP_PATH_COST_AGGR;

    enable_port(stp, root_port);


    FOR_ALL_PORTS_IN_STP(stp, stport) {
        if (stport->lport != lport && stport->tid == tid &&
            stport->link_flags & STP_LF_TRUNKMEMBER) {
            stp_port_bpdu_enable(stp, stport->lport, 0);

            stport->link_flags &= ~STP_LF_TRUNKROOT;
            /*其它端口状态的选择应该根据新端口状态一致*/

            stp_port_state_set(stp, stport, root_port->state);
        }
    }

    root_port->link_flags |= STP_LF_TRUNKMEMBER | STP_LF_TRUNKROOT;
    root_port->tid = tid;
    trunk_table[tid].active_count++;
    return (0);
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_root_get
* DESCRIPTION:获取聚合组根端口。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

stp_port_t *
stp_trunk_root_get(spantree_t *stp, int tid)
{
    stp_port_t *stport;

    FOR_ALL_PORTS_IN_STP(stp, stport) {
        if (stport->link_flags & STP_LF_TRUNKROOT) {
            return (stport);
        }
    }

    return (0);
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_member_add
* DESCRIPTION:添加聚合组成员。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

int
stp_trunk_member_add(spantree_t *stp, int tid, int lport)
{
    stp_port_t *stport;
    stp_port_t *root_port;
    int state;

    stport = stp_port_lookup_from_id(stp, lport);
    if (stport == NULL) {
        return -1;
    }
    debugk(DK_STP,"Add member lport= %d\n",lport);
    stp_port_bpdu_enable(stp, lport, 0);

    stport->link_flags |= STP_LF_TRUNKMEMBER;
    stport->tid = tid;

    if ((root_port = stp_trunk_root_get(stp, tid))) {

        state = root_port->state;
    } else {
        state = STP_DISABLED;
    }

    stp_port_state_set(stp, stport, state);
    trunk_table[tid].active_count++;
    return (0);
}

/*
 * Function:
 *     stp_trunk_member_remove
 * Purpose:
 *     Remove this port from the trunk
 * Parameters:
 *     tid - trunk group id
 *     lport - logical port number
 * Returns:
 */
int
stp_trunk_member_remove(spantree_t *stp, int tid, int lport)
{
    stp_port_t *stport;
    stp_port_t *port;

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

    if (stport->link_flags & STP_LF_TRUNKROOT) {
        FOR_ALL_PORTS_IN_STP(stp, port) {
            if (lport != port->lport && port->tid == tid &&
                port->link_flags & STP_LF_TRUNKMEMBER) {
                if (port->state != STP_DISABLED) {
                    disable_port(stp, port);
                }
                stp_port_state_set(stp, port, STP_DISABLED);
            }
        }
    }

    stport->link_flags &= ~(STP_LF_TRUNKMEMBER | STP_LF_TRUNKROOT);
    stport->tid = 0;

    if (stport->state != STP_DISABLED) {
        disable_port(stp, stport);
    }
    /*
     * enable BPDUs from this port again
     */
    stp_port_bpdu_enable(stp, lport, 1);

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

    return (0);
}

/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_show
* DESCRIPTION:显示聚合组成员信息。
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

int
stp_trunk_show(void)
{
    int t, p;
    stp_print_trunk_table();
    if (!stp_trunk_initialized) {
        trace(TRACE_TRUNK, TR_ERROR, "Trunk not initialized!\n");
        return 1;
    }

    printk("\tR - Root, A - Active");
    for (t = 0; t < BCM_TRUNK_GROUP_MAX; t++) {
        if (trunk_table[t].port_count > 0) {
            printk("\n\nTrunk Group %d, psc %d, ports %d, active ports %d\n",
                    t, trunk_table[t].rtag, trunk_table[t].port_count,
                    trunk_table[t].active_count);
            printk("Ports : ");
        }
        for (p = 0; p < trunk_table[t].port_count; p++) {
            if (stp_stack_ready) {
                printk(" M%dP%d(", stp_port_l2cpu(trunk_table[t].port[p].num),
                        stp_port_l2p(trunk_table[t].port[p].num));
            } else {
                printk(" %d(", trunk_table[t].port[p].num);
            }
            if (trunk_table[t].port[p].flag & TRUNK_PORT_ROOT) {
                printk("R");
            }
            if (trunk_table[t].port[p].flag & TRUNK_PORT_ACTIVE) {
                printk("A");
            }
            printk(")");
        }
    }
    printk("\n");

    return (0);
}
/*------------------------------------------------------------------------------
* FUNCTION:stp_trunk_deal_with_port
* DESCRIPTION:当创建生成树的时候如果VLAN成员里面有聚合成员,
*             应该把加到聚合组中。       
* AUTHOR:ZHOUGUIS 2005-12-15
-------------------------------------------------------------------------------*/

void stp_trunk_deal_with_port(spantree_t *stp,int lport)
{
	 int trunk_id,link_up;
    stp_port_t *stport;
   /* 察看软件表的信息,判断这个端口是否为聚合组的一个成员 */
	  trunk_id = stp_trunk_get_trunk_id(lport);
	  if(trunk_id == -1){
         return;	 		
	  }

    if (!stp_trunk_initialized) {
        printL("Trunk not initialized!\n","");
        return;
    }	
    stport = stp_port_lookup_from_id(stp, lport);
    if (stport == NULL) {
        link_up = FALSE;
    }        
    else{
    	link_up = TRUE;
    }
    stp_trunk_add_one_port(stp, trunk_id, lport, link_up); 
    return;    
}

⌨️ 快捷键说明

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