Exemplo n.º 1
0
/**fm10000InformRedirectCPUPortLinkChange
 * \ingroup intStacking
 *
 * \desc            Inform a link change for a port. This will update
 *                  the port mask appropriately for the CPU port
 *                  when the traffic is redirected over a LAG.
 *
 * \param[in]       sw is the switch number to operate on.
 *
 * \param[in]       port is the logical port.
 *
 * \param[in]       linkStatus is the link status of the port.
 *
 * \return          FM_OK if successful.
 *
 *****************************************************************************/
fm_status fm10000InformRedirectCPUPortLinkChange(fm_int            sw,
                                                 fm_int            port,
                                                 fm_portLinkStatus linkStatus)
{
    fm_status  err;
    fm_switch *switchPtr;
    fm_int     members[FM_MAX_NUM_LAG_MEMBERS];
    fm_int     numMembers;
    fm_int     cnt;

    FM_NOT_USED(linkStatus);

    FM_LOG_ENTRY(FM_LOG_CAT_STACKING, "sw=%d port=%d\n", sw, port);

    switchPtr = GET_SWITCH_PTR(sw);

    if (switchPtr->cpuPort == 0)
    {
        /* real CPU port is always up, no need to do anything */
        FM_LOG_EXIT(FM_LOG_CAT_STACKING, FM_OK);
    }

    err = fmGetLAGCardinalPortList(sw,
                                   switchPtr->cpuPort,
                                   &numMembers,
                                   members,
                                   FM_MAX_NUM_LAG_MEMBERS);
    FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_STACKING, err);

    for (cnt = 0 ; cnt < numMembers ; cnt++)
    {
        if (members[cnt] == port)
        {
            /* Link change for a member, update */
            err = fm10000RedirectCpuTrafficToPort(sw, -1);
            break;
        }
    }

    FM_LOG_EXIT(FM_LOG_CAT_STACKING, err);

}   /* end fm10000InformRedirectCPUPortLinkChange */
Exemplo n.º 2
0
/** MapLagPortToMemberPort
 * \ingroup intSwitch
 *
 * \desc            Maps a LAG logical port to one of its member ports.
 *
 * \param[in]       sw is the switch to operate on.
 *
 * \param[in]       port is the LAG logical port number.
 *
 * \param[out]      logPort points to the location to receive the logical
 *                  port number.
 *
 * \return          FM_OK if successful.
 * \return          FM_ERR_INVALID_PORT if the port number is invalid.
 * \return          FM_ERR_NO_PORTS_IN_LAG if port refers to an empty LAG.
 *
 *****************************************************************************/
static fm_status MapLagPortToMemberPort(fm_int  sw,
                                        fm_int  port,
                                        fm_int *logPort)
{
    fm_int      portList[FM_MAX_NUM_LAG_MEMBERS];
    fm_port *   portPtr;
    fm_lag *    lagPtr;
    fm_int      numPorts;
    fm_status   err;

    portPtr = GET_PORT_PTR(sw, port);
    if (portPtr == NULL)
    {
        return FM_ERR_INVALID_PORT;
    }

    lagPtr = GET_LAG_PTR(sw, portPtr->lagIndex);

    if(lagPtr == NULL)
    {
        return FM_ERR_INVALID_PORT;
    }

    /* Get a list of active member ports. */
    err = fmGetLAGCardinalPortList(sw,
                                   lagPtr->logicalPort,
                                   &numPorts,
                                   portList,
                                   FM_MAX_NUM_LAG_MEMBERS);

    if (err != FM_OK)
    {
        return err;
    }

    if (numPorts == 0)
    {
        /* Return the first port even if the link is currently down.
         * This should ensure that a SWAG or Stacked Configuration
         * works properly at init time. */
        err = fmGetLAGMemberPorts(sw,
                                  portPtr->lagIndex,
                                  &numPorts,
                                  portList,
                                  FM_MAX_NUM_LAG_MEMBERS,
                                  FALSE);
        if (err != FM_OK)
        {
            return err;
        }
        else if (numPorts == 0)
        {
            return FM_ERR_NO_PORTS_IN_LAG;
        }
    }

    /*
     * Select one of the LAG ports using pseudo-random selection.
     *
     * Why are we doing "pseudo-random" selection? Why not (for
     * example) return the logical port that corresponds to the canonical
     * logical port?
     */
    *logPort = portList[port % numPorts];

    return FM_OK;

}   /* end MapLagPortToMemberPort */